@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,579 @@
1
+ # MSW Mock 데이터 사용법
2
+
3
+ > API 응답 데이터를 자동으로 저장하고 재사용하여, 외부 API 의존도를 줄이고 개발 효율을 높이는 방법
4
+
5
+ ## 📋 개요
6
+
7
+ 이 기능은 MSW(Mock Service Worker)와 IndexedDB를 사용하여:
8
+ - **첫 번째 API 호출**: 실제 API 호출 후 응답 데이터 자동 저장
9
+ - **두 번째부터**: 저장된 mock 데이터 사용 (API 호출 없음)
10
+ - **영구 저장**: 브라우저를 닫아도 데이터 유지
11
+
12
+ ## 🎯 주요 장점
13
+
14
+ - ✅ **외부 API 차단 대응**: 네트워크 차단 시에도 개발 가능
15
+ - ✅ **빠른 개발**: API 응답을 기다리지 않고 즉시 데이터 사용
16
+ - ✅ **일관된 데이터**: 동일한 테스트 데이터로 반복 작업
17
+ - ✅ **환경별 설정**: `.env` 파일로 쉽게 ON/OFF 제어
18
+
19
+ ## 🚀 적용 방법
20
+
21
+ ### 1. MSW 설치
22
+
23
+ ```bash
24
+ npm install msw --save-dev
25
+ ```
26
+
27
+ ### 2. MSW Service Worker 초기화
28
+
29
+ ```bash
30
+ npx msw init public/ --save
31
+ ```
32
+
33
+ ### 3. 필수 파일 생성
34
+
35
+ #### `src/mocks/storage/mockStorage.ts`
36
+
37
+ IndexedDB를 사용한 mock 데이터 저장소:
38
+
39
+ ```typescript
40
+ const DB_NAME = 'msw-mock-data';
41
+ const DB_VERSION = 1;
42
+ const STORE_NAME = 'api-responses';
43
+
44
+ let db: IDBDatabase | null = null;
45
+
46
+ const initDB = (): Promise<IDBDatabase> => {
47
+ return new Promise((resolve, reject) => {
48
+ const request = indexedDB.open(DB_NAME, DB_VERSION);
49
+
50
+ request.onerror = () => reject(request.error);
51
+ request.onsuccess = () => {
52
+ db = request.result;
53
+ resolve(db);
54
+ };
55
+
56
+ request.onupgradeneeded = (event) => {
57
+ const database = (event.target as IDBOpenDBRequest).result;
58
+ if (!database.objectStoreNames.contains(STORE_NAME)) {
59
+ database.createObjectStore(STORE_NAME, { keyPath: 'key' });
60
+ }
61
+ };
62
+ });
63
+ };
64
+
65
+ export const saveMockData = async (key: string, data: unknown): Promise<void> => {
66
+ if (!db) await initDB();
67
+
68
+ const transaction = db!.transaction([STORE_NAME], 'readwrite');
69
+ const objectStore = transaction.objectStore(STORE_NAME);
70
+
71
+ objectStore.put({ key, data, timestamp: Date.now() });
72
+ };
73
+
74
+ export const getMockData = async (key: string): Promise<unknown | null> => {
75
+ if (!db) await initDB();
76
+
77
+ const transaction = db!.transaction([STORE_NAME], 'readonly');
78
+ const objectStore = transaction.objectStore(STORE_NAME);
79
+ const request = objectStore.get(key);
80
+
81
+ return new Promise((resolve) => {
82
+ request.onsuccess = () => {
83
+ const record = request.result;
84
+ resolve(record ? record.data : null);
85
+ };
86
+ request.onerror = () => resolve(null);
87
+ });
88
+ };
89
+
90
+ export const generateKey = (method: string, url: string, params?: Record<string, unknown>): string => {
91
+ const normalizedMethod = method.toUpperCase();
92
+ const normalizedUrl = url.split('?')[0]; // 쿼리 파라미터 제거
93
+
94
+ if (params && Object.keys(params).length > 0) {
95
+ // 객체를 안전하게 쿼리 문자열로 변환
96
+ const searchParams = new URLSearchParams();
97
+
98
+ Object.entries(params).forEach(([key, value]) => {
99
+ if (value !== undefined && value !== null) {
100
+ searchParams.append(key, String(value));
101
+ }
102
+ });
103
+
104
+ const paramString = searchParams.toString();
105
+ return `${normalizedMethod}:${normalizedUrl}:${paramString}`;
106
+ }
107
+
108
+ return `${normalizedMethod}:${normalizedUrl}`;
109
+ };
110
+
111
+ // 백업용: 모든 데이터 조회
112
+ export const getAllMockData = async (): Promise<Record<string, unknown>> => {
113
+ // ... IndexedDB에서 모든 데이터 가져오기
114
+ };
115
+
116
+ // 리스토어용: 여러 데이터 한 번에 저장
117
+ export const saveMultipleMockData = async (dataMap: Record<string, unknown>): Promise<void> => {
118
+ // ... IndexedDB에 여러 데이터 저장
119
+ };
120
+ ```
121
+
122
+ #### `src/mocks/apiWrapperMock.ts`
123
+
124
+ apiWrapper용 mock 데이터 관리:
125
+
126
+ ```typescript
127
+ import { getMockData, generateKey, saveMockData } from './storage/mockStorage';
128
+
129
+ export interface ApiWrapperMockOptions {
130
+ useMock?: boolean;
131
+ method: string;
132
+ route: string;
133
+ body?: any;
134
+ }
135
+
136
+ export const useMockDataIfNeeded = async <T>(
137
+ options: ApiWrapperMockOptions,
138
+ ): Promise<{ data: T | null; shouldCallApi: boolean }> => {
139
+ if (import.meta.env.VITE_MSW_ENABLED !== 'true') {
140
+ return { data: null, shouldCallApi: true };
141
+ }
142
+
143
+ const { method, route, body } = options;
144
+ const key = generateKey(method, route, body);
145
+
146
+ try {
147
+ const mockData = await getMockData(key);
148
+
149
+ if (mockData) {
150
+ console.log(`[apiWrapper Mock] ✅ Using cached data for: ${key}`);
151
+ return { data: mockData as T, shouldCallApi: false };
152
+ }
153
+
154
+ console.log(`[apiWrapper Mock] ⏳ No cached data for: ${key}`);
155
+ return { data: null, shouldCallApi: true };
156
+ } catch (error) {
157
+ console.error('[apiWrapper Mock] Failed to get mock data:', error);
158
+ return { data: null, shouldCallApi: true };
159
+ }
160
+ };
161
+
162
+ export const saveMockResponseIfNeeded = async (
163
+ options: ApiWrapperMockOptions,
164
+ data: unknown,
165
+ ) => {
166
+ if (import.meta.env.VITE_MSW_ENABLED !== 'true') {
167
+ return;
168
+ }
169
+
170
+ const { method, route, body } = options;
171
+ const key = generateKey(method, route, body);
172
+
173
+ try {
174
+ await saveMockData(key, data);
175
+ console.log(`[apiWrapper Mock] 💾 Saved mock data for: ${key}`);
176
+ } catch (error) {
177
+ console.error('[apiWrapper Mock] Failed to save mock data:', error);
178
+ }
179
+ };
180
+ ```
181
+
182
+ #### `src/mocks/handlers/index.ts`
183
+
184
+ MSW 핸들러 (빈 핸들러로 유지):
185
+
186
+ ```typescript
187
+ import { http } from 'msw';
188
+
189
+ export const handlers = [
190
+ // 실제 mock 처리는 apiWrapper에서 수행
191
+ ];
192
+ ```
193
+
194
+ #### `src/mocks/browser.ts`
195
+
196
+ MSW 브라우저 워커:
197
+
198
+ ```typescript
199
+ import { setupWorker } from 'msw/browser';
200
+ import { handlers } from './handlers';
201
+
202
+ type SetupWorker = ReturnType<typeof setupWorker>;
203
+
204
+ let worker: SetupWorker | null = null;
205
+
206
+ export const createMockWorker = (): SetupWorker => {
207
+ if (worker) {
208
+ return worker;
209
+ }
210
+
211
+ worker = setupWorker(...handlers);
212
+ return worker;
213
+ };
214
+ ```
215
+
216
+ #### `src/mocks/devtools.ts`
217
+
218
+ 개발자 도구 유틸리티:
219
+
220
+ ```typescript
221
+ import {
222
+ getAllMockKeys,
223
+ getMockData,
224
+ deleteMockData,
225
+ clearAllMockData,
226
+ getAllMockData,
227
+ saveMultipleMockData,
228
+ } from './storage/mockStorage';
229
+
230
+ export interface MSWDevTools {
231
+ list: () => Promise<string[]>;
232
+ get: (key: string) => Promise<unknown>;
233
+ delete: (key: string) => Promise<void>;
234
+ clear: () => Promise<void>;
235
+ backup: () => Promise<void>;
236
+ restore: () => Promise<void>;
237
+ help: () => void;
238
+ }
239
+
240
+ export const setupMSWDevTools = () => {
241
+ if (import.meta.env.DEV) {
242
+ const mswDevTools: MSWDevTools = {
243
+ list: async () => {
244
+ const keys = await getAllMockKeys();
245
+ console.log(`[MSW DevTools] Total ${keys.length} cached APIs:`);
246
+ console.table(keys.map((key) => ({ key })));
247
+ return keys;
248
+ },
249
+
250
+ get: async (key: string) => {
251
+ const data = await getMockData(key);
252
+ if (data) {
253
+ console.log(`[MSW DevTools] Data for: ${key}`, data);
254
+ } else {
255
+ console.warn(`[MSW DevTools] No data found for: ${key}`);
256
+ }
257
+ return data;
258
+ },
259
+
260
+ delete: async (key: string) => {
261
+ await deleteMockData(key);
262
+ console.log(`[MSW DevTools] Deleted: ${key}`);
263
+ },
264
+
265
+ clear: async () => {
266
+ await clearAllMockData();
267
+ console.log('[MSW DevTools] All mock data cleared!');
268
+ },
269
+
270
+ backup: async () => {
271
+ try {
272
+ const dataMap = await getAllMockData();
273
+ const keys = Object.keys(dataMap);
274
+
275
+ if (keys.length === 0) {
276
+ console.warn('[MSW DevTools] No data to backup!');
277
+ return;
278
+ }
279
+
280
+ // JSON 파일 생성 및 다운로드
281
+ const jsonString = JSON.stringify(dataMap, null, 2);
282
+ const blob = new Blob([jsonString], { type: 'application/json' });
283
+ const url = URL.createObjectURL(blob);
284
+
285
+ const link = document.createElement('a');
286
+ link.href = url;
287
+ const date = new Date().toISOString().split('T')[0];
288
+ link.download = `msw-mock-backup-${date}.json`;
289
+ document.body.appendChild(link);
290
+ link.click();
291
+ document.body.removeChild(link);
292
+ URL.revokeObjectURL(url);
293
+
294
+ console.log(`[MSW DevTools] ✅ Backup complete: ${keys.length} entries saved`);
295
+ } catch (error) {
296
+ console.error('[MSW DevTools] Failed to backup:', error);
297
+ }
298
+ },
299
+
300
+ restore: async () => {
301
+ try {
302
+ const input = document.createElement('input');
303
+ input.type = 'file';
304
+ input.accept = 'application/json';
305
+
306
+ input.onchange = async (event) => {
307
+ const file = (event.target as HTMLInputElement).files?.[0];
308
+ if (!file) return;
309
+
310
+ try {
311
+ const text = await file.text();
312
+ const dataMap = JSON.parse(text);
313
+
314
+ // 기존 데이터 삭제 후 복원
315
+ await clearAllMockData();
316
+ await saveMultipleMockData(dataMap);
317
+
318
+ console.log(`[MSW DevTools] ✅ Restore complete: ${Object.keys(dataMap).length} entries restored!`);
319
+ console.log('[MSW DevTools] 💡 Recommended: Refresh the page to apply changes.');
320
+ } catch (error) {
321
+ console.error('[MSW DevTools] Failed to restore:', error);
322
+ }
323
+ };
324
+
325
+ input.click();
326
+ } catch (error) {
327
+ console.error('[MSW DevTools] Failed to restore:', error);
328
+ }
329
+ },
330
+
331
+ help: () => {
332
+ console.log(`
333
+ [MSW DevTools] 사용법:
334
+
335
+ window.mswDevTools.list() # 저장된 모든 mock 데이터 키 목록
336
+ window.mswDevTools.get('GET:/ao/api/users') # 특정 mock 데이터 조회
337
+ window.mswDevTools.delete('GET:/ao/api/users') # 특정 mock 데이터 삭제
338
+ window.mswDevTools.clear() # 모든 mock 데이터 삭제
339
+ window.mswDevTools.backup() # JSON 파일로 백업 (다운로드)
340
+ window.mswDevTools.restore() # JSON 파일에서 리스토어 (파일 선택)
341
+
342
+ 예시:
343
+ // 백업 생성
344
+ await window.mswDevTools.backup()
345
+
346
+ // 리스토어
347
+ await window.mswDevTools.restore()
348
+
349
+ // 모든 저장된 API 목록 보기
350
+ await window.mswDevTools.list()
351
+ `);
352
+ },
353
+ };
354
+
355
+ (window as unknown as { mswDevTools: MSWDevTools }).mswDevTools = mswDevTools;
356
+ console.log('[MSW DevTools] initialized. Type window.mswDevTools.help() for usage.');
357
+ }
358
+ };
359
+ ```
360
+
361
+ ### 4. apiWrapper 수정
362
+
363
+ `src/services/apiWrapper.ts`의 `apiWrapper` 함수에 mock 데이터 확인 로직 추가:
364
+
365
+ ```typescript
366
+ export const apiWrapper: ApiWrapper = async <P>(
367
+ method: ApiMethod,
368
+ route: string,
369
+ body?: any,
370
+ config: ApiRequestConfig = {},
371
+ ) => {
372
+ // ... 기존 코드 ...
373
+
374
+ // MSW Mock 데이터 확인 (apiWrapper 레벨에서 직접 처리)
375
+ if (import.meta.env.DEV && import.meta.env.VITE_MSW_ENABLED === 'true') {
376
+ try {
377
+ const { useMockDataIfNeeded } = await import("../mocks/apiWrapperMock");
378
+ const { data: mockData, shouldCallApi } = await useMockDataIfNeeded<P>({
379
+ method,
380
+ route,
381
+ body,
382
+ });
383
+
384
+ if (!shouldCallApi && mockData) {
385
+ // mock 데이터가 있으면 반환
386
+ return { data: mockData, headers: {}, ...{} as any };
387
+ }
388
+ } catch (error) {
389
+ console.error('[apiWrapper] Failed to check mock data:', error);
390
+ }
391
+ }
392
+
393
+ try {
394
+ const { data, headers, ...rest } = await _axios(apiDataPlugin(axiosConfig));
395
+ // ... 기존 에러 처리 코드 ...
396
+
397
+ // 성공 응답 시 mock 데이터 저장
398
+ const { saveMockResponseIfNeeded } = await import("../mocks/apiWrapperMock");
399
+ const mockKey = generateKey(method, route, body);
400
+ saveMockResponseIfNeeded({ method, route, body }, data);
401
+ }
402
+ // ... catch 코드 ...
403
+ };
404
+ ```
405
+
406
+ ### 5. main.tsx 수정
407
+
408
+ ```typescript
409
+ // MSW (Mock Service Worker) - 개발 환경에서만 활성화
410
+ const initializeMSW = async () => {
411
+ if (import.meta.env.DEV && import.meta.env.VITE_MSW_ENABLED === 'true') {
412
+ const { createMockWorker } = await import('./mocks/browser');
413
+ const { setupMSWDevTools } = await import('./mocks/devtools');
414
+ const worker = createMockWorker();
415
+
416
+ try {
417
+ await worker?.start({
418
+ onUnhandledRequest: 'bypass',
419
+ });
420
+ console.log('[MSW] Mock Service Worker started successfully');
421
+
422
+ setupMSWDevTools();
423
+ } catch (error) {
424
+ console.error('[MSW] Failed to start Mock Service Worker:', error);
425
+ }
426
+ }
427
+ };
428
+
429
+ // MSW 초기화 후 앱 렌더링
430
+ initializeMSW().then(() => {
431
+ ReactDOM.createRoot(document.getElementById("root")!).render(
432
+ // ... 앱 렌더링 코드 ...
433
+ );
434
+ });
435
+ ```
436
+
437
+ ### 6. 환경 변수 설정
438
+
439
+ `.env.dev`, `.env.alpha`, `.env.beta` 등에 추가:
440
+
441
+ ```bash
442
+ # MSW (Mock Service Worker) 설정
443
+ VITE_MSW_ENABLED=true
444
+ ```
445
+
446
+ ### 7. package.json 업데이트
447
+
448
+ `npx msw init public/ --save` 명령어 실행 후 `package.json`에 자동 추가됨:
449
+
450
+ ```json
451
+ {
452
+ "msw": {
453
+ "workerDirectory": "public"
454
+ }
455
+ }
456
+ ```
457
+
458
+ ## 🛠️ 사용 방법
459
+
460
+ ### 1. MSW 활성화
461
+
462
+ `.env.alpha` 등 환경 파일에서 `VITE_MSW_ENABLED=true`로 설정:
463
+
464
+ ```bash
465
+ VITE_MSW_ENABLED=true
466
+ ```
467
+
468
+ ### 2. 개발 서버 시작
469
+
470
+ ```bash
471
+ npm run dev:alpha
472
+ ```
473
+
474
+ ### 3. DevTools 사용
475
+
476
+ 브라우저 개발자 도구 콜솔에서:
477
+
478
+ ```javascript
479
+ // 저장된 모든 API 목록
480
+ await window.mswDevTools.list()
481
+
482
+ // 특정 API 데이터 조회
483
+ await window.mswDevTools.get('POST:/ao/api/login/otp/sms:usrLoginId=system&usrPw=...')
484
+
485
+ // 특정 API 데이터 삭제
486
+ await window.mswDevTools.delete('POST:/ao/api/login/otp/sms:...')
487
+
488
+ // 모든 데이터 삭제
489
+ await window.mswDevTools.clear()
490
+
491
+ // 💾 백업 (JSON 파일 다운로드)
492
+ await window.mswDevTools.backup()
493
+
494
+ // 📂 리스토어 (JSON 파일 선택창 열림)
495
+ await window.mswDevTools.restore()
496
+
497
+ // 도움말
498
+ window.mswDevTools.help()
499
+ ```
500
+
501
+ ### 4. 백업 & 리스토어
502
+
503
+ #### 백업 (Backup)
504
+
505
+ IndexedDB에 저장된 모든 mock 데이터를 JSON 파일로 다운로드합니다:
506
+
507
+ ```javascript
508
+ await window.mswDevTools.backup()
509
+ ```
510
+
511
+ - 파일명: `msw-mock-backup-YYYY-MM-DD.json`
512
+ - 모든 API 응답 데이터가 포함됩니다
513
+ - 팀원들과 공유하거나 다른 PC에서 사용 가능
514
+
515
+ #### 리스토어 (Restore)
516
+
517
+ 백업된 JSON 파일을 불러와서 IndexedDB에 복원합니다:
518
+
519
+ ```javascript
520
+ await window.mswDevTools.restore()
521
+ ```
522
+
523
+ 1. 파일 선택창이 열립니다
524
+ 2. 백업 파일을 선택하면 자동으로 복원됩니다
525
+ 3. 복원 후 페이지 새로고침을 권장합니다
526
+
527
+ **주의사항:**
528
+ - 리스토어 시 **기존 데이터는 모두 삭제**됩니다
529
+ - 다른 프로젝트에서 백업한 파일도 사용 가능합니다 (경로가 동일한 경우)
530
+
531
+ ## 📁 파일 구조
532
+
533
+ ```
534
+ src/mocks/
535
+ ├── browser.ts # MSW 브라우저 워커 설정
536
+ ├── handlers/
537
+ │ └── index.ts # MSW 핸들러 (비어있음)
538
+ ├── storage/
539
+ │ └── mockStorage.ts # IndexedDB 저장소
540
+ ├── apiWrapperMock.ts # apiWrapper용 mock 유틸리티
541
+ └── devtools.ts # 개발자 도구
542
+
543
+ public/
544
+ └── mockServiceWorker.js # MSW 서비스 워커 (자동 생성)
545
+ ```
546
+
547
+ ## 🔑 API 데이터 키 형식
548
+
549
+ ```
550
+ METHOD:/API/path:param1=value1&param2=value2
551
+
552
+ 예시:
553
+ GET:/ao/api/users:pageNumber=1&pageSize=20
554
+ POST:/ao/api/users/save
555
+ POST:/ao/api/login/otp/sms:usrLoginId=system&usrPw=...&otpNum=123456
556
+ ```
557
+
558
+ ## 💡 주의사항
559
+
560
+ 1. **로그인 API**: 보안상 로그인 관련 API도 mock으로 저장됩니다. 실제 로그인 테스트 시 주의하세요.
561
+ 2. **데이터 무결성**: mock 데이터는 실제 API 응답을 저장하므로, 백엔드 데이터 변경 시 `window.mswDevTools.clear()`로 초기화하세요.
562
+ 3. **개발 전용**: 이 기능은 개발 환경에서만 사용하세요. 프로덕션 빌드에서는 자동으로 비활성화됩니다.
563
+ 4. **CORS 문제**: apiWrapper 레벨에서 mock을 처리하므로 CORS 문제가 발생하지 않습니다.
564
+
565
+ ## 🎯 적용 후 효과
566
+
567
+ ### Before (MSW 미적용)
568
+ - 외부 API 차단 시 개발 불가
569
+ - 매번 실제 API 호출 대기
570
+ - 네트워크 지연으로 개발 속도 저하
571
+
572
+ ### After (MSW 적용)
573
+ - 외부 API 차단 시에도 개발 가능
574
+ - 첫 호출 이후 즉시 mock 데이터 사용
575
+ - 일관된 테스트 데이터로 빠른 개발
576
+
577
+ ---
578
+
579
+ *이 가이드는 실제 프로젝트에 적용된 MSW Mock 데이터 기능을 정리한 것입니다.*