desktop-team-doc 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +89 -0
- package/content/docs/README.md +227 -0
- package/content/docs/index.md +352 -0
- package/content/docs/instructions/coding-conventions/.clang-format +65 -0
- package/content/docs/instructions/coding-conventions/cpp.md +132 -0
- package/content/docs/instructions/coding-conventions/frontend.md +612 -0
- package/content/docs/instructions/coding-conventions/team-wide.md +176 -0
- package/content/docs/instructions/workflows/assets/jira-1.png +0 -0
- package/content/docs/instructions/workflows/assets/jira-comment.png +0 -0
- package/content/docs/instructions/workflows/assets/jira-release-note.png +0 -0
- package/content/docs/instructions/workflows/assets/jira-tag.png +0 -0
- package/content/docs/instructions/workflows/code-review.md +451 -0
- package/content/docs/instructions/workflows/git-branch-convention.md +246 -0
- package/content/docs/instructions/workflows/git-commit.md +95 -0
- package/content/docs/instructions/workflows/jira-process.md +173 -0
- package/content/docs/instructions/workflows/jira-ticket-guide.md +105 -0
- package/content/docs/instructions/workflows/pull-request-generation.md +319 -0
- package/content/docs/instructions/workflows/scrum-process.md +104 -0
- package/content/docs/instructions/workflows/survey-project-setup.md +76 -0
- package/content/docs/knowledge/architecture/README.md +11 -0
- package/content/docs/knowledge/architecture/audio-plugin-architecture.md +213 -0
- package/content/docs/knowledge/architecture/cross-platform-design.md +176 -0
- package/content/docs/knowledge/architecture/frontend-native-bridge.md +193 -0
- package/content/docs/knowledge/architecture/native-command.md +189 -0
- package/content/docs/knowledge/architecture/state-management-architecture.md +105 -0
- package/content/docs/knowledge/component-library/ControlComponent/README.md +281 -0
- package/content/docs/knowledge/component-library/ControlComponent/accessibility/accessibility-implementation.md +503 -0
- package/content/docs/knowledge/component-library/ControlComponent/common-mechanisms.md +278 -0
- package/content/docs/knowledge/component-library/ControlComponent/core/error-handling.md +451 -0
- package/content/docs/knowledge/component-library/ControlComponent/core/native-interface.md +515 -0
- package/content/docs/knowledge/component-library/ControlComponent/core/state-management.md +509 -0
- package/content/docs/knowledge/component-library/ControlComponent/creating-new-controls.md +654 -0
- package/content/docs/knowledge/component-library/ControlComponent/design/api-design-reference.md +1142 -0
- package/content/docs/knowledge/component-library/ControlComponent/design/design-principles.md +336 -0
- package/content/docs/knowledge/component-library/ControlComponent/design/styling-architecture.md +595 -0
- package/content/docs/knowledge/component-library/ControlComponent/design/visual-feedback.md +456 -0
- package/content/docs/knowledge/component-library/ControlComponent/development-environment.md +213 -0
- package/content/docs/knowledge/component-library/ControlComponent/interaction/gesture-algorithms.md +705 -0
- package/content/docs/knowledge/component-library/ControlComponent/interaction/touch-support.md +525 -0
- package/content/docs/knowledge/component-library/ControlComponent/interaction/value-processing-patterns.md +801 -0
- package/content/docs/knowledge/component-library/ControlComponent/interaction/velocity-damping-systems.md +741 -0
- package/content/docs/knowledge/component-library/ControlComponent/knob/architecture.md +490 -0
- package/content/docs/knowledge/component-library/ControlComponent/knob/how-to-use.md +304 -0
- package/content/docs/knowledge/component-library/ControlComponent/knob/index.md +105 -0
- package/content/docs/knowledge/component-library/ControlComponent/optimization/performance-benchmarks.md +535 -0
- package/content/docs/knowledge/component-library/ControlComponent/optimization/performance-optimization.md +1092 -0
- package/content/docs/knowledge/component-library/ControlComponent/quick-start.md +345 -0
- package/content/docs/knowledge/component-library/ControlComponent/slider/architecture.md +444 -0
- package/content/docs/knowledge/component-library/ControlComponent/slider/how-to-use.md +470 -0
- package/content/docs/knowledge/component-library/ControlComponent/slider/index.md +107 -0
- package/content/docs/knowledge/component-library/ControlComponent/testing-guide.md +950 -0
- package/content/docs/knowledge/component-library/ControlComponent/troubleshooting.md +657 -0
- package/content/docs/knowledge/component-library/frontend-develop/LICENSE.txt +176 -0
- package/content/docs/knowledge/component-library/frontend-develop/SKILL.md +124 -0
- package/content/docs/knowledge/component-library/frontend-develop/references/code-organization.md +620 -0
- package/content/docs/knowledge/component-library/frontend-develop/references/coding-standards.md +275 -0
- package/content/docs/knowledge/component-library/frontend-develop/references/component-reusability.md +559 -0
- package/content/docs/knowledge/component-library/frontend-develop/references/examples.md +554 -0
- package/content/docs/knowledge/component-library/frontend-develop/references/layout-separation.md +638 -0
- package/content/docs/knowledge/component-library/frontend-develop/references/performance-optimization.md +678 -0
- package/content/docs/knowledge/component-library/frontend-develop/references/state-management.md +331 -0
- package/content/docs/knowledge/component-library/frontend-develop/references/styling-guidelines.md +349 -0
- package/content/docs/knowledge/component-library/frontend-develop/references/type-safety.md +493 -0
- package/content/docs/knowledge/development/assets/cyberduck-aws-credentials.png +0 -0
- package/content/docs/knowledge/development/assets/postman-environment-setup.png +0 -0
- package/content/docs/knowledge/development/aws-storage.md +95 -0
- package/content/docs/knowledge/development/crm-system.md +22 -0
- package/content/docs/knowledge/development/glossary.md +246 -0
- package/content/docs/knowledge/development/pg-api-guide.md +71 -0
- package/content/docs/knowledge/development/staging-license-management.md +44 -0
- package/content/docs/knowledge/development/tech-stack.md +240 -0
- package/content/docs/knowledge/domain/popup-system.md +106 -0
- package/content/docs/knowledge/domain/sigpath.md +264 -0
- package/content/docs/knowledge/environment-setup/aax-signing-update.md +149 -0
- package/content/docs/knowledge/environment-setup/assets/aax-1.png +0 -0
- package/content/docs/knowledge/environment-setup/assets/aax-2.png +0 -0
- package/content/docs/knowledge/environment-setup/assets/aax-3.png +0 -0
- package/content/docs/knowledge/environment-setup/assets/aax-4.png +0 -0
- package/content/docs/knowledge/environment-setup/assets/aax-5.png +0 -0
- package/content/docs/knowledge/environment-setup/assets/aax-6.png +0 -0
- package/content/docs/knowledge/environment-setup/assets/aax-7.png +0 -0
- package/content/docs/knowledge/environment-setup/assets/buildmachine-1.png +0 -0
- package/content/docs/knowledge/environment-setup/assets/buildmachine-10.png +0 -0
- package/content/docs/knowledge/environment-setup/assets/buildmachine-11.png +0 -0
- package/content/docs/knowledge/environment-setup/assets/buildmachine-12.png +0 -0
- package/content/docs/knowledge/environment-setup/assets/buildmachine-13.png +0 -0
- package/content/docs/knowledge/environment-setup/assets/buildmachine-14.png +0 -0
- package/content/docs/knowledge/environment-setup/assets/buildmachine-2.png +0 -0
- package/content/docs/knowledge/environment-setup/assets/buildmachine-3.png +0 -0
- package/content/docs/knowledge/environment-setup/assets/buildmachine-4.png +0 -0
- package/content/docs/knowledge/environment-setup/assets/buildmachine-5.png +0 -0
- package/content/docs/knowledge/environment-setup/assets/buildmachine-6.png +0 -0
- package/content/docs/knowledge/environment-setup/assets/buildmachine-7.png +0 -0
- package/content/docs/knowledge/environment-setup/assets/buildmachine-8.png +0 -0
- package/content/docs/knowledge/environment-setup/assets/buildmachine-9.png +0 -0
- package/content/docs/knowledge/environment-setup/build-machine-setup.md +224 -0
- package/content/docs/knowledge/environment-setup/build-machine-troubleshooting.md +193 -0
- package/content/docs/knowledge/implementation-guides/adding-amp.md +190 -0
- package/content/docs/knowledge/implementation-guides/adding-fx.md +111 -0
- package/content/docs/knowledge/implementation-guides/cab-integration.md +194 -0
- package/content/docs/knowledge/implementation-guides/custom-pedal-integration.md +309 -0
- package/content/docs/knowledge/projects/BIAS_ONE_GUI/README.md +17 -0
- package/content/manifest.json +122 -0
- package/content/rules/cpp.mdc +135 -0
- package/content/rules/frontend.mdc +615 -0
- package/content/rules/index.mdc +256 -0
- package/content/rules/knowledge.mdc +46 -0
- package/content/rules/team-wide.mdc +179 -0
- package/content/rules/workflows.mdc +43 -0
- package/content/tools/agents/context-compressor.md +357 -0
- package/content/tools/agents/context-writer.md +328 -0
- package/content/tools/agents/release-notes-generator.md +389 -0
- package/content/tools/agents/srs-writer-agent.md +63 -0
- package/content/tools/mcp/README.md +25 -0
- package/content/tools/mcp/mcp-desktop-team.example.json +13 -0
- package/content/tools/skills/frontend-develop/LICENSE.txt +176 -0
- package/content/tools/skills/frontend-develop/SKILL.md +124 -0
- package/content/tools/skills/frontend-develop/references/code-organization.md +620 -0
- package/content/tools/skills/frontend-develop/references/coding-standards.md +275 -0
- package/content/tools/skills/frontend-develop/references/component-reusability.md +559 -0
- package/content/tools/skills/frontend-develop/references/examples.md +554 -0
- package/content/tools/skills/frontend-develop/references/layout-separation.md +638 -0
- package/content/tools/skills/frontend-develop/references/performance-optimization.md +678 -0
- package/content/tools/skills/frontend-develop/references/state-management.md +331 -0
- package/content/tools/skills/frontend-develop/references/styling-guidelines.md +349 -0
- package/content/tools/skills/frontend-develop/references/type-safety.md +493 -0
- package/content/tools/slash-commands/commit.md +17 -0
- package/content/tools/slash-commands/context-compress.md +149 -0
- package/content/tools/slash-commands/context-write.md +92 -0
- package/content/tools/slash-commands/jira.md +12 -0
- package/content/tools/slash-commands/pr-gen.md +12 -0
- package/content/tools/slash-commands/pr-review.md +12 -0
- package/dist/commands/detect.d.ts +1 -0
- package/dist/commands/detect.js +33 -0
- package/dist/commands/install.d.ts +1 -0
- package/dist/commands/install.js +100 -0
- package/dist/commands/uninstall.d.ts +1 -0
- package/dist/commands/uninstall.js +132 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +53 -0
- package/dist/lib/detect-env.d.ts +3 -0
- package/dist/lib/detect-env.js +52 -0
- package/dist/lib/prompt-env.d.ts +3 -0
- package/dist/lib/prompt-env.js +16 -0
- package/dist/lib/resolve-doc-repo.d.ts +14 -0
- package/dist/lib/resolve-doc-repo.js +61 -0
- package/dist/lib/symlink.d.ts +7 -0
- package/dist/lib/symlink.js +60 -0
- package/dist/lib/sync-from-manifest.d.ts +8 -0
- package/dist/lib/sync-from-manifest.js +64 -0
- package/package.json +46 -0
|
@@ -0,0 +1,493 @@
|
|
|
1
|
+
# Type Safety Guidelines
|
|
2
|
+
|
|
3
|
+
This document provides comprehensive guidelines for type safety in TypeScript/React projects, including enum standards, extensibility patterns, and generics usage.
|
|
4
|
+
|
|
5
|
+
## Core Principles
|
|
6
|
+
|
|
7
|
+
### Avoid `any` Type
|
|
8
|
+
|
|
9
|
+
**Rule**: Never use `any` unless absolutely necessary. Use specific types or `unknown` when the type is truly unknown.
|
|
10
|
+
|
|
11
|
+
**Bad**:
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
function processData(data: any): any {
|
|
15
|
+
return data.value;
|
|
16
|
+
}
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
**Good**:
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
interface DataWithValue {
|
|
23
|
+
value: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function processData(data: DataWithValue): string {
|
|
27
|
+
return data.value;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// When type is truly unknown
|
|
31
|
+
function processUnknown(data: unknown): string {
|
|
32
|
+
if (typeof data === 'object' && data !== null && 'value' in data) {
|
|
33
|
+
return String((data as { value: unknown }).value);
|
|
34
|
+
}
|
|
35
|
+
throw new Error('Invalid data');
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Strict Type Checking
|
|
40
|
+
|
|
41
|
+
Always enable strict mode in TypeScript configuration:
|
|
42
|
+
|
|
43
|
+
- `noImplicitAny: true`
|
|
44
|
+
- `strictNullChecks: true`
|
|
45
|
+
- `strictFunctionTypes: true`
|
|
46
|
+
|
|
47
|
+
## Enum Standards
|
|
48
|
+
|
|
49
|
+
### Enum Naming Convention
|
|
50
|
+
|
|
51
|
+
**Rule**: Use `PascalCase` for enum names, `camelCase` for enum values.
|
|
52
|
+
|
|
53
|
+
**Example**:
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
enum LicenseType {
|
|
57
|
+
trial = 'trial',
|
|
58
|
+
standard = 'standard',
|
|
59
|
+
professional = 'professional',
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
enum MenuType {
|
|
63
|
+
amp = 'amp',
|
|
64
|
+
cab = 'cab',
|
|
65
|
+
fx = 'fx',
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Enum Best Practices
|
|
70
|
+
|
|
71
|
+
1. **Use String Enums for Extensibility**: String enums are more maintainable and allow for easier serialization.
|
|
72
|
+
|
|
73
|
+
**Good**:
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
enum SortOrder {
|
|
77
|
+
ascend = 'ascend',
|
|
78
|
+
descend = 'descend',
|
|
79
|
+
none = null,
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
2. **Export Enums**: Make enums available for reuse across modules.
|
|
84
|
+
|
|
85
|
+
```typescript
|
|
86
|
+
export enum Status {
|
|
87
|
+
idle = 'idle',
|
|
88
|
+
loading = 'loading',
|
|
89
|
+
success = 'success',
|
|
90
|
+
error = 'error',
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
3. **Use Const Assertions for Read-only Arrays**: When creating arrays of enum-like values, use `as const`.
|
|
95
|
+
|
|
96
|
+
```typescript
|
|
97
|
+
export const MIDI_TYPE_OPTIONS = [
|
|
98
|
+
{ name: 'Power', value: 'toggle' },
|
|
99
|
+
{ name: 'Parameter', value: 'parameter' },
|
|
100
|
+
] as const;
|
|
101
|
+
|
|
102
|
+
export type MidiType = (typeof MIDI_TYPE_OPTIONS)[number]['value'];
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Enum Extensibility Patterns
|
|
106
|
+
|
|
107
|
+
When designing enums that may need to be extended:
|
|
108
|
+
|
|
109
|
+
**Pattern 1: Union Types for Extensibility**
|
|
110
|
+
|
|
111
|
+
```typescript
|
|
112
|
+
type BaseStatus = 'idle' | 'loading' | 'success' | 'error';
|
|
113
|
+
|
|
114
|
+
// Can be extended in other modules
|
|
115
|
+
type ExtendedStatus = BaseStatus | 'pending' | 'cancelled';
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
**Pattern 2: Const Objects with Type Inference**
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
const Status = {
|
|
122
|
+
idle: 'idle',
|
|
123
|
+
loading: 'loading',
|
|
124
|
+
success: 'success',
|
|
125
|
+
error: 'error',
|
|
126
|
+
} as const;
|
|
127
|
+
|
|
128
|
+
type Status = (typeof Status)[keyof typeof Status];
|
|
129
|
+
|
|
130
|
+
// Easy to extend
|
|
131
|
+
const ExtendedStatus = {
|
|
132
|
+
...Status,
|
|
133
|
+
pending: 'pending',
|
|
134
|
+
cancelled: 'cancelled',
|
|
135
|
+
} as const;
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Type Extensibility Design
|
|
139
|
+
|
|
140
|
+
### Interface Extension
|
|
141
|
+
|
|
142
|
+
**Rule**: Use interfaces for object shapes that may be extended.
|
|
143
|
+
|
|
144
|
+
**Example**:
|
|
145
|
+
|
|
146
|
+
```typescript
|
|
147
|
+
export interface BaseComponentProps {
|
|
148
|
+
className?: string;
|
|
149
|
+
id?: string;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export interface ButtonProps extends BaseComponentProps {
|
|
153
|
+
onClick: () => void;
|
|
154
|
+
disabled?: boolean;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export interface IconButtonProps extends ButtonProps {
|
|
158
|
+
icon: React.ReactNode;
|
|
159
|
+
label: string;
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### Type Intersection for Composition
|
|
164
|
+
|
|
165
|
+
**Rule**: Use type intersections for composing multiple types.
|
|
166
|
+
|
|
167
|
+
**Example**:
|
|
168
|
+
|
|
169
|
+
```typescript
|
|
170
|
+
type Clickable = {
|
|
171
|
+
onClick: () => void;
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
type Hoverable = {
|
|
175
|
+
onMouseEnter: () => void;
|
|
176
|
+
onMouseLeave: () => void;
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
type InteractiveButton = Clickable &
|
|
180
|
+
Hoverable & {
|
|
181
|
+
label: string;
|
|
182
|
+
};
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### Discriminated Unions for Type Safety
|
|
186
|
+
|
|
187
|
+
**Rule**: Use discriminated unions for type-safe handling of different variants.
|
|
188
|
+
|
|
189
|
+
**Example**:
|
|
190
|
+
|
|
191
|
+
```typescript
|
|
192
|
+
type LoadingState = {
|
|
193
|
+
status: 'loading';
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
type SuccessState<T> = {
|
|
197
|
+
status: 'success';
|
|
198
|
+
data: T;
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
type ErrorState = {
|
|
202
|
+
status: 'error';
|
|
203
|
+
error: string;
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
type AsyncState<T> = LoadingState | SuccessState<T> | ErrorState;
|
|
207
|
+
|
|
208
|
+
function handleState<T>(state: AsyncState<T>): void {
|
|
209
|
+
switch (state.status) {
|
|
210
|
+
case 'loading':
|
|
211
|
+
// TypeScript knows state is LoadingState
|
|
212
|
+
console.log('Loading...');
|
|
213
|
+
break;
|
|
214
|
+
case 'success':
|
|
215
|
+
// TypeScript knows state is SuccessState<T>
|
|
216
|
+
console.log('Data:', state.data);
|
|
217
|
+
break;
|
|
218
|
+
case 'error':
|
|
219
|
+
// TypeScript knows state is ErrorState
|
|
220
|
+
console.error('Error:', state.error);
|
|
221
|
+
break;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
## Generics Usage
|
|
227
|
+
|
|
228
|
+
### When to Use Generics
|
|
229
|
+
|
|
230
|
+
Use generics when:
|
|
231
|
+
|
|
232
|
+
1. Creating reusable components or functions that work with multiple types
|
|
233
|
+
2. Maintaining type relationships between function parameters and return values
|
|
234
|
+
3. Creating type-safe data structures
|
|
235
|
+
|
|
236
|
+
### Generic Naming Conventions
|
|
237
|
+
|
|
238
|
+
**Rule**: Use descriptive generic names, typically single uppercase letters.
|
|
239
|
+
|
|
240
|
+
- `<T>` - Generic type
|
|
241
|
+
- `<TItem>` - Generic item type
|
|
242
|
+
- `<TData>` - Generic data type
|
|
243
|
+
- `<TKey>` - Generic key type
|
|
244
|
+
- `<TValue>` - Generic value type
|
|
245
|
+
|
|
246
|
+
### Generic Constraints
|
|
247
|
+
|
|
248
|
+
**Rule**: Always constrain generics when possible to ensure type safety.
|
|
249
|
+
|
|
250
|
+
**Example**:
|
|
251
|
+
|
|
252
|
+
```typescript
|
|
253
|
+
// Unconstrained (less safe)
|
|
254
|
+
function getValue<T>(obj: T, key: string): unknown {
|
|
255
|
+
return (obj as Record<string, unknown>)[key];
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// Constrained (safer)
|
|
259
|
+
function getValue<T extends Record<string, unknown>>(obj: T, key: keyof T): T[keyof T] {
|
|
260
|
+
return obj[key];
|
|
261
|
+
}
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
### Generic Component Example
|
|
265
|
+
|
|
266
|
+
**Example**: Generic table column component
|
|
267
|
+
|
|
268
|
+
```typescript
|
|
269
|
+
export interface ColumnType<T = Record<string, unknown>> {
|
|
270
|
+
title: React.ReactNode;
|
|
271
|
+
dataIndex?: string | string[];
|
|
272
|
+
key?: string;
|
|
273
|
+
width?: number | string;
|
|
274
|
+
align?: 'left' | 'center' | 'right';
|
|
275
|
+
sorter?: boolean | ((a: T, b: T) => number);
|
|
276
|
+
sortOrder?: SortOrder;
|
|
277
|
+
render?: (value: unknown, record: T, index: number) => React.ReactNode;
|
|
278
|
+
onCell?: (record: T, index: number) => React.HTMLAttributes<HTMLTableCellElement>;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
interface TableProps<T> {
|
|
282
|
+
dataSource: T[];
|
|
283
|
+
columns: ColumnType<T>[];
|
|
284
|
+
rowKey: (record: T) => string | number;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
function Table<T extends Record<string, unknown>>({ dataSource, columns, rowKey }: TableProps<T>): JSX.Element {
|
|
288
|
+
// Implementation
|
|
289
|
+
}
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
### Generic Function Example
|
|
293
|
+
|
|
294
|
+
**Example**: Generic input component
|
|
295
|
+
|
|
296
|
+
```typescript
|
|
297
|
+
type GenericInputProps = {
|
|
298
|
+
currentName?: string;
|
|
299
|
+
onConfirm: (value: string) => boolean;
|
|
300
|
+
onExit: () => void;
|
|
301
|
+
maximum?: number;
|
|
302
|
+
};
|
|
303
|
+
|
|
304
|
+
const GenericInput = <T extends PopupComponent & GenericInputProps>(props: T): JSX.Element => {
|
|
305
|
+
const { currentName = '', onConfirm, onExit, maximum = 20 } = props;
|
|
306
|
+
|
|
307
|
+
// Implementation
|
|
308
|
+
};
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
### Advanced Generic Patterns
|
|
312
|
+
|
|
313
|
+
**Pattern 1: Conditional Types**
|
|
314
|
+
|
|
315
|
+
```typescript
|
|
316
|
+
type ValueType<T> = T extends Record<any, infer V> ? (V extends Record<any, infer V2> ? V2 : V) : never;
|
|
317
|
+
|
|
318
|
+
type KeyType<T> = T extends Record<infer K, any> ? K : never;
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
**Pattern 2: Mapped Types**
|
|
322
|
+
|
|
323
|
+
```typescript
|
|
324
|
+
type Partial<T> = {
|
|
325
|
+
[P in keyof T]?: T[P];
|
|
326
|
+
};
|
|
327
|
+
|
|
328
|
+
type Readonly<T> = {
|
|
329
|
+
readonly [P in keyof T]: T[P];
|
|
330
|
+
};
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
## Type Imports
|
|
334
|
+
|
|
335
|
+
**Rule**: Use `import type` for type-only imports to improve build performance.
|
|
336
|
+
|
|
337
|
+
**Example**:
|
|
338
|
+
|
|
339
|
+
```typescript
|
|
340
|
+
import React, { useState } from 'react';
|
|
341
|
+
import type { MousePos } from '@/src/utils/mouseRx/types';
|
|
342
|
+
import type { AppButtonProps } from './types';
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
## Function Return Types
|
|
346
|
+
|
|
347
|
+
**Rule**: Always explicitly define return types for functions.
|
|
348
|
+
|
|
349
|
+
**Example**:
|
|
350
|
+
|
|
351
|
+
```typescript
|
|
352
|
+
const processData = (input: string): string => {
|
|
353
|
+
return input.toUpperCase();
|
|
354
|
+
};
|
|
355
|
+
|
|
356
|
+
const fetchData = async (url: string): Promise<Response> => {
|
|
357
|
+
return await fetch(url);
|
|
358
|
+
};
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
## Interface vs Type Alias
|
|
362
|
+
|
|
363
|
+
### Use Interfaces For:
|
|
364
|
+
|
|
365
|
+
- Object shapes, especially props and public APIs
|
|
366
|
+
- When you need declaration merging
|
|
367
|
+
- When defining contracts that may be extended
|
|
368
|
+
|
|
369
|
+
**Example**:
|
|
370
|
+
|
|
371
|
+
```typescript
|
|
372
|
+
export interface AppButtonProps {
|
|
373
|
+
disable?: boolean;
|
|
374
|
+
selected?: boolean;
|
|
375
|
+
className?: string;
|
|
376
|
+
}
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
### Use Type Aliases For:
|
|
380
|
+
|
|
381
|
+
- Unions, intersections, and complex types
|
|
382
|
+
- When you need computed types
|
|
383
|
+
- When defining types that won't be extended
|
|
384
|
+
|
|
385
|
+
**Example**:
|
|
386
|
+
|
|
387
|
+
```typescript
|
|
388
|
+
export type TKnobProps = {
|
|
389
|
+
config: KnobConfig;
|
|
390
|
+
};
|
|
391
|
+
|
|
392
|
+
export type SortOrder = 'ascend' | 'descend' | null;
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
## Common Patterns and Anti-patterns
|
|
396
|
+
|
|
397
|
+
### ✅ Good Patterns
|
|
398
|
+
|
|
399
|
+
**Pattern 1: Type Guards**
|
|
400
|
+
|
|
401
|
+
```typescript
|
|
402
|
+
function isString(value: unknown): value is string {
|
|
403
|
+
return typeof value === 'string';
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
function process(value: unknown): void {
|
|
407
|
+
if (isString(value)) {
|
|
408
|
+
// TypeScript knows value is string here
|
|
409
|
+
console.log(value.toUpperCase());
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
**Pattern 2: Branded Types**
|
|
415
|
+
|
|
416
|
+
```typescript
|
|
417
|
+
type UserId = string & { readonly __brand: unique symbol };
|
|
418
|
+
type ProductId = string & { readonly __brand: unique symbol };
|
|
419
|
+
|
|
420
|
+
function getUser(id: UserId): User {
|
|
421
|
+
// Implementation
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
// Prevents mixing UserId and ProductId
|
|
425
|
+
const userId = '123' as UserId;
|
|
426
|
+
const productId = '456' as ProductId;
|
|
427
|
+
// getUser(productId); // Type error!
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
### ❌ Anti-patterns
|
|
431
|
+
|
|
432
|
+
**Anti-pattern 1: Overusing `any`**
|
|
433
|
+
|
|
434
|
+
```typescript
|
|
435
|
+
// Bad
|
|
436
|
+
function process(data: any): any {
|
|
437
|
+
return data.value;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
// Good
|
|
441
|
+
function process<T extends { value: string }>(data: T): string {
|
|
442
|
+
return data.value;
|
|
443
|
+
}
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
**Anti-pattern 2: Type Assertions Without Validation**
|
|
447
|
+
|
|
448
|
+
```typescript
|
|
449
|
+
// Bad
|
|
450
|
+
const data = response as UserData;
|
|
451
|
+
processUser(data);
|
|
452
|
+
|
|
453
|
+
// Good
|
|
454
|
+
function isUserData(data: unknown): data is UserData {
|
|
455
|
+
return typeof data === 'object' && data !== null && 'id' in data && 'name' in data;
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
if (isUserData(response)) {
|
|
459
|
+
processUser(response);
|
|
460
|
+
}
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
**Anti-pattern 3: Ignoring Type Errors**
|
|
464
|
+
|
|
465
|
+
```typescript
|
|
466
|
+
// Bad
|
|
467
|
+
const value = data.value as string; // @ts-ignore
|
|
468
|
+
|
|
469
|
+
// Good
|
|
470
|
+
if (typeof data.value === 'string') {
|
|
471
|
+
const value = data.value;
|
|
472
|
+
// Use value safely
|
|
473
|
+
}
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
## Summary Checklist
|
|
477
|
+
|
|
478
|
+
When writing TypeScript code, ensure:
|
|
479
|
+
|
|
480
|
+
- [ ] No `any` types used (use `unknown` if truly unknown)
|
|
481
|
+
- [ ] Enums follow naming convention (PascalCase enum, camelCase values)
|
|
482
|
+
- [ ] Types are designed for extensibility
|
|
483
|
+
- [ ] Generics are used when appropriate with proper constraints
|
|
484
|
+
- [ ] Function return types are explicitly defined
|
|
485
|
+
- [ ] `import type` is used for type-only imports
|
|
486
|
+
- [ ] Interfaces are used for object shapes, types for unions/intersections
|
|
487
|
+
- [ ] Type guards are used for runtime type checking
|
|
488
|
+
- [ ] Discriminated unions are used for type-safe variant handling
|
|
489
|
+
|
|
490
|
+
## References
|
|
491
|
+
|
|
492
|
+
- [TypeScript Handbook](https://www.typescriptlang.org/docs/handbook/intro.html)
|
|
493
|
+
- Project Coding Standards: `desktop-team-documentation/instructions/coding-conventions/frontend.md`
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# Desktop Team AWS Storage
|
|
2
|
+
|
|
3
|
+
*Last Updated: 2025-10-16*
|
|
4
|
+
|
|
5
|
+
This document provides access information and usage instructions for the Desktop Team's AWS S3 storage infrastructure.
|
|
6
|
+
|
|
7
|
+
## Access Information
|
|
8
|
+
|
|
9
|
+
### AWS Console Login
|
|
10
|
+
|
|
11
|
+
- **URL**: https://positivegrid-aws.signin.aws.amazon.com/console
|
|
12
|
+
- **Account ID/Alias**: `positivegrid-aws`
|
|
13
|
+
- **Username**: Contact IT department to request account
|
|
14
|
+
- **Password**: Contact IT department to request account
|
|
15
|
+
- **AWS Credentials** (`Access key ID`, `Secret access key`): Contact IT department
|
|
16
|
+
|
|
17
|
+
### S3 Bucket
|
|
18
|
+
|
|
19
|
+
**Bucket Name**: `positivegrid-bias`
|
|
20
|
+
|
|
21
|
+
## Connecting via Cyberduck
|
|
22
|
+
|
|
23
|
+
[Cyberduck](https://cyberduck.io/) is the recommended S3 client for accessing the Desktop Team storage.
|
|
24
|
+
|
|
25
|
+
### Setup Instructions
|
|
26
|
+
|
|
27
|
+
1. **Download and Install**
|
|
28
|
+
- Download [Cyberduck](https://cyberduck.io/) for your platform
|
|
29
|
+
- Install the application
|
|
30
|
+
|
|
31
|
+
2. **Configure Connection**
|
|
32
|
+
- Open Cyberduck
|
|
33
|
+
- Create a new connection with the AWS credentials provided by IT
|
|
34
|
+
- Use the configuration shown below:
|
|
35
|
+
|
|
36
|
+

|
|
37
|
+
|
|
38
|
+
### Connection Parameters
|
|
39
|
+
|
|
40
|
+
- **Protocol**: Amazon S3
|
|
41
|
+
- **Server**: s3.amazonaws.com
|
|
42
|
+
- **Access Key ID**: Provided by IT department
|
|
43
|
+
- **Secret Access Key**: Provided by IT department
|
|
44
|
+
- **Path**: `/positivegrid-bias` (or leave blank to browse all buckets)
|
|
45
|
+
|
|
46
|
+
## Security Guidelines
|
|
47
|
+
|
|
48
|
+
- **Never commit credentials** to source control
|
|
49
|
+
- **Store credentials securely** using your system's keychain or password manager
|
|
50
|
+
- **Request separate credentials** for each team member (no shared accounts)
|
|
51
|
+
- **Rotate credentials** if compromised immediately and notify IT
|
|
52
|
+
|
|
53
|
+
## Common Use Cases
|
|
54
|
+
|
|
55
|
+
- Storing build artifacts and release packages
|
|
56
|
+
- Sharing large files between team members
|
|
57
|
+
- Backup storage for important project resources
|
|
58
|
+
- Hosting static assets for testing
|
|
59
|
+
|
|
60
|
+
## Troubleshooting
|
|
61
|
+
|
|
62
|
+
### Connection Issues
|
|
63
|
+
|
|
64
|
+
If you cannot connect to the S3 bucket:
|
|
65
|
+
|
|
66
|
+
1. Verify credentials are correct (Access Key ID and Secret Access Key)
|
|
67
|
+
2. Check network connectivity and firewall settings
|
|
68
|
+
3. Ensure your AWS account has proper S3 permissions
|
|
69
|
+
4. Contact IT if credentials need to be regenerated
|
|
70
|
+
|
|
71
|
+
### Permission Errors
|
|
72
|
+
|
|
73
|
+
If you can connect but receive permission errors:
|
|
74
|
+
|
|
75
|
+
1. Verify you're accessing the correct bucket (`positivegrid-bias`)
|
|
76
|
+
2. Check that your account has read/write permissions
|
|
77
|
+
3. Contact IT to verify IAM policy settings
|
|
78
|
+
|
|
79
|
+
## Related Resources
|
|
80
|
+
|
|
81
|
+
- [AWS S3 Documentation](https://docs.aws.amazon.com/s3/)
|
|
82
|
+
- [Cyberduck Documentation](https://docs.cyberduck.io/)
|
|
83
|
+
- [Tech Stack Overview](./tech-stack.md)
|
|
84
|
+
|
|
85
|
+
## Support
|
|
86
|
+
|
|
87
|
+
For AWS access issues or questions:
|
|
88
|
+
|
|
89
|
+
- **IT Department**: Contact for credentials and account setup
|
|
90
|
+
- **Team Lead**: For bucket organization and usage policies
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
**Maintained by**: Desktop Team
|
|
95
|
+
**Contact**: IT Department for access, Team Lead for usage questions
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Positive Grid Desktop 產品 CRM 系統
|
|
2
|
+
|
|
3
|
+
*Last Updated: 2025-10-16*
|
|
4
|
+
|
|
5
|
+
## 系統連結
|
|
6
|
+
|
|
7
|
+
### Production
|
|
8
|
+
|
|
9
|
+
https://crm-console.positivegrid.com/login
|
|
10
|
+
|
|
11
|
+
### Staging
|
|
12
|
+
|
|
13
|
+
https://crm-console-staging.positivegrid.com/login
|
|
14
|
+
|
|
15
|
+
## 登入方式
|
|
16
|
+
|
|
17
|
+
使用公司帳號即可登入
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
**Maintained by**: Desktop Team
|
|
22
|
+
**Contact**: IT Department for account access, Backend Team for CRM system issues
|