@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.
Files changed (78) hide show
  1. package/CLAUDE.md +119 -0
  2. package/MCP_TOOL_PLAN.md +710 -0
  3. package/MCP_USAGE.md +914 -0
  4. package/README.md +168 -0
  5. package/REPOSITORY_CONVENTIONS.md +250 -0
  6. package/SEARCH_PARAMS_MCP_TOOL_COMPLETE_PLAN.md +646 -0
  7. package/SEARCH_PARAMS_PLAN.md +2570 -0
  8. package/STORE_PATTERNS.md +1178 -0
  9. package/debug-dto.js +72 -0
  10. package/generate-banner-store.js +62 -0
  11. package/generation-plan.json +2176 -0
  12. package/generation-results.json +1817 -0
  13. package/package.json +45 -0
  14. package/scripts/batch-generate-all.js +159 -0
  15. package/scripts/batch-generate-mcp.js +329 -0
  16. package/scripts/batch-generate-stores-v2.js +272 -0
  17. package/scripts/batch-generate-stores.js +179 -0
  18. package/scripts/batch-plan.json +3810 -0
  19. package/scripts/batch-process.py +90 -0
  20. package/scripts/batch-regenerate.js +356 -0
  21. package/scripts/direct-generate.js +227 -0
  22. package/scripts/execute-batches.js +1911 -0
  23. package/scripts/generate-all-stores.js +144 -0
  24. package/scripts/generate-stores-mcp.js +161 -0
  25. package/scripts/generate-stores-v2.js +450 -0
  26. package/scripts/generate-stores-v3.js +412 -0
  27. package/scripts/generate-stores-v4.js +521 -0
  28. package/scripts/generate-stores.js +382 -0
  29. package/scripts/repos-to-process.json +1899 -0
  30. package/src/config/nh-layout-patterns.ts +166 -0
  31. package/src/docs/HOOK_GENERATION_PLAN.md +2226 -0
  32. package/src/docs/NH_STORE_PATTERNS.md +297 -0
  33. package/src/docs/README.md +216 -0
  34. package/src/docs/index.ts +28 -0
  35. package/src/docs/loader.ts +568 -0
  36. package/src/docs/patterns.json +419 -0
  37. package/src/docs/practical-examples.md +732 -0
  38. package/src/docs/quick-start.md +257 -0
  39. package/src/docs/requirements-analysis-guide.md +364 -0
  40. package/src/docs/rules.json +321 -0
  41. package/src/docs/store-pattern-analysis.md +664 -0
  42. package/src/docs/store-patterns-rules.md +1168 -0
  43. package/src/docs/store-patterns-usage-guide.md +1835 -0
  44. package/src/docs/troubleshooting.md +544 -0
  45. package/src/docs/type-selection-guide.md +572 -0
  46. 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
  47. 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
  48. 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
  49. 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
  50. 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
  51. 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
  52. 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
  53. 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
  54. 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
  55. 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
  56. 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
  57. package/src/features/store-features.ts +232 -0
  58. package/src/handlers/analyze-requirements.ts +403 -0
  59. package/src/handlers/analyze.ts +1373 -0
  60. package/src/handlers/generate-from-requirements.ts +250 -0
  61. package/src/handlers/generate-hook.ts +950 -0
  62. package/src/handlers/generate-interactive.ts +840 -0
  63. package/src/handlers/generate-listdatagrid.ts +521 -0
  64. package/src/handlers/generate-multi-stores.ts +577 -0
  65. package/src/handlers/generate-requirements-from-layout.ts +160 -0
  66. package/src/handlers/generate-search-params.ts +717 -0
  67. package/src/handlers/generate.ts +911 -0
  68. package/src/handlers/list-templates.ts +104 -0
  69. package/src/handlers/scan-metadata.ts +485 -0
  70. package/src/handlers/suggest-layout.ts +326 -0
  71. package/src/index.ts +959 -0
  72. package/src/prompts/search-params.md +793 -0
  73. package/src/templates/index.ts +107 -0
  74. package/src/templates/unified.ts +462 -0
  75. package/store-generation-error-patterns.md +225 -0
  76. package/test/useAgentStore.ts +136 -0
  77. package/test-server.js +78 -0
  78. package/tsconfig.json +20 -0
