@axboot-mcp/mcp-server 1.0.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/CLAUDE.md +119 -0
- package/MCP_TOOL_PLAN.md +710 -0
- package/MCP_USAGE.md +914 -0
- package/README.md +168 -0
- package/REPOSITORY_CONVENTIONS.md +250 -0
- package/SEARCH_PARAMS_MCP_TOOL_COMPLETE_PLAN.md +646 -0
- package/SEARCH_PARAMS_PLAN.md +2570 -0
- package/STORE_PATTERNS.md +1178 -0
- package/debug-dto.js +72 -0
- package/generate-banner-store.js +62 -0
- package/generation-plan.json +2176 -0
- package/generation-results.json +1817 -0
- package/package.json +45 -0
- package/scripts/batch-generate-all.js +159 -0
- package/scripts/batch-generate-mcp.js +329 -0
- package/scripts/batch-generate-stores-v2.js +272 -0
- package/scripts/batch-generate-stores.js +179 -0
- package/scripts/batch-plan.json +3810 -0
- package/scripts/batch-process.py +90 -0
- package/scripts/batch-regenerate.js +356 -0
- package/scripts/direct-generate.js +227 -0
- package/scripts/execute-batches.js +1911 -0
- package/scripts/generate-all-stores.js +144 -0
- package/scripts/generate-stores-mcp.js +161 -0
- package/scripts/generate-stores-v2.js +450 -0
- package/scripts/generate-stores-v3.js +412 -0
- package/scripts/generate-stores-v4.js +521 -0
- package/scripts/generate-stores.js +382 -0
- package/scripts/repos-to-process.json +1899 -0
- package/src/config/nh-layout-patterns.ts +166 -0
- package/src/docs/HOOK_GENERATION_PLAN.md +2226 -0
- package/src/docs/NH_STORE_PATTERNS.md +297 -0
- package/src/docs/README.md +216 -0
- package/src/docs/index.ts +28 -0
- package/src/docs/loader.ts +568 -0
- package/src/docs/patterns.json +419 -0
- package/src/docs/practical-examples.md +732 -0
- package/src/docs/quick-start.md +257 -0
- package/src/docs/requirements-analysis-guide.md +364 -0
- package/src/docs/rules.json +321 -0
- package/src/docs/store-pattern-analysis.md +664 -0
- package/src/docs/store-patterns-rules.md +1168 -0
- package/src/docs/store-patterns-usage-guide.md +1835 -0
- package/src/docs/troubleshooting.md +544 -0
- package/src/docs/type-selection-guide.md +572 -0
- package/src/docs//354/202/254/354/232/251/353/262/225/AntD-/354/273/264/355/217/254/353/204/214/355/212/270-/354/202/254/354/232/251/353/262/225.md +1515 -0
- package/src/docs//354/202/254/354/232/251/353/262/225/DataGrid-/354/202/254/354/232/251/353/262/225.md +866 -0
- package/src/docs//354/202/254/354/232/251/353/262/225/FormItem-/354/202/254/354/232/251/353/262/225.md +903 -0
- package/src/docs//354/202/254/354/232/251/353/262/225/FormModal-/354/202/254/354/232/251/353/262/225.md +1155 -0
- package/src/docs//354/202/254/354/232/251/353/262/225/MCP-/353/260/224/354/235/264/353/270/214/354/275/224/353/224/251-/352/260/200/354/235/264/353/223/234.md +1133 -0
- package/src/docs//354/202/254/354/232/251/353/262/225/MSW-Mock-/353/215/260/354/235/264/355/204/260-/354/202/254/354/232/251/353/262/225.md +579 -0
- package/src/docs//354/202/254/354/232/251/353/262/225/Search-/354/273/264/355/217/254/353/204/214/355/212/270-/354/202/254/354/232/251/353/262/225.md +738 -0
- package/src/docs//354/202/254/354/232/251/353/262/225/Store-/355/214/250/355/204/264-/354/202/254/354/232/251/353/262/225.md +1135 -0
- package/src/docs//354/202/254/354/232/251/353/262/225//355/231/224/353/251/264/352/265/254/354/204/261-/355/203/200/354/236/205/353/263/204-/352/260/234/353/260/234/354/210/234/354/204/234.md +1805 -0
- package/src/docs//354/202/254/354/232/251/353/262/225//355/231/224/353/251/264/355/203/200/354/236/205/353/263/204-/352/260/234/353/260/234-/355/224/204/353/241/254/355/224/204/355/212/270-/352/260/200/354/235/264/353/223/234.md +946 -0
- package/src/docs//354/202/254/354/232/251/353/262/225//355/231/225/354/236/245/355/231/224/353/251/264/355/203/200/354/236/205/353/263/204-/354/203/201/354/204/270-/355/224/204/353/241/254/355/224/204/355/212/270/352/260/200/354/235/264/353/223/234.md +2422 -0
- package/src/features/store-features.ts +232 -0
- package/src/handlers/analyze-requirements.ts +403 -0
- package/src/handlers/analyze.ts +1373 -0
- package/src/handlers/generate-from-requirements.ts +250 -0
- package/src/handlers/generate-hook.ts +950 -0
- package/src/handlers/generate-interactive.ts +840 -0
- package/src/handlers/generate-listdatagrid.ts +521 -0
- package/src/handlers/generate-multi-stores.ts +577 -0
- package/src/handlers/generate-requirements-from-layout.ts +160 -0
- package/src/handlers/generate-search-params.ts +717 -0
- package/src/handlers/generate.ts +911 -0
- package/src/handlers/list-templates.ts +104 -0
- package/src/handlers/scan-metadata.ts +485 -0
- package/src/handlers/suggest-layout.ts +326 -0
- package/src/index.ts +959 -0
- package/src/prompts/search-params.md +793 -0
- package/src/templates/index.ts +107 -0
- package/src/templates/unified.ts +462 -0
- package/store-generation-error-patterns.md +225 -0
- package/test/useAgentStore.ts +136 -0
- package/test-server.js +78 -0
- package/tsconfig.json +20 -0
|
@@ -0,0 +1,544 @@
|
|
|
1
|
+
# 문제 해결 가이드
|
|
2
|
+
|
|
3
|
+
> MCP-AXBoot 사용 시 발생할 수 있는 문제와 해결 방법을 정리했습니다.
|
|
4
|
+
|
|
5
|
+
## 목차
|
|
6
|
+
|
|
7
|
+
1. [빌드/설치 문제](#1 빌드설치-문제)
|
|
8
|
+
2. [Store 생성 문제](#2-store-생성-문제)
|
|
9
|
+
3. [타입 오류](#3-타입-오류)
|
|
10
|
+
4. [런타임 오류](#4-런타임-오류)
|
|
11
|
+
5. [품질 개선 팁](#5-품질-개선-팁)
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## 1. 빌드/설치 문제
|
|
16
|
+
|
|
17
|
+
### 문제 1.1: import.meta 오류
|
|
18
|
+
|
|
19
|
+
**에러 메시지**:
|
|
20
|
+
```
|
|
21
|
+
error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'es2020'...
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
**원인**: CommonJS 환경에서 `import.meta` 사용
|
|
25
|
+
|
|
26
|
+
**해결**: 이미 `src/docs/loader.ts`에서 해결됨. 경로 계산 로직이 CommonJS 호환되도록 구현됨.
|
|
27
|
+
|
|
28
|
+
**참고**: `docs/loader.ts`의 `getDocsDir()` 함수 참조
|
|
29
|
+
|
|
30
|
+
### 문제 1.2: 모듈 찾기 오류
|
|
31
|
+
|
|
32
|
+
**에러 메시지**:
|
|
33
|
+
```
|
|
34
|
+
Cannot find module '../docs/index.js' or its corresponding type declarations
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
**원인**: 빌드되지 않았거나 경로 오류
|
|
38
|
+
|
|
39
|
+
**해결**:
|
|
40
|
+
```bash
|
|
41
|
+
# 프로젝트 루트에서
|
|
42
|
+
npm run build
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### 문제 1.3: docs 폴더 누락
|
|
46
|
+
|
|
47
|
+
**에러 메시지**:
|
|
48
|
+
```
|
|
49
|
+
ENOENT: no such file or directory, open '.../dist/docs/patterns.json'
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
**원인**: docs 파일이 dist로 복사되지 않음
|
|
53
|
+
|
|
54
|
+
**해결 1**: package.json에 copy 스크립트 추가
|
|
55
|
+
```json
|
|
56
|
+
{
|
|
57
|
+
"scripts": {
|
|
58
|
+
"build": "tsc && npm run copy-docs",
|
|
59
|
+
"copy-docs": "cp -r src/docs dist/docs"
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
**해결 2**: tsconfig.json 설정 확인
|
|
65
|
+
```json
|
|
66
|
+
{
|
|
67
|
+
"compilerOptions": {
|
|
68
|
+
"rootDir": "./src",
|
|
69
|
+
"outDir": "./dist"
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## 2. Store 생성 문제
|
|
77
|
+
|
|
78
|
+
### 문제 2.1: Repository 분석 실패
|
|
79
|
+
|
|
80
|
+
**에러 메시지**:
|
|
81
|
+
```
|
|
82
|
+
{
|
|
83
|
+
"success": false,
|
|
84
|
+
"error": "인터페이스 분석 실패"
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
**원인**: Repository 파일이 TypeScript 인터페이스가 아님
|
|
89
|
+
|
|
90
|
+
**해결**: Repository 파일 형식 확인
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
// ✅ 올바른 형식
|
|
94
|
+
export interface MemberRepository {
|
|
95
|
+
postMemberListMember(request: PostMemberListMemberRequest): Promise<MemberListResponse>;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// ❌ 잘못된 형식
|
|
99
|
+
export class MemberRepository {
|
|
100
|
+
async postMemberListMember(request: PostMemberListMemberRequest) {
|
|
101
|
+
// ...
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### 문제 2.2: 지원하지 않는 Store 타입
|
|
107
|
+
|
|
108
|
+
**에러 메시지**:
|
|
109
|
+
```
|
|
110
|
+
{
|
|
111
|
+
"success": false,
|
|
112
|
+
"error": "지원하지 않는 Store 타입입니다: 15"
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
**원인**: 타입 번호가 1~10 범위를 벗어남
|
|
117
|
+
|
|
118
|
+
**해결**: 올바른 타입 번호 사용
|
|
119
|
+
|
|
120
|
+
| 타입 | 이름 | 설명 |
|
|
121
|
+
|-----|------|------|
|
|
122
|
+
| 1 | Basic List | 단순 조회 |
|
|
123
|
+
| 2 | List + Excel | 엑셀 다운로드 |
|
|
124
|
+
| 3 | List + Detail | 상세 보기/편집 |
|
|
125
|
+
| 4 | Master-Detail | 마스터-디테일 |
|
|
126
|
+
| 5 | CRUD | 전체 기능 |
|
|
127
|
+
| 6 | Tree + Form | 트리 구조 |
|
|
128
|
+
| 7 | Dashboard | 대시보드 |
|
|
129
|
+
| 8 | Modal Based | 모달 기반 |
|
|
130
|
+
| 9 | Status Change | 상태 변경 |
|
|
131
|
+
| 10 | Master-Detail + Excel | 엑셀 포함 |
|
|
132
|
+
|
|
133
|
+
### 문제 2.3: 잘못된 타입 추천
|
|
134
|
+
|
|
135
|
+
**증상**: 요구사항과 맞지 않는 타입이 추천됨
|
|
136
|
+
|
|
137
|
+
**해결 1**: 더 구체적인 요구사항 작성
|
|
138
|
+
|
|
139
|
+
```
|
|
140
|
+
❌ "회원 Store"
|
|
141
|
+
✅ "회원 목록을 보여주고 검색할 수 있으며, 선택하면 상세 정보를 보여주는 Store"
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
**해결 2**: `analyze_requirements`로 먼저 분석
|
|
145
|
+
|
|
146
|
+
```
|
|
147
|
+
"회원 목록에 상세 보기, 저장, 삭제가 있는 Store"를 분석해줘.
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
**해결 3**: 타입을 직접 지정
|
|
151
|
+
|
|
152
|
+
```
|
|
153
|
+
Type 5 (CRUD)로 Store를 만들어줘.
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## 3. 타입 오류
|
|
159
|
+
|
|
160
|
+
### 문제 3.1: Request/Response 타입 불일치
|
|
161
|
+
|
|
162
|
+
**에러 메시지**:
|
|
163
|
+
```
|
|
164
|
+
Type 'PostMemberListRequest' is not assignable to type 'ListRequest'
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
**원인**: Repository Request 타입을 확장하지 않음
|
|
168
|
+
|
|
169
|
+
**해결**: ListRequest가 Repository Request를 확장하도록 수정
|
|
170
|
+
|
|
171
|
+
```typescript
|
|
172
|
+
// ✅ 올바름
|
|
173
|
+
interface ListRequest extends PostMemberListMemberRequest {
|
|
174
|
+
dateRange?: [string, string];
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// ❌ 잘못됨
|
|
178
|
+
interface ListRequest {
|
|
179
|
+
pageNumber: number;
|
|
180
|
+
pageSize: number;
|
|
181
|
+
}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### 문제 3.2: Actions 타입 오류
|
|
185
|
+
|
|
186
|
+
**에러 메시지**:
|
|
187
|
+
```
|
|
188
|
+
Property 'callXXXApi' does not exist on type...
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
**원인**: Actions 인터페이스에 메서드 누락
|
|
192
|
+
|
|
193
|
+
**해결**: Actions 인터페이스에 메서드 추가
|
|
194
|
+
|
|
195
|
+
```typescript
|
|
196
|
+
interface Actions extends PageStoreActions<States> {
|
|
197
|
+
callListApi: (request?: ListRequest) => Promise<void>;
|
|
198
|
+
callSaveApi: (request?: SaveRequest) => Promise<void>; // 추가
|
|
199
|
+
// ...
|
|
200
|
+
}
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### 문제 3.3: TemplateVariables 타입 오류
|
|
204
|
+
|
|
205
|
+
**에러 메시지**:
|
|
206
|
+
```
|
|
207
|
+
Object literal may only specify known properties, and 'XXX' does not exist in type 'TemplateVariables'
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
**원인**: 템플릿에 새 변수를 추가했지만 TemplateVariables 인터페이스에 없음
|
|
211
|
+
|
|
212
|
+
**해결**: `src/templates/index.ts`에 필드 추가
|
|
213
|
+
|
|
214
|
+
```typescript
|
|
215
|
+
export interface TemplateVariables {
|
|
216
|
+
// ... 기존 필드
|
|
217
|
+
METADATA_FIELDS?: string; // 추가
|
|
218
|
+
CREATE_STATE_FIELDS?: string; // 추가
|
|
219
|
+
}
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
---
|
|
223
|
+
|
|
224
|
+
## 4. 런타임 오류
|
|
225
|
+
|
|
226
|
+
### 문제 4.1: API 호출 실패
|
|
227
|
+
|
|
228
|
+
**증상**: 리스트가 로드되지 않음
|
|
229
|
+
|
|
230
|
+
**해결 1**: Service 메서드명 확인
|
|
231
|
+
|
|
232
|
+
```typescript
|
|
233
|
+
// 생성된 코드
|
|
234
|
+
await MemberService.postMemberList(apiParam);
|
|
235
|
+
|
|
236
|
+
// 실제 Service 확인
|
|
237
|
+
// services/MemberService.ts에서 메서드명 확인
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
**해결 2**: deleteEmptyValue 사용 확인
|
|
241
|
+
|
|
242
|
+
```typescript
|
|
243
|
+
// ✅ 올바름
|
|
244
|
+
await MemberService.postMemberList(
|
|
245
|
+
deleteEmptyValue({ ...apiParam })
|
|
246
|
+
);
|
|
247
|
+
|
|
248
|
+
// ❌ 잘못됨
|
|
249
|
+
await MemberService.postMemberList(apiParam);
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
**해결 3**: API 파라미터 구조 확인
|
|
253
|
+
|
|
254
|
+
```typescript
|
|
255
|
+
// Request 구조 확인
|
|
256
|
+
const apiParam: ListRequest = {
|
|
257
|
+
pageNumber: 1,
|
|
258
|
+
pageSize: 100,
|
|
259
|
+
// 필요한 파라미터 모두 포함
|
|
260
|
+
};
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
### 문제 4.2: 스피넝이 멈추지 않음
|
|
264
|
+
|
|
265
|
+
**증상**: 로딩 스피너가 계속 돔
|
|
266
|
+
|
|
267
|
+
**원인**: finally 블록 누락
|
|
268
|
+
|
|
269
|
+
**해결**: finally 블록에서 스피닝 해제
|
|
270
|
+
|
|
271
|
+
```typescript
|
|
272
|
+
// ✅ 올바름
|
|
273
|
+
callListApi: async (request) => {
|
|
274
|
+
if (get().listSpinning) return;
|
|
275
|
+
set({ listSpinning: true });
|
|
276
|
+
|
|
277
|
+
try {
|
|
278
|
+
// API 호출
|
|
279
|
+
} finally {
|
|
280
|
+
set({ listSpinning: false }); // 필수
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
// ❌ 잘못됨
|
|
285
|
+
callListApi: async (request) => {
|
|
286
|
+
set({ listSpinning: true });
|
|
287
|
+
await API.call();
|
|
288
|
+
// finally 블록 누락
|
|
289
|
+
}
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
### 문ssue 4.3: Store.subscribe 오류
|
|
293
|
+
|
|
294
|
+
**증상**: 탭 전환 시 상태가 유지되지 않음
|
|
295
|
+
|
|
296
|
+
**해결 1**: equalityFn 확인
|
|
297
|
+
|
|
298
|
+
```typescript
|
|
299
|
+
// ✅ 올바름
|
|
300
|
+
useXXXStore.subscribe(
|
|
301
|
+
(s) => ({ ... }),
|
|
302
|
+
getTabStoreListener<MetaData>(createState.routePath),
|
|
303
|
+
{ equalityFn: shallow }, // 필수
|
|
304
|
+
);
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
**해결 2**: Selector에 모든 MetaData 필드 포함
|
|
308
|
+
|
|
309
|
+
```typescript
|
|
310
|
+
// ✅ 올바름 - 모든 필드 포함
|
|
311
|
+
useXXXStore.subscribe(
|
|
312
|
+
(s): Record<keyof MetaData, any> => ({
|
|
313
|
+
programFn: s.programFn,
|
|
314
|
+
listRequestValue: s.listRequestValue,
|
|
315
|
+
listColWidths: s.listColWidths,
|
|
316
|
+
listSortParams: s.listSortParams,
|
|
317
|
+
}),
|
|
318
|
+
// ...
|
|
319
|
+
);
|
|
320
|
+
|
|
321
|
+
// ❌ 잘못됨 - 필드 누락
|
|
322
|
+
useXXXStore.subscribe(
|
|
323
|
+
(s): Record<keyof MetaData, any> => ({
|
|
324
|
+
programFn: s.programFn,
|
|
325
|
+
listRequestValue: s.listRequestValue,
|
|
326
|
+
// listColWidths 누락
|
|
327
|
+
}),
|
|
328
|
+
// ...
|
|
329
|
+
);
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
---
|
|
333
|
+
|
|
334
|
+
## 5. 품질 개선 팁
|
|
335
|
+
|
|
336
|
+
### 팁 1: 생성 후 커스터마이징
|
|
337
|
+
|
|
338
|
+
Store 생성 후 프로젝트에 맞게 커스터마이징하세요.
|
|
339
|
+
|
|
340
|
+
**초기 검색조건 추가**:
|
|
341
|
+
|
|
342
|
+
```typescript
|
|
343
|
+
const createState: States = {
|
|
344
|
+
listRequestValue: {
|
|
345
|
+
pageNumber: 1,
|
|
346
|
+
pageSize: 100,
|
|
347
|
+
// 프로젝트에 맞는 검색조건 추가
|
|
348
|
+
searchKeyword: "",
|
|
349
|
+
searchStatus: "ACTIVE",
|
|
350
|
+
searchType: "ALL",
|
|
351
|
+
dateRange: undefined,
|
|
352
|
+
},
|
|
353
|
+
// ...
|
|
354
|
+
};
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
**API 파라미터 변환 로직 추가**:
|
|
358
|
+
|
|
359
|
+
```typescript
|
|
360
|
+
callListApi: async (request) => {
|
|
361
|
+
// ...
|
|
362
|
+
|
|
363
|
+
// 파라미터 변환
|
|
364
|
+
const apiParam = {
|
|
365
|
+
...get().listRequestValue,
|
|
366
|
+
...request,
|
|
367
|
+
// 프로젝트 특화 변환
|
|
368
|
+
startDate: request.dateRange?.[0],
|
|
369
|
+
endDate: request.dateRange?.[1],
|
|
370
|
+
};
|
|
371
|
+
|
|
372
|
+
// ...
|
|
373
|
+
},
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
### 팁 2: 타입 안전성 확보
|
|
377
|
+
|
|
378
|
+
**DTO 타입 정의**:
|
|
379
|
+
|
|
380
|
+
```typescript
|
|
381
|
+
// Repository Response 타입 활용
|
|
382
|
+
interface DtoItem extends MemberRes {
|
|
383
|
+
// 추가 필드가 필요한 경우
|
|
384
|
+
fullName?: string;
|
|
385
|
+
}
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
**Service 타입 import**:
|
|
389
|
+
|
|
390
|
+
```typescript
|
|
391
|
+
// services/index.ts에서 재export 활용
|
|
392
|
+
import {
|
|
393
|
+
MemberService,
|
|
394
|
+
PostMemberListMemberRequest,
|
|
395
|
+
MemberRes,
|
|
396
|
+
} from "services";
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
### 팁 3: 성능 최적화
|
|
400
|
+
|
|
401
|
+
**불시적 비교 사용 (shallow)**:
|
|
402
|
+
|
|
403
|
+
```typescript
|
|
404
|
+
// 컴포넌트에서 Store 사용 시
|
|
405
|
+
import { shallow } from 'zustand/shallow';
|
|
406
|
+
|
|
407
|
+
const listData = useMemberListStore(
|
|
408
|
+
(state) => state.listData,
|
|
409
|
+
shallow
|
|
410
|
+
);
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
**선택자 사용**:
|
|
414
|
+
|
|
415
|
+
```typescript
|
|
416
|
+
// 필요한 상태만 선택
|
|
417
|
+
const { listData, callListApi } = useMemberListStore(
|
|
418
|
+
(state) => ({
|
|
419
|
+
listData: state.listData,
|
|
420
|
+
callListApi: state.callListApi,
|
|
421
|
+
})
|
|
422
|
+
);
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
### 팁 4: 재사용 가능한 Hooks
|
|
426
|
+
|
|
427
|
+
Store와 함께 사용할 커스텀 Hook을 만드세요.
|
|
428
|
+
|
|
429
|
+
```typescript
|
|
430
|
+
// hooks/useMemberList.ts
|
|
431
|
+
export function useMemberList() {
|
|
432
|
+
const store = useMemberListStore();
|
|
433
|
+
|
|
434
|
+
useEffect(() => {
|
|
435
|
+
if (!store.listData.length) {
|
|
436
|
+
store.callListApi();
|
|
437
|
+
}
|
|
438
|
+
}, []);
|
|
439
|
+
|
|
440
|
+
const handleSearch = (keyword: string) => {
|
|
441
|
+
store.setListRequestValue({
|
|
442
|
+
...store.listRequestValue,
|
|
443
|
+
searchKeyword: keyword,
|
|
444
|
+
});
|
|
445
|
+
store.callListApi();
|
|
446
|
+
};
|
|
447
|
+
|
|
448
|
+
return {
|
|
449
|
+
...store,
|
|
450
|
+
handleSearch,
|
|
451
|
+
};
|
|
452
|
+
}
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
### 팁 5: 테스트 가능한 Store
|
|
456
|
+
|
|
457
|
+
Store를 테스트하기 쉽게 만드세요.
|
|
458
|
+
|
|
459
|
+
```typescript
|
|
460
|
+
// 테스트용 초기값
|
|
461
|
+
export const createTestStore = (initialState?: Partial<States>) =>
|
|
462
|
+
create(subscribeWithSelector<memberListStore>((set, get) => ({
|
|
463
|
+
...createState,
|
|
464
|
+
...initialState,
|
|
465
|
+
...createActions(set, get),
|
|
466
|
+
})));
|
|
467
|
+
|
|
468
|
+
// 테스트 예시
|
|
469
|
+
describe('useMemberListStore', () => {
|
|
470
|
+
it('should load list data', async () => {
|
|
471
|
+
const store = createTestStore();
|
|
472
|
+
await store.callListApi();
|
|
473
|
+
expect(store.listData).toHaveLength(10);
|
|
474
|
+
});
|
|
475
|
+
});
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
---
|
|
479
|
+
|
|
480
|
+
## 6. 디버깅 팁
|
|
481
|
+
|
|
482
|
+
### 팁 1: Store 상태 확인
|
|
483
|
+
|
|
484
|
+
```typescript
|
|
485
|
+
// 개발 중 상태 확인
|
|
486
|
+
useEffect(() => {
|
|
487
|
+
console.log('Store State:', useMemberListStore.getState());
|
|
488
|
+
}, []);
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
### 팁 2: API 요청/응답 확인
|
|
492
|
+
|
|
493
|
+
```typescript
|
|
494
|
+
callListApi: async (request) => {
|
|
495
|
+
console.log('API Request:', { ...get().listRequestValue, ...request });
|
|
496
|
+
|
|
497
|
+
try {
|
|
498
|
+
const response = await MemberService.postMemberList(apiParam);
|
|
499
|
+
console.log('API Response:', response);
|
|
500
|
+
// ...
|
|
501
|
+
} catch (error) {
|
|
502
|
+
console.error('API Error:', error);
|
|
503
|
+
throw error;
|
|
504
|
+
}
|
|
505
|
+
},
|
|
506
|
+
```
|
|
507
|
+
|
|
508
|
+
### 팁 3: MCP 도구 확인
|
|
509
|
+
|
|
510
|
+
생성된 Store가 올바른지 `analyze_requirements`로 확인:
|
|
511
|
+
|
|
512
|
+
```
|
|
513
|
+
"useMemberListStore와 유사한 기능을 가진 Store 타입을 추천해줘.
|
|
514
|
+
리스트, 검색, 저장, 삭제, 엑셀 다운로드가 필요해.
|
|
515
|
+
```
|
|
516
|
+
|
|
517
|
+
---
|
|
518
|
+
|
|
519
|
+
## 7. 지원 및 피드백
|
|
520
|
+
|
|
521
|
+
### 문제 보고
|
|
522
|
+
|
|
523
|
+
문제가 발생하면 다음 정보를 포함하여 보고해주세요:
|
|
524
|
+
|
|
525
|
+
1. **Repository 인터페이스**: 사용한 Repository의 인터페이스 정의
|
|
526
|
+
2. **요구사항**: Store 생성 요청 시 사용한 요구사항
|
|
527
|
+
3. **에러 메시지**: 전체 에러 메시지
|
|
528
|
+
4. **예상 동작**: 기대하던 동작
|
|
529
|
+
|
|
530
|
+
### 기능 요청
|
|
531
|
+
|
|
532
|
+
새로운 Store 타입이나 기능이 필요하면:
|
|
533
|
+
|
|
534
|
+
1. `docs/patterns.json`에 새 패턴 추가
|
|
535
|
+
2. `src/templates/`에 새 템플릿 추가
|
|
536
|
+
3. `src/features/store-features.ts`에 피처 추가
|
|
537
|
+
|
|
538
|
+
### 문서 기여
|
|
539
|
+
|
|
540
|
+
경험을 공유하고 싶으시면:
|
|
541
|
+
|
|
542
|
+
1. 예제 추가: `practical-examples.md`
|
|
543
|
+
2. 문서 개선: 기존 문서 업데이트
|
|
544
|
+
3. 템플릿 개선: 더 나은 템플릿 제안
|