@@ -0,0 +1,646 @@
1
+ # SearchParams 대화형 생성 MCP 툴 완전 계획서
2
+
3
+ > **목차**
4
+ > 1. [개요](#1-개요)
5
+ > 2. [SearchParamType 상세](#2-searchparamtype-상세)
6
+ > 3. [패턴 카탈로그 및 대화형 설정](#3-패턴-카탈로그-및-대화형-설정)
7
+ > 4. [메타데이터 수집 시스템](#4-메타데이터-수집-시스템)
8
+ > 5. [MCP 툴 스키마](#5-mcp-툴-스키마)
9
+ > 6. [코드 생성 예시](#6-코드-생성-예시)
10
+
11
+ ---
12
+
13
+ ## 1. 개요
14
+
15
+ ### 1.1 목적
16
+
17
+ SearchParams(검색 폼) 컴포넌트를 대화형으로 생성하는 MCP 툴입니다.
18
+
19
+ ### 1.2 핵심 컨셉
20
+
21
+ - **자연어 대화**: 사용자가 자연어로 설명하면 AI가 패턴을 추론하여 코드 생성
22
+ - **패턴 카탈로그**: 16가지 검색 컴포넌트 패턴 제공
23
+ - **메타데이터 기반**: 프로젝트의 DTO, Repository, Code 등을 스캔하여 자동 완성
24
+ - **extends 체인 추적**: Repository 인터페이스의 Request 타입이 실제 DTO를 extend하는 경우 모든 필드 수집
25
+
26
+ ### 1.3 처리 흐름
27
+
28
+ ```
29
+ 1. 메타데이터 스캔 (SCAN 툴)
30
+ └─ DTO, Repository, Modal, Service, Hook, Code 수집
31
+ └─ extends 체인 추적으로 완전한 필드 수집
32
+ └─ .mcp-cache/에 저장
33
+
34
+ 2. 대화형 생성 (GENERATE 툴)
35
+ └─ 필드별 패턴 선택 (16가지 옵션)
36
+ └─ 추가 설정 (옵션, 기본값, 너비 등)
37
+ └─ SearchParams JSX 코드 생성
38
+
39
+ 3. 파일 생성
40
+ └─ App.tsx의 <PageSearchBar> 내부에 삽입
41
+ ```
42
+
43
+ ---
44
+
45
+ ## 2. SearchParamType 상세
46
+
47
+ ### 2.1 타입 목록
48
+
49
+ | # | 타입 | 설명 | 빈도 |
50
+ |---|------|------|------|
51
+ | 1 | INPUT | 텍스트 입력 | 115회 |
52
+ | 2 | GROUP | 검색구분 + 텍스트 | 110회 |
53
+ | 3 | SELECT | 드롭다운 선택 | 191회 |
54
+ | 4 | CHECKBOX | 체크박스 다중 선택 | 14회 |
55
+ | 5 | SELECT_MULTI | 멀티 셀렉트 | 38회 |
56
+ | 6 | RADIO | 라디오 버튼 | 127회 |
57
+ | 7 | DTPICKER_DATE | 단일 날짜 | 1회 |
58
+ | 8 | DTPICKER_DATE_RANGE | 날짜 범위 | 100회 |
59
+ | 9 | NUMBER_RANGE | 숫자 범위 | 1회 |
60
+ | 10 | AUTOCOMPLETE | 자동완성 검색 | - |
61
+ | 11 | CASCADE | 계층 선택 | - |
62
+ | 12 | MODAL | 모달 검색 | - |
63
+ | 13 | CONDITIONAL | 조건부 필드 | - |
64
+ | 14 | SKIP | 제외 | - |
65
+ | 15 | HIDDEN | 숨김 | - |
66
+ | 16 | LINE_BREAK | 줄바꿈 | 15회 |
67
+
68
+ ---
69
+
70
+ ## 3. 패턴 카탈로그 및 대화형 설정
71
+
72
+ ### 3.1 패턴 선택 메인 화면
73
+
74
+ ```
75
+ [MCP] usrNm (회원명) 필드를 발견했습니다.
76
+ 어떤 검색 컴포넌트를 사용할까요?
77
+
78
+ ┌─────────────────────────────────────────────────────────────────────┐
79
+ │ 1. 🤖 AI에게 맡기기 (자연어로 설명) │
80
+ ├─────────────────────────────────────────────────────────────────────┤
81
+ │ 2. 📝 일반 텍스트 입력 (INPUT) │
82
+ ├─────────────────────────────────────────────────────────────────────┤
83
+ │ 3. 🔍 검색구분 + 텍스트 (GROUP) │
84
+ ├─────────────────────────────────────────────────────────────────────┤
85
+ │ 4. 📋 드롭다운 선택 (SELECT) │
86
+ ├─────────────────────────────────────────────────────────────────────┤
87
+ │ 5. ✓ 체크박스 다중 선택 (CHECKBOX) │
88
+ ├─────────────────────────────────────────────────────────────────────┤
89
+ │ 6. ☐ 멀티 셀렉트 (SELECT_MULTI) │
90
+ ├─────────────────────────────────────────────────────────────────────┤
91
+ │ 7. ○ 라디오 버튼 (RADIO) │
92
+ ├─────────────────────────────────────────────────────────────────────┤
93
+ │ 8. 📅 단일 날짜 (DTPICKER_DATE) │
94
+ ├─────────────────────────────────────────────────────────────────────┤
95
+ │ 9. 📆 날짜 범위 (DTPICKER_DATE_RANGE) │
96
+ ├─────────────────────────────────────────────────────────────────────┤
97
+ │ 10. 🔢 숫자 범위 (NUMBER_RANGE) │
98
+ ├─────────────────────────────────────────────────────────────────────┤
99
+ │ 11. ⏭️ 스킵 (SKIP) │
100
+ ├─────────────────────────────────────────────────────────────────────┤
101
+ │ 12. 👁️ 숨김 (HIDDEN) │
102
+ ├─────────────────────────────────────────────────────────────────────┤
103
+ │ 13. 🔀 조건부 필드 (CONDITIONAL) │
104
+ ├─────────────────────────────────────────────────────────────────────┤
105
+ │ 14. 🔍 자동완성 (AUTOCOMPLETE) │
106
+ ├─────────────────────────────────────────────────────────────────────┤
107
+ │ 15. 🌊 계층 선택 (CASCADE) │
108
+ ├─────────────────────────────────────────────────────────────────────┤
109
+ │ 16. 🪟 모달 검색 (MODAL) │
110
+ └─────────────────────────────────────────────────────────────────────┘
111
+
112
+ 번호를 입력하세요:
113
+ ```
114
+
115
+ ### 3.2 INPUT (일반 텍스트)
116
+
117
+ ```tsx
118
+ {
119
+ label: t("회원명"),
120
+ name: "usrNm",
121
+ type: SearchParamType.INPUT,
122
+ width: 200,
123
+ placeholder: t("회원명을 입력하세요"),
124
+ }
125
+ ```
126
+
127
+ ### 3.3 GROUP (검색구분 + 텍스트)
128
+
129
+ ```tsx
130
+ {
131
+ type: SearchParamType.GROUP,
132
+ children: [
133
+ {
134
+ label: t("검색어구분"),
135
+ name: "searchType",
136
+ type: SearchParamType.SELECT,
137
+ options: [
138
+ { label: t("제목"), value: "TITLE" },
139
+ { label: t("내용"), value: "CONTENT" },
140
+ ],
141
+ width: 120,
142
+ },
143
+ {
144
+ label: t("검색어"),
145
+ name: "searchText",
146
+ type: SearchParamType.INPUT,
147
+ },
148
+ ],
149
+ }
150
+ ```
151
+
152
+ ### 3.4 SELECT (드롭다운)
153
+
154
+ ```tsx
155
+ // Code Store 사용
156
+ {
157
+ label: t("상태코드"),
158
+ name: "statusCd",
159
+ type: SearchParamType.SELECT,
160
+ codeVar: "STATUS_CD", // useCodeStore에서 자동 추출
161
+ width: 150,
162
+ }
163
+
164
+ // 직접 옵션
165
+ {
166
+ label: t("정렬"),
167
+ name: "sortType",
168
+ type: SearchParamType.SELECT,
169
+ options: [
170
+ { label: t("최신순"), value: "latest" },
171
+ { label: t("이름순"), value: "name" },
172
+ ],
173
+ width: 150,
174
+ }
175
+ ```
176
+
177
+ ### 3.5 CHECKBOX (체크박스 다중)
178
+
179
+ ```tsx
180
+ {
181
+ label: t("회원가입채널"),
182
+ name: "sbscrbPathClcdArr",
183
+ type: SearchParamType.CHECKBOX,
184
+ options: SBSCRB_PATH_CLCD?.options ?? [],
185
+ checkAllItem: true, // "전체" 옵션 추가
186
+ defaultValue: ["Y", "02"],
187
+ }
188
+ ```
189
+
190
+ ### 3.6 RADIO (라디오 버튼)
191
+
192
+ ```tsx
193
+ // Y/N 패턴
194
+ {
195
+ label: t("사용여부"),
196
+ name: "useYn",
197
+ type: SearchParamType.RADIO,
198
+ options: [
199
+ { label: t("전체"), value: "" },
200
+ { label: t("Y"), value: "Y" },
201
+ { label: t("N"), value: "N" },
202
+ ],
203
+ initialValue: "Y",
204
+ }
205
+ ```
206
+
207
+ ### 3.7 DTPICKER_DATE_RANGE (날짜 범위)
208
+
209
+ ```tsx
210
+ {
211
+ label: t("가입기간"),
212
+ placeholder: [t("년월일"), t("년월일")],
213
+ name: "dateRange",
214
+ type: SearchParamType.DTPICKER_DATE_RANGE,
215
+ format: DT_FORMAT.DATE,
216
+ isTimeSelector: false,
217
+ presetRender: DtPickerPresetRender({ type: "all" }),
218
+ defaultValue: [dayjs().subtract(30, 'day'), dayjs()],
219
+ }
220
+ ```
221
+
222
+ ### 3.8 NUMBER_RANGE (숫자 범위)
223
+
224
+ ```tsx
225
+ {
226
+ label: t("방문회수"),
227
+ placeholder: [t("MIN"), t("MAX")],
228
+ name: "visitCount",
229
+ type: SearchParamType.NUMBER_RANGE,
230
+ defaultValue: [10, 100],
231
+ }
232
+ ```
233
+
234
+ ### 3.9 AUTOCOMPLETE (자동완성)
235
+
236
+ ```tsx
237
+ {
238
+ placeholder: t("고객사"),
239
+ name: "custDto",
240
+ type: SearchParamType.AUTOCOMPLETE,
241
+ onSearch: async (filter?: string) => {
242
+ const { ds } = await CustomerService.getCustomerList({
243
+ filter,
244
+ filterCond: "CONTAINS",
245
+ pageSize: 100,
246
+ });
247
+ return ds.map((n) => ({
248
+ key: n.id ?? "",
249
+ value: n, // 전체 객체 저장
250
+ label: `${n.custNm} (${bizNumFormatter(n.bizNum)})`,
251
+ }));
252
+ },
253
+ }
254
+ ```
255
+
256
+ ### 3.10 CASCADE (계층 선택)
257
+
258
+ ```tsx
259
+ const { list: organizationOption } = useOrganizationCascadeData();
260
+
261
+ {
262
+ placeholder: t("조직"),
263
+ name: "_orgCd",
264
+ width: 200,
265
+ type: SearchParamType.CASCADE,
266
+ options: organizationOption,
267
+ displayRender: (labels: string[]) => labels[labels.length - 1],
268
+ onSelect: (option) => {
269
+ setUserComboParams({ ...option });
270
+ },
271
+ }
272
+ ```
273
+
274
+ ### 3.11 MODAL (모달 검색)
275
+
276
+ ```tsx
277
+ {
278
+ placeholder: t("고객사코드"),
279
+ name: "custId",
280
+ type: SearchParamType.MODAL,
281
+ onSearch: async () => {
282
+ const data = await openCustomerModal();
283
+ return [{
284
+ label: data.customer?.custNm,
285
+ value: JSON.stringify({
286
+ custId: data.customer?.id,
287
+ custNm: data.customer?.custNm,
288
+ }),
289
+ }];
290
+ },
291
+ config: {
292
+ single: true,
293
+ },
294
+ width: 150,
295
+ }
296
+ ```
297
+
298
+ ### 3.12 CONDITIONAL (조건부 필드)
299
+
300
+ ```tsx
301
+ // prdBbsRvwTpcd가 "1"일 때만 표시
302
+ ...(listRequestValue.prdBbsRvwTpcd === "1"
303
+ ? [{
304
+ label: t("상세옵션"),
305
+ name: "prdBbsRvwDtlTpcdArray",
306
+ type: SearchParamType.CHECKBOX,
307
+ options: PRD_BBS_RVW_DTL_TPCD?.options,
308
+ }]
309
+ : [])
310
+ ```
311
+
312
+ ---
313
+
314
+ ## 4. 메타데이터 수집 시스템
315
+
316
+ ### 4.1 수집 항목
317
+
318
+ | 항목 | 설명 | 사용처 |
319
+ |------|------|--------|
320
+ | DTO 필드 | Request/Response DTO의 모든 필드 | 필드 목록 자동 완성 |
321
+ | Repository API | Repository 인터페이스의 메서드 시그니처 | API 연동 패턴 |
322
+ | 모달 함수 | `openXxxModal()` 형태의 함수 | MODAL 타입 |
323
+ | 서비스 | API 서비스 메서드 | AUTOCOMPLETE 타입 |
324
+ | 훅 | 계층 데이터 훅 | CASCADE 타입 |
325
+ | 코드 | Code Store의 코드 변수명 | SELECT, CHECKBOX |
326
+
327
+ ### 4.2 extends 체인 추적 (중요!)
328
+
329
+ **실제 프로젝트에서 Repository 인터페이스의 Request 타입이 실제 DTO를 `extends` 합니다.**
330
+
331
+ ```typescript
332
+ // 예시 구조
333
+ export interface PostMemberListMemberRequest extends MemberSearch {
334
+ pageNumber?: number;
335
+ pageSize?: number;
336
+ }
337
+
338
+ export interface MemberSearch extends DefaultDto {
339
+ usrNm?: string;
340
+ usrTpcd?: string;
341
+ }
342
+
343
+ export interface DefaultDto {
344
+ __status__?: DtoItemStatus;
345
+ rowId?: string;
346
+ crtrId?: string;
347
+ // ...
348
+ }
349
+ ```
350
+
351
+ **체인 추적 인터페이스:**
352
+
353
+ ```typescript
354
+ interface DtoIndex {
355
+ name: string; // 인터페이스 명
356
+ filePath: string; // 파일 경로
357
+ extends?: string[]; // 상속 체인 (예: ["MemberSearch", "DefaultDto"])
358
+ fields: DtoField[]; // 모든 필드 (extends 포함)
359
+ }
360
+
361
+ interface DtoField {
362
+ name: string; // 필드명
363
+ type: string; // 타입
364
+ isOptional: boolean; // optional 여부
365
+ comment?: string; // 주석
366
+ source?: string; // 정의 위치 (예: "MemberSearch")
367
+ }
368
+ ```
369
+
370
+ **체인 추적 알고리즘:**
371
+
372
+ ```typescript
373
+ async function resolveExtendsChain(
374
+ interfaceName: string,
375
+ cache: MetadataCache,
376
+ visited = new Set<string>()
377
+ ): Promise<DtoIndex> {
378
+ if (visited.has(interfaceName)) {
379
+ return { name: interfaceName, fields: [] }; // 순환 참조 방지
380
+ }
381
+ visited.add(interfaceName);
382
+
383
+ const current = cache.dtos[interfaceName];
384
+ if (!current) return { name: interfaceName, fields: [] };
385
+
386
+ const allFields = [...current.fields];
387
+ const extendsChain: string[] = [];
388
+
389
+ if (current.extends) {
390
+ for (const parent of current.extends) {
391
+ extendsChain.push(parent);
392
+ const parentDto = await resolveExtendsChain(parent, cache, visited);
393
+ allFields.push(...parentDto.fields);
394
+ }
395
+ }
396
+
397
+ // 필드 중복 제거 (하위 클래스가 우선)
398
+ const uniqueFields = Array.from(
399
+ new Map(allFields.map(f => [f.name, f])).values()
400
+ );
401
+
402
+ return {
403
+ ...current,
404
+ extends: [...new Set(extendsChain)],
405
+ fields: uniqueFields,
406
+ };
407
+ }
408
+ ```
409
+
410
+ > **이미 구현됨**: `analyze_interface` MCP 툴(`src/handlers/analyze.ts`)의 `extractRequestFields()` 함수가 이미 extends 체인 추적을 구현하고 있습니다.
411
+
412
+ ### 4.3 스캔 경로 패턴
413
+
414
+ ```typescript
415
+ const DTO_PATTERNS = [
416
+ 'src/services/@interface/dto/**/*.ts', // 1순위
417
+ 'src/services/**/dto/**/*.ts', // 2순위
418
+ 'src/types/**/*Dto*.ts', // 3순위
419
+ 'src/interfaces/**/*Request*.ts', // 4순위
420
+ 'src/interfaces/**/*Response*.ts', // 5순위
421
+ ];
422
+
423
+ const SCAN_PATTERNS = {
424
+ repository: ['src/services/**/*Repository.ts'],
425
+ modal: ['src/modals/**/*Modal.ts'],
426
+ service: ['src/services/**/*.ts'],
427
+ hook: ['src/hooks/**/*.ts'],
428
+ };
429
+ ```
430
+
431
+ ### 4.4 캐시 저장 위치
432
+
433
+ ```
434
+ 프젝트 루트/
435
+ ├── .mcp-cache/
436
+ │ ├── search-params-meta.json
437
+ │ ├── .gitignore
438
+ │ └── README.md
439
+ ├── src/
440
+ └── package.json
441
+ ```
442
+
443
+ ### 4.5 캐시 구조 예시
444
+
445
+ ```json
446
+ {
447
+ "version": "1.0.0",
448
+ "scannedAt": "2024-01-15T10:30:00Z",
449
+ "projectRoot": "/Users/kyle/Desktop/nh-fe-bo",
450
+ "dtos": {
451
+ "PostMemberListMemberRequest": {
452
+ "name": "PostMemberListMemberRequest",
453
+ "filePath": "/path/to/MemberInterface.ts",
454
+ "extends": ["MemberSearch", "DefaultDto"],
455
+ "fields": [
456
+ { "name": "__status__", "type": "DtoItemStatus", "source": "DefaultDto" },
457
+ { "name": "usrNm", "type": "string", "source": "MemberSearch" },
458
+ { "name": "pageNumber", "type": "number", "source": "PostMemberListMemberRequest" }
459
+ ]
460
+ }
461
+ },
462
+ "repositories": {
463
+ "MemberRepository": {
464
+ "filePath": "/path/to/MemberRepository.ts",
465
+ "methods": [
466
+ {
467
+ "name": "postMemberListMember",
468
+ "requestType": "PostMemberListMemberRequest",
469
+ "responseType": "PostMemberListMemberResponse"
470
+ }
471
+ ]
472
+ }
473
+ }
474
+ }
475
+ ```
476
+
477
+ ---
478
+
479
+ ## 5. MCP 툴 스키마
480
+
481
+ ### 5.1 SCAN 툴 (메타데이터 수집)
482
+
483
+ ```typescript
484
+ {
485
+ name: 'scan_search_params_metadata',
486
+ description: 'SearchParams 생성을 위한 프로젝트 메타데이터 수집',
487
+ inputSchema: {
488
+ type: 'object',
489
+ properties: {
490
+ projectRoot: {
491
+ type: 'string',
492
+ description: '프로젝트 루트 경로 (절대 경로)',
493
+ },
494
+ forceRescan: {
495
+ type: 'boolean',
496
+ description: '강제 재스캔 여부',
497
+ },
498
+ },
499
+ required: ['projectRoot'],
500
+ },
501
+ }
502
+ ```
503
+
504
+ ### 5.2 GENERATE 툴 (대화형 생성)
505
+
506
+ ```typescript
507
+ {
508
+ name: 'generate_search_params_interactive',
509
+ description: 'SearchParams를 대화형으로 생성 (캐시 기반)',
510
+ inputSchema: {
511
+ type: 'object',
512
+ properties: {
513
+ outPath: {
514
+ type: 'string',
515
+ description: '출력 SearchParams 파일 경로 (절대 경로)',
516
+ },
517
+ dtoName: {
518
+ type: 'string',
519
+ description: 'Request DTO 명 (선택 시 캐시에서 필드 목록 자동 완성)',
520
+ },
521
+ },
522
+ required: ['outPath'],
523
+ },
524
+ }
525
+ ```
526
+
527
+ ---
528
+
529
+ ## 6. 코드 생성 예시
530
+
531
+ ### 6.1 기본 예시
532
+
533
+ ```tsx
534
+ <SearchParams
535
+ form={searchForm}
536
+ params={[
537
+ { label: t("이름"), name: 'usrNm', type: SearchParamType.INPUT },
538
+ { label: t("이메일"), name: 'usrEmailAddr', type: SearchParamType.INPUT },
539
+ null, // 줄바꿈
540
+ { label: t("사용여부"), name: 'useYn', type: SearchParamType.RADIO,
541
+ options: [{ label: t("전체"), value: "" }, { label: t("Y"), value: "Y" }, { label: t("N"), value: "N" }] },
542
+ { label: t("상태"), name: 'statusCd', type: SearchParamType.SELECT, codeVar: 'STATUS_CD' },
543
+ null, // 줄바꿈
544
+ { label: t("가입일"), name: 'dateRange', type: SearchParamType.DTPICKER_DATE_RANGE,
545
+ format: DT_FORMAT.DATE, presetRender: DtPickerPresetRender({ type: "all" }) },
546
+ ]}
547
+ paramsValue={listRequestValue}
548
+ onChangeParamsValue={setListRequestValue}
549
+ onSearch={handleSearch}
550
+ spinning={listSpinning}
551
+ />
552
+ ```
553
+
554
+ ### 6.2 App.tsx 삽입 위치
555
+
556
+ ```tsx
557
+ <Container stretch role={"page-container"}>
558
+ <Header>
559
+ <ProgramTitle>...</ProgramTitle>
560
+ <Flex align={"center"} gap={6}>
561
+ <Button onClick={handleSearch}>{t("btn.검색")}</Button>
562
+ </Flex>
563
+
564
+ {/* 👇 SearchParams 삽입 위치 */}
565
+ <PageSearchBar>
566
+ <SearchParams
567
+ form={searchForm}
568
+ params={[/* 생성된 params 배열 */]}
569
+ paramsValue={listRequestValue}
570
+ onChangeParamsValue={setListRequestValue}
571
+ onSearch={handleSearch}
572
+ spinning={listSpinning}
573
+ />
574
+ </PageSearchBar>
575
+ </Header>
576
+
577
+ <Body>
578
+ <Frame>
579
+ <ListDataGrid />
580
+ </Frame>
581
+ </Body>
582
+ </Container>
583
+ ```
584
+
585
+ ### 6.3 필요한 styled 컴포넌트
586
+
587
+ ```tsx
588
+ const Container = styled(PageLayout)``;
589
+ const Header = styled(PageLayout.Header)``;
590
+ const PageSearchBar = styled(PageLayout.PageSearchBar)``; // 필수
591
+ const Body = styled(PageLayout.FrameRow)``;
592
+ const Frame = styled(PageLayout.FrameColumn)``;
593
+ ```
594
+
595
+ ---
596
+
597
+ ## 7. 자연어 처리 규칙
598
+
599
+ | 키워드 | 컴포넌트 | 예시 |
600
+ |--------|----------|------|
601
+ | 검색어, 텍스트, 입력 | INPUT | "이름으로 검색" |
602
+ | 드롭다운, 셀렉트 | SELECT | "드롭다운으로" |
603
+ | 체크박스, 다중 선택 | CHECKBOX | "여러 개 선택" |
604
+ | 라디오, Y/N | RADIO | "사용여부 Y/N" |
605
+ | 날짜, 일자 | DTPICKER_DATE | "가입일자" |
606
+ | 기간, 범위 | DTPICKER_DATE_RANGE | "가입기간" |
607
+ | 숫자 범위 | NUMBER_RANGE | "방문회수 범위" |
608
+ | 검색구분 + 텍스트 | GROUP | "제목/내용 검색" |
609
+ | 코드, 분류 | SELECT + codeVar | "상태코드" |
610
+ | 필수, 필수입력 | required: true | "필수 입력" |
611
+ | placeholder ~ | placeholder: "~" | "placeholder는 '검색어'" |
612
+
613
+ ---
614
+
615
+ ## 8. 파일 감시 및 증분 스캔
616
+
617
+ ```typescript
618
+ // watch 대상
619
+ const WATCH_PATTERNS = [
620
+ 'src/services/@interface/dto/**/*.ts',
621
+ 'src/services/**/*Repository.ts',
622
+ 'src/modals/**/*Modal.ts',
623
+ ];
624
+
625
+ // 증분 업데이트
626
+ watcher.on('change', (filePath) => {
627
+ if (filePath.includes('/dto/')) {
628
+ const dto = await scanSingleDto(filePath);
629
+ cache.dtos[dto.name] = dto;
630
+ await saveCache(cache);
631
+ }
632
+ });
633
+ ```
634
+
635
+ ---
636
+
637
+ ## 9. 장점
638
+
639
+ | 장점 | 설명 |
640
+ |------|------|
641
+ | 누락 방지 | 전체 DTO를 스캔하여 Request 타입 누락 없음 |
642
+ | 위치 독립적 | DTO가 어디에 있든 상관없이 자동 발견 |
643
+ | Repository 연동 | Repository 메서드 시그니처와 DTO 자동 매칭 |
644
+ | 빠른 대화형 | 캐시된 데이터로 즉시 필드 선택 가능 |
645
+ | 자동 업데이트 | 파일 감시로 최신 상태 유지 |
646
+ | Fail-safe | 캐시 없으면 백그라운드 자동 스캔 |