daiso 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 (69) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +741 -0
  3. package/dist/api/cgvHandlers.js +97 -0
  4. package/dist/api/handlers.js +208 -0
  5. package/dist/api/megaboxHandlers.js +145 -0
  6. package/dist/api/response.js +22 -0
  7. package/dist/api/routes/cgvRoutes.js +22 -0
  8. package/dist/api/routes/daisoRoutes.js +27 -0
  9. package/dist/api/routes/megaboxRoutes.js +22 -0
  10. package/dist/api/routes/oliveyoungRoutes.js +17 -0
  11. package/dist/cli.js +140 -0
  12. package/dist/core/interfaces.js +6 -0
  13. package/dist/core/registry.js +121 -0
  14. package/dist/core/types.js +6 -0
  15. package/dist/index.js +123 -0
  16. package/dist/pages/openapi.js +6 -0
  17. package/dist/pages/openapiResponse.js +32 -0
  18. package/dist/pages/openapiSpec.js +43 -0
  19. package/dist/pages/openapiSpecComponents.js +419 -0
  20. package/dist/pages/openapiSpecComponentsCgv.js +123 -0
  21. package/dist/pages/openapiSpecPathsCgv.js +149 -0
  22. package/dist/pages/openapiSpecPathsDaisoOliveyoung.js +381 -0
  23. package/dist/pages/openapiSpecPathsMegabox.js +184 -0
  24. package/dist/pages/openapiYaml.js +58 -0
  25. package/dist/pages/privacy.js +262 -0
  26. package/dist/pages/prompt.js +425 -0
  27. package/dist/services/cgv/api.js +15 -0
  28. package/dist/services/cgv/client.js +146 -0
  29. package/dist/services/cgv/index.js +30 -0
  30. package/dist/services/cgv/timetable.js +16 -0
  31. package/dist/services/cgv/tools/findTheaters.js +43 -0
  32. package/dist/services/cgv/tools/getTimetable.js +47 -0
  33. package/dist/services/cgv/tools/searchMovies.js +40 -0
  34. package/dist/services/cgv/transport.js +91 -0
  35. package/dist/services/cgv/types.js +4 -0
  36. package/dist/services/daiso/api.js +53 -0
  37. package/dist/services/daiso/client.js +35 -0
  38. package/dist/services/daiso/index.js +42 -0
  39. package/dist/services/daiso/tools/checkInventory.js +122 -0
  40. package/dist/services/daiso/tools/findStores.js +145 -0
  41. package/dist/services/daiso/tools/getPriceInfo.js +90 -0
  42. package/dist/services/daiso/tools/searchProducts.js +74 -0
  43. package/dist/services/daiso/types.js +4 -0
  44. package/dist/services/megabox/api.js +8 -0
  45. package/dist/services/megabox/client.js +140 -0
  46. package/dist/services/megabox/index.js +26 -0
  47. package/dist/services/megabox/tools/findNearbyTheaters.js +74 -0
  48. package/dist/services/megabox/tools/getRemainingSeats.js +57 -0
  49. package/dist/services/megabox/tools/listNowShowing.js +51 -0
  50. package/dist/services/megabox/types.js +4 -0
  51. package/dist/services/oliveyoung/api.js +8 -0
  52. package/dist/services/oliveyoung/client.js +90 -0
  53. package/dist/services/oliveyoung/index.js +28 -0
  54. package/dist/services/oliveyoung/tools/checkInventory.js +87 -0
  55. package/dist/services/oliveyoung/tools/findNearbyStores.js +53 -0
  56. package/dist/services/oliveyoung/types.js +4 -0
  57. package/dist/tools/checkInventory.js +98 -0
  58. package/dist/tools/findStores.js +125 -0
  59. package/dist/tools/getPriceInfo.js +77 -0
  60. package/dist/tools/searchProducts.js +61 -0
  61. package/dist/types/index.js +4 -0
  62. package/dist/utils/cache.js +54 -0
  63. package/dist/utils/fetch.js +14 -0
  64. package/dist/utils/format.js +31 -0
  65. package/dist/utils/http.js +35 -0
  66. package/dist/utils/zyte.js +76 -0
  67. package/openapi.json +1938 -0
  68. package/openapi.yaml +1338 -0
  69. package/package.json +79 -0
package/openapi.json ADDED
@@ -0,0 +1,1938 @@
1
+ {
2
+ "openapi": "3.1.0",
3
+ "info": {
4
+ "title": "다이소 MCP API",
5
+ "description": "다이소 제품 검색, 매장 찾기, 재고 확인을 위한 API입니다.\n\n## 주요 기능\n- 🔍 **제품 검색**: 키워드로 다이소 제품 검색\n- 🏪 **매장 찾기**: 지역/키워드로 매장 검색\n- 📦 **재고 확인**: 온라인 및 오프라인 매장 재고 조회\n- 🎬 **메가박스 지점/영화 조회**: 주변 지점, 상영 목록, 잔여 좌석 조회\n- 🎥 **CGV 지점/영화 조회**: 극장 목록, 영화 목록, 시간표 조회\n\n## 사용 팁\n1. 한글 검색어는 URL 인코딩이 자동 처리됩니다\n2. 재고 확인 시 먼저 제품 검색으로 제품 ID를 확인하세요\n3. 위치 기반 재고 조회 시 lat, lng 파라미터를 활용하세요",
6
+ "version": "1.0.0",
7
+ "contact": {
8
+ "name": "GitHub Repository",
9
+ "url": "https://github.com/hmmhmmhm/daiso-mcp"
10
+ }
11
+ },
12
+ "servers": [
13
+ {
14
+ "url": "https://mcp.aka.page",
15
+ "description": "Production Server"
16
+ }
17
+ ],
18
+ "paths": {
19
+ "/api/daiso/products": {
20
+ "get": {
21
+ "operationId": "searchProducts",
22
+ "summary": "제품 검색",
23
+ "description": "키워드로 다이소 제품을 검색합니다. 수납박스, 펜, 정리함 등 다양한 키워드로 검색할 수 있습니다.",
24
+ "parameters": [
25
+ {
26
+ "name": "q",
27
+ "in": "query",
28
+ "required": true,
29
+ "description": "검색 키워드 (예: 수납박스, 펜, 정리함)",
30
+ "schema": {
31
+ "type": "string"
32
+ },
33
+ "example": "수납박스"
34
+ },
35
+ {
36
+ "name": "page",
37
+ "in": "query",
38
+ "required": false,
39
+ "description": "페이지 번호",
40
+ "schema": {
41
+ "type": "integer",
42
+ "default": 1,
43
+ "minimum": 1
44
+ }
45
+ },
46
+ {
47
+ "name": "pageSize",
48
+ "in": "query",
49
+ "required": false,
50
+ "description": "페이지당 결과 수",
51
+ "schema": {
52
+ "type": "integer",
53
+ "default": 30,
54
+ "minimum": 1,
55
+ "maximum": 100
56
+ }
57
+ }
58
+ ],
59
+ "responses": {
60
+ "200": {
61
+ "description": "검색 성공",
62
+ "content": {
63
+ "application/json": {
64
+ "schema": {
65
+ "$ref": "#/components/schemas/ProductSearchResponse"
66
+ }
67
+ }
68
+ }
69
+ },
70
+ "400": {
71
+ "description": "잘못된 요청 (검색어 누락)",
72
+ "content": {
73
+ "application/json": {
74
+ "schema": {
75
+ "$ref": "#/components/schemas/ErrorResponse"
76
+ }
77
+ }
78
+ }
79
+ }
80
+ }
81
+ }
82
+ },
83
+ "/api/daiso/products/{productId}": {
84
+ "get": {
85
+ "operationId": "getProduct",
86
+ "summary": "제품 상세 정보",
87
+ "description": "제품 ID로 상세 정보를 조회합니다.",
88
+ "parameters": [
89
+ {
90
+ "name": "productId",
91
+ "in": "path",
92
+ "required": true,
93
+ "description": "제품 ID (제품 검색 결과의 id 값)",
94
+ "schema": {
95
+ "type": "string"
96
+ },
97
+ "example": "1234567890"
98
+ }
99
+ ],
100
+ "responses": {
101
+ "200": {
102
+ "description": "조회 성공",
103
+ "content": {
104
+ "application/json": {
105
+ "schema": {
106
+ "$ref": "#/components/schemas/ProductDetailResponse"
107
+ }
108
+ }
109
+ }
110
+ },
111
+ "404": {
112
+ "description": "제품을 찾을 수 없음",
113
+ "content": {
114
+ "application/json": {
115
+ "schema": {
116
+ "$ref": "#/components/schemas/ErrorResponse"
117
+ }
118
+ }
119
+ }
120
+ }
121
+ }
122
+ }
123
+ },
124
+ "/api/daiso/stores": {
125
+ "get": {
126
+ "operationId": "findStores",
127
+ "summary": "매장 찾기",
128
+ "description": "키워드 또는 지역으로 다이소 매장을 검색합니다. keyword 또는 sido 중 하나는 필수입니다.",
129
+ "parameters": [
130
+ {
131
+ "name": "keyword",
132
+ "in": "query",
133
+ "required": false,
134
+ "description": "매장명 또는 주소 키워드 (예: 강남, 홍대, 안산)",
135
+ "schema": {
136
+ "type": "string"
137
+ },
138
+ "example": "강남"
139
+ },
140
+ {
141
+ "name": "sido",
142
+ "in": "query",
143
+ "required": false,
144
+ "description": "시/도 (예: 서울, 경기, 부산)",
145
+ "schema": {
146
+ "type": "string"
147
+ },
148
+ "example": "서울"
149
+ },
150
+ {
151
+ "name": "gugun",
152
+ "in": "query",
153
+ "required": false,
154
+ "description": "구/군 (예: 강남구, 마포구)",
155
+ "schema": {
156
+ "type": "string"
157
+ },
158
+ "example": "강남구"
159
+ },
160
+ {
161
+ "name": "dong",
162
+ "in": "query",
163
+ "required": false,
164
+ "description": "동 (예: 역삼동, 합정동)",
165
+ "schema": {
166
+ "type": "string"
167
+ }
168
+ },
169
+ {
170
+ "name": "limit",
171
+ "in": "query",
172
+ "required": false,
173
+ "description": "최대 결과 수",
174
+ "schema": {
175
+ "type": "integer",
176
+ "default": 50,
177
+ "minimum": 1,
178
+ "maximum": 100
179
+ }
180
+ }
181
+ ],
182
+ "responses": {
183
+ "200": {
184
+ "description": "검색 성공",
185
+ "content": {
186
+ "application/json": {
187
+ "schema": {
188
+ "$ref": "#/components/schemas/StoreSearchResponse"
189
+ }
190
+ }
191
+ }
192
+ },
193
+ "400": {
194
+ "description": "잘못된 요청 (필수 파라미터 누락)",
195
+ "content": {
196
+ "application/json": {
197
+ "schema": {
198
+ "$ref": "#/components/schemas/ErrorResponse"
199
+ }
200
+ }
201
+ }
202
+ }
203
+ }
204
+ }
205
+ },
206
+ "/api/daiso/inventory": {
207
+ "get": {
208
+ "operationId": "checkInventory",
209
+ "summary": "재고 확인",
210
+ "description": "특정 제품의 온라인 재고와 매장별 재고를 확인합니다. 위치 정보를 제공하면 가까운 매장 순으로 정렬됩니다.",
211
+ "parameters": [
212
+ {
213
+ "name": "productId",
214
+ "in": "query",
215
+ "required": true,
216
+ "description": "제품 ID (제품 검색 결과의 id 값)",
217
+ "schema": {
218
+ "type": "string"
219
+ },
220
+ "example": "1234567890"
221
+ },
222
+ {
223
+ "name": "lat",
224
+ "in": "query",
225
+ "required": false,
226
+ "description": "위도 (기본값: 서울 시청 37.5665)",
227
+ "schema": {
228
+ "type": "number",
229
+ "format": "float",
230
+ "default": 37.5665
231
+ },
232
+ "example": 37.4979
233
+ },
234
+ {
235
+ "name": "lng",
236
+ "in": "query",
237
+ "required": false,
238
+ "description": "경도 (기본값: 서울 시청 126.978)",
239
+ "schema": {
240
+ "type": "number",
241
+ "format": "float",
242
+ "default": 126.978
243
+ },
244
+ "example": 127.0276
245
+ },
246
+ {
247
+ "name": "keyword",
248
+ "in": "query",
249
+ "required": false,
250
+ "description": "매장 검색어 (예: 안산, 강남)",
251
+ "schema": {
252
+ "type": "string"
253
+ }
254
+ },
255
+ {
256
+ "name": "page",
257
+ "in": "query",
258
+ "required": false,
259
+ "description": "페이지 번호",
260
+ "schema": {
261
+ "type": "integer",
262
+ "default": 1,
263
+ "minimum": 1
264
+ }
265
+ },
266
+ {
267
+ "name": "pageSize",
268
+ "in": "query",
269
+ "required": false,
270
+ "description": "페이지당 결과 수",
271
+ "schema": {
272
+ "type": "integer",
273
+ "default": 30,
274
+ "minimum": 1,
275
+ "maximum": 100
276
+ }
277
+ }
278
+ ],
279
+ "responses": {
280
+ "200": {
281
+ "description": "조회 성공",
282
+ "content": {
283
+ "application/json": {
284
+ "schema": {
285
+ "$ref": "#/components/schemas/InventoryResponse"
286
+ }
287
+ }
288
+ }
289
+ },
290
+ "400": {
291
+ "description": "잘못된 요청 (제품 ID 누락)",
292
+ "content": {
293
+ "application/json": {
294
+ "schema": {
295
+ "$ref": "#/components/schemas/ErrorResponse"
296
+ }
297
+ }
298
+ }
299
+ }
300
+ }
301
+ }
302
+ },
303
+ "/api/oliveyoung/stores": {
304
+ "get": {
305
+ "operationId": "oliveyoungFindStores",
306
+ "summary": "올리브영 매장 검색",
307
+ "description": "위치(위도/경도)와 키워드로 올리브영 매장을 검색합니다.",
308
+ "parameters": [
309
+ {
310
+ "name": "keyword",
311
+ "in": "query",
312
+ "required": false,
313
+ "description": "매장명 또는 지역 키워드 (예: 명동, 강남)",
314
+ "schema": {
315
+ "type": "string"
316
+ },
317
+ "example": "명동"
318
+ },
319
+ {
320
+ "name": "lat",
321
+ "in": "query",
322
+ "required": false,
323
+ "description": "위도 (기본값: 서울 시청 37.5665)",
324
+ "schema": {
325
+ "type": "number",
326
+ "format": "float",
327
+ "default": 37.5665
328
+ }
329
+ },
330
+ {
331
+ "name": "lng",
332
+ "in": "query",
333
+ "required": false,
334
+ "description": "경도 (기본값: 서울 시청 126.978)",
335
+ "schema": {
336
+ "type": "number",
337
+ "format": "float",
338
+ "default": 126.978
339
+ }
340
+ },
341
+ {
342
+ "name": "pageIdx",
343
+ "in": "query",
344
+ "required": false,
345
+ "description": "매장 검색 페이지 번호",
346
+ "schema": {
347
+ "type": "integer",
348
+ "default": 1,
349
+ "minimum": 1
350
+ }
351
+ },
352
+ {
353
+ "name": "limit",
354
+ "in": "query",
355
+ "required": false,
356
+ "description": "최대 결과 수",
357
+ "schema": {
358
+ "type": "integer",
359
+ "default": 20,
360
+ "minimum": 1,
361
+ "maximum": 100
362
+ }
363
+ }
364
+ ],
365
+ "responses": {
366
+ "200": {
367
+ "description": "검색 성공",
368
+ "content": {
369
+ "application/json": {
370
+ "schema": {
371
+ "$ref": "#/components/schemas/OliveyoungStoreSearchResponse"
372
+ }
373
+ }
374
+ }
375
+ },
376
+ "500": {
377
+ "description": "올리브영 API 호출 실패",
378
+ "content": {
379
+ "application/json": {
380
+ "schema": {
381
+ "$ref": "#/components/schemas/ErrorResponse"
382
+ }
383
+ }
384
+ }
385
+ }
386
+ }
387
+ }
388
+ },
389
+ "/api/oliveyoung/inventory": {
390
+ "get": {
391
+ "operationId": "oliveyoungCheckInventory",
392
+ "summary": "올리브영 재고 확인",
393
+ "description": "상품 키워드로 올리브영 재고를 검색하고 주변 매장 정보를 함께 조회합니다.",
394
+ "parameters": [
395
+ {
396
+ "name": "keyword",
397
+ "in": "query",
398
+ "required": true,
399
+ "description": "재고를 확인할 상품 키워드",
400
+ "schema": {
401
+ "type": "string"
402
+ },
403
+ "example": "선크림"
404
+ },
405
+ {
406
+ "name": "lat",
407
+ "in": "query",
408
+ "required": false,
409
+ "description": "위도 (기본값: 서울 시청 37.5665)",
410
+ "schema": {
411
+ "type": "number",
412
+ "format": "float",
413
+ "default": 37.5665
414
+ }
415
+ },
416
+ {
417
+ "name": "lng",
418
+ "in": "query",
419
+ "required": false,
420
+ "description": "경도 (기본값: 서울 시청 126.978)",
421
+ "schema": {
422
+ "type": "number",
423
+ "format": "float",
424
+ "default": 126.978
425
+ }
426
+ },
427
+ {
428
+ "name": "storeKeyword",
429
+ "in": "query",
430
+ "required": false,
431
+ "description": "주변 매장 필터 키워드",
432
+ "schema": {
433
+ "type": "string"
434
+ }
435
+ },
436
+ {
437
+ "name": "page",
438
+ "in": "query",
439
+ "required": false,
440
+ "description": "상품 검색 페이지 번호",
441
+ "schema": {
442
+ "type": "integer",
443
+ "default": 1,
444
+ "minimum": 1
445
+ }
446
+ },
447
+ {
448
+ "name": "size",
449
+ "in": "query",
450
+ "required": false,
451
+ "description": "페이지당 결과 수",
452
+ "schema": {
453
+ "type": "integer",
454
+ "default": 20,
455
+ "minimum": 1,
456
+ "maximum": 100
457
+ }
458
+ },
459
+ {
460
+ "name": "sort",
461
+ "in": "query",
462
+ "required": false,
463
+ "description": "정렬 코드",
464
+ "schema": {
465
+ "type": "string",
466
+ "default": "01"
467
+ }
468
+ },
469
+ {
470
+ "name": "includeSoldOut",
471
+ "in": "query",
472
+ "required": false,
473
+ "description": "품절 포함 여부 (true/false)",
474
+ "schema": {
475
+ "type": "boolean",
476
+ "default": false
477
+ }
478
+ }
479
+ ],
480
+ "responses": {
481
+ "200": {
482
+ "description": "조회 성공",
483
+ "content": {
484
+ "application/json": {
485
+ "schema": {
486
+ "$ref": "#/components/schemas/OliveyoungInventoryResponse"
487
+ }
488
+ }
489
+ }
490
+ },
491
+ "400": {
492
+ "description": "잘못된 요청 (검색어 누락)",
493
+ "content": {
494
+ "application/json": {
495
+ "schema": {
496
+ "$ref": "#/components/schemas/ErrorResponse"
497
+ }
498
+ }
499
+ }
500
+ },
501
+ "500": {
502
+ "description": "올리브영 API 호출 실패",
503
+ "content": {
504
+ "application/json": {
505
+ "schema": {
506
+ "$ref": "#/components/schemas/ErrorResponse"
507
+ }
508
+ }
509
+ }
510
+ }
511
+ }
512
+ }
513
+ },
514
+ "/api/megabox/theaters": {
515
+ "get": {
516
+ "operationId": "megaboxFindNearbyTheaters",
517
+ "summary": "메가박스 주변 지점 조회",
518
+ "description": "좌표 기준으로 메가박스 지점을 거리순으로 조회합니다.",
519
+ "parameters": [
520
+ {
521
+ "name": "lat",
522
+ "in": "query",
523
+ "required": false,
524
+ "description": "위도 (기본값: 서울 시청 37.5665)",
525
+ "schema": {
526
+ "type": "number",
527
+ "format": "float",
528
+ "default": 37.5665
529
+ }
530
+ },
531
+ {
532
+ "name": "lng",
533
+ "in": "query",
534
+ "required": false,
535
+ "description": "경도 (기본값: 서울 시청 126.978)",
536
+ "schema": {
537
+ "type": "number",
538
+ "format": "float",
539
+ "default": 126.978
540
+ }
541
+ },
542
+ {
543
+ "name": "playDate",
544
+ "in": "query",
545
+ "required": false,
546
+ "description": "조회 날짜 (YYYYMMDD)",
547
+ "schema": {
548
+ "type": "string",
549
+ "example": "20260304"
550
+ }
551
+ },
552
+ {
553
+ "name": "areaCode",
554
+ "in": "query",
555
+ "required": false,
556
+ "description": "지역 코드 (기본값: 11, 서울)",
557
+ "schema": {
558
+ "type": "string",
559
+ "default": "11"
560
+ }
561
+ },
562
+ {
563
+ "name": "limit",
564
+ "in": "query",
565
+ "required": false,
566
+ "description": "최대 결과 수",
567
+ "schema": {
568
+ "type": "integer",
569
+ "default": 10,
570
+ "minimum": 1,
571
+ "maximum": 100
572
+ }
573
+ }
574
+ ],
575
+ "responses": {
576
+ "200": {
577
+ "description": "조회 성공",
578
+ "content": {
579
+ "application/json": {
580
+ "schema": {
581
+ "$ref": "#/components/schemas/MegaboxTheaterSearchResponse"
582
+ }
583
+ }
584
+ }
585
+ },
586
+ "500": {
587
+ "description": "메가박스 API 호출 실패",
588
+ "content": {
589
+ "application/json": {
590
+ "schema": {
591
+ "$ref": "#/components/schemas/ErrorResponse"
592
+ }
593
+ }
594
+ }
595
+ }
596
+ }
597
+ }
598
+ },
599
+ "/api/megabox/movies": {
600
+ "get": {
601
+ "operationId": "megaboxListNowShowing",
602
+ "summary": "메가박스 영화/회차 목록 조회",
603
+ "description": "날짜, 지점, 영화 조건으로 메가박스 영화 및 상영 회차를 조회합니다.",
604
+ "parameters": [
605
+ {
606
+ "name": "playDate",
607
+ "in": "query",
608
+ "required": false,
609
+ "description": "조회 날짜 (YYYYMMDD)",
610
+ "schema": {
611
+ "type": "string",
612
+ "example": "20260304"
613
+ }
614
+ },
615
+ {
616
+ "name": "theaterId",
617
+ "in": "query",
618
+ "required": false,
619
+ "description": "지점 ID (예: 1372)",
620
+ "schema": {
621
+ "type": "string",
622
+ "example": "1372"
623
+ }
624
+ },
625
+ {
626
+ "name": "movieId",
627
+ "in": "query",
628
+ "required": false,
629
+ "description": "영화 ID (예: 25104500)",
630
+ "schema": {
631
+ "type": "string",
632
+ "example": "25104500"
633
+ }
634
+ },
635
+ {
636
+ "name": "areaCode",
637
+ "in": "query",
638
+ "required": false,
639
+ "description": "지역 코드 (기본값: 11, 서울)",
640
+ "schema": {
641
+ "type": "string",
642
+ "default": "11"
643
+ }
644
+ }
645
+ ],
646
+ "responses": {
647
+ "200": {
648
+ "description": "조회 성공",
649
+ "content": {
650
+ "application/json": {
651
+ "schema": {
652
+ "$ref": "#/components/schemas/MegaboxMovieListResponse"
653
+ }
654
+ }
655
+ }
656
+ },
657
+ "500": {
658
+ "description": "메가박스 API 호출 실패",
659
+ "content": {
660
+ "application/json": {
661
+ "schema": {
662
+ "$ref": "#/components/schemas/ErrorResponse"
663
+ }
664
+ }
665
+ }
666
+ }
667
+ }
668
+ }
669
+ },
670
+ "/api/megabox/seats": {
671
+ "get": {
672
+ "operationId": "megaboxGetRemainingSeats",
673
+ "summary": "메가박스 잔여 좌석 조회",
674
+ "description": "영화/지점/날짜 조건으로 회차별 잔여 좌석 수를 조회합니다.",
675
+ "parameters": [
676
+ {
677
+ "name": "playDate",
678
+ "in": "query",
679
+ "required": false,
680
+ "description": "조회 날짜 (YYYYMMDD)",
681
+ "schema": {
682
+ "type": "string",
683
+ "example": "20260304"
684
+ }
685
+ },
686
+ {
687
+ "name": "theaterId",
688
+ "in": "query",
689
+ "required": false,
690
+ "description": "지점 ID",
691
+ "schema": {
692
+ "type": "string"
693
+ }
694
+ },
695
+ {
696
+ "name": "movieId",
697
+ "in": "query",
698
+ "required": false,
699
+ "description": "영화 ID",
700
+ "schema": {
701
+ "type": "string"
702
+ }
703
+ },
704
+ {
705
+ "name": "areaCode",
706
+ "in": "query",
707
+ "required": false,
708
+ "description": "지역 코드 (기본값: 11, 서울)",
709
+ "schema": {
710
+ "type": "string",
711
+ "default": "11"
712
+ }
713
+ },
714
+ {
715
+ "name": "limit",
716
+ "in": "query",
717
+ "required": false,
718
+ "description": "최대 결과 수",
719
+ "schema": {
720
+ "type": "integer",
721
+ "default": 50,
722
+ "minimum": 1,
723
+ "maximum": 200
724
+ }
725
+ }
726
+ ],
727
+ "responses": {
728
+ "200": {
729
+ "description": "조회 성공",
730
+ "content": {
731
+ "application/json": {
732
+ "schema": {
733
+ "$ref": "#/components/schemas/MegaboxSeatListResponse"
734
+ }
735
+ }
736
+ }
737
+ },
738
+ "500": {
739
+ "description": "메가박스 API 호출 실패",
740
+ "content": {
741
+ "application/json": {
742
+ "schema": {
743
+ "$ref": "#/components/schemas/ErrorResponse"
744
+ }
745
+ }
746
+ }
747
+ }
748
+ }
749
+ }
750
+ },
751
+ "/api/cgv/theaters": {
752
+ "get": {
753
+ "operationId": "cgvFindTheaters",
754
+ "summary": "CGV 극장 목록 조회",
755
+ "description": "날짜/지역 코드 조건으로 CGV 극장 목록을 조회합니다.",
756
+ "parameters": [
757
+ {
758
+ "name": "playDate",
759
+ "in": "query",
760
+ "required": false,
761
+ "description": "조회 날짜 (YYYYMMDD)",
762
+ "schema": {
763
+ "type": "string",
764
+ "example": "20260304"
765
+ }
766
+ },
767
+ {
768
+ "name": "regionCode",
769
+ "in": "query",
770
+ "required": false,
771
+ "description": "지역 코드 (예: 01 서울)",
772
+ "schema": {
773
+ "type": "string",
774
+ "example": "01"
775
+ }
776
+ },
777
+ {
778
+ "name": "limit",
779
+ "in": "query",
780
+ "required": false,
781
+ "description": "최대 결과 수",
782
+ "schema": {
783
+ "type": "integer",
784
+ "default": 30,
785
+ "minimum": 1,
786
+ "maximum": 100
787
+ }
788
+ }
789
+ ],
790
+ "responses": {
791
+ "200": {
792
+ "description": "조회 성공",
793
+ "content": {
794
+ "application/json": {
795
+ "schema": {
796
+ "$ref": "#/components/schemas/CgvTheaterSearchResponse"
797
+ }
798
+ }
799
+ }
800
+ },
801
+ "500": {
802
+ "description": "CGV API 호출 실패",
803
+ "content": {
804
+ "application/json": {
805
+ "schema": {
806
+ "$ref": "#/components/schemas/ErrorResponse"
807
+ }
808
+ }
809
+ }
810
+ }
811
+ }
812
+ }
813
+ },
814
+ "/api/cgv/movies": {
815
+ "get": {
816
+ "operationId": "cgvSearchMovies",
817
+ "summary": "CGV 영화 목록 조회",
818
+ "description": "날짜/극장 조건으로 CGV 영화 목록을 조회합니다.",
819
+ "parameters": [
820
+ {
821
+ "name": "playDate",
822
+ "in": "query",
823
+ "required": false,
824
+ "description": "조회 날짜 (YYYYMMDD)",
825
+ "schema": {
826
+ "type": "string",
827
+ "example": "20260304"
828
+ }
829
+ },
830
+ {
831
+ "name": "theaterCode",
832
+ "in": "query",
833
+ "required": false,
834
+ "description": "극장 코드 (예: 0056)",
835
+ "schema": {
836
+ "type": "string",
837
+ "example": "0056"
838
+ }
839
+ }
840
+ ],
841
+ "responses": {
842
+ "200": {
843
+ "description": "조회 성공",
844
+ "content": {
845
+ "application/json": {
846
+ "schema": {
847
+ "$ref": "#/components/schemas/CgvMovieSearchResponse"
848
+ }
849
+ }
850
+ }
851
+ },
852
+ "500": {
853
+ "description": "CGV API 호출 실패",
854
+ "content": {
855
+ "application/json": {
856
+ "schema": {
857
+ "$ref": "#/components/schemas/ErrorResponse"
858
+ }
859
+ }
860
+ }
861
+ }
862
+ }
863
+ }
864
+ },
865
+ "/api/cgv/timetable": {
866
+ "get": {
867
+ "operationId": "cgvGetTimetable",
868
+ "summary": "CGV 시간표 조회",
869
+ "description": "날짜/극장/영화 조건으로 CGV 상영 시간표를 조회합니다.",
870
+ "parameters": [
871
+ {
872
+ "name": "playDate",
873
+ "in": "query",
874
+ "required": false,
875
+ "description": "조회 날짜 (YYYYMMDD)",
876
+ "schema": {
877
+ "type": "string",
878
+ "example": "20260304"
879
+ }
880
+ },
881
+ {
882
+ "name": "theaterCode",
883
+ "in": "query",
884
+ "required": false,
885
+ "description": "극장 코드",
886
+ "schema": {
887
+ "type": "string"
888
+ }
889
+ },
890
+ {
891
+ "name": "movieCode",
892
+ "in": "query",
893
+ "required": false,
894
+ "description": "영화 코드",
895
+ "schema": {
896
+ "type": "string"
897
+ }
898
+ },
899
+ {
900
+ "name": "limit",
901
+ "in": "query",
902
+ "required": false,
903
+ "description": "최대 결과 수",
904
+ "schema": {
905
+ "type": "integer",
906
+ "default": 50,
907
+ "minimum": 1,
908
+ "maximum": 200
909
+ }
910
+ }
911
+ ],
912
+ "responses": {
913
+ "200": {
914
+ "description": "조회 성공",
915
+ "content": {
916
+ "application/json": {
917
+ "schema": {
918
+ "$ref": "#/components/schemas/CgvTimetableResponse"
919
+ }
920
+ }
921
+ }
922
+ },
923
+ "500": {
924
+ "description": "CGV API 호출 실패",
925
+ "content": {
926
+ "application/json": {
927
+ "schema": {
928
+ "$ref": "#/components/schemas/ErrorResponse"
929
+ }
930
+ }
931
+ }
932
+ }
933
+ }
934
+ }
935
+ }
936
+ },
937
+ "components": {
938
+ "schemas": {
939
+ "Product": {
940
+ "type": "object",
941
+ "description": "제품 정보",
942
+ "properties": {
943
+ "id": {
944
+ "type": "string",
945
+ "description": "제품 ID",
946
+ "example": "1234567890"
947
+ },
948
+ "name": {
949
+ "type": "string",
950
+ "description": "제품명",
951
+ "example": "PP 수납박스 대형"
952
+ },
953
+ "price": {
954
+ "type": "integer",
955
+ "description": "가격 (원)",
956
+ "example": 5000
957
+ },
958
+ "imageUrl": {
959
+ "type": "string",
960
+ "description": "제품 이미지 URL",
961
+ "example": "https://img.daisomall.co.kr/..."
962
+ },
963
+ "soldOut": {
964
+ "type": "boolean",
965
+ "description": "품절 여부",
966
+ "example": false
967
+ },
968
+ "isNew": {
969
+ "type": "boolean",
970
+ "description": "신상품 여부",
971
+ "example": false
972
+ },
973
+ "pickupAvailable": {
974
+ "type": "boolean",
975
+ "description": "매장 픽업 가능 여부",
976
+ "example": true
977
+ }
978
+ }
979
+ },
980
+ "ProductDetail": {
981
+ "type": "object",
982
+ "description": "제품 상세 정보",
983
+ "properties": {
984
+ "id": {
985
+ "type": "string",
986
+ "description": "제품 ID"
987
+ },
988
+ "name": {
989
+ "type": "string",
990
+ "description": "제품명"
991
+ },
992
+ "price": {
993
+ "type": "integer",
994
+ "description": "가격 (원)"
995
+ },
996
+ "currency": {
997
+ "type": "string",
998
+ "description": "통화",
999
+ "example": "KRW"
1000
+ },
1001
+ "imageUrl": {
1002
+ "type": "string",
1003
+ "description": "제품 이미지 URL"
1004
+ },
1005
+ "brand": {
1006
+ "type": "string",
1007
+ "description": "브랜드명"
1008
+ },
1009
+ "soldOut": {
1010
+ "type": "boolean",
1011
+ "description": "품절 여부"
1012
+ },
1013
+ "isNew": {
1014
+ "type": "boolean",
1015
+ "description": "신상품 여부"
1016
+ }
1017
+ }
1018
+ },
1019
+ "Store": {
1020
+ "type": "object",
1021
+ "description": "매장 정보",
1022
+ "properties": {
1023
+ "name": {
1024
+ "type": "string",
1025
+ "description": "매장명",
1026
+ "example": "다이소 강남역점"
1027
+ },
1028
+ "phone": {
1029
+ "type": "string",
1030
+ "description": "전화번호",
1031
+ "example": "02-1234-5678"
1032
+ },
1033
+ "address": {
1034
+ "type": "string",
1035
+ "description": "주소",
1036
+ "example": "서울특별시 강남구 강남대로 123"
1037
+ },
1038
+ "lat": {
1039
+ "type": "number",
1040
+ "format": "float",
1041
+ "description": "위도",
1042
+ "example": 37.4979
1043
+ },
1044
+ "lng": {
1045
+ "type": "number",
1046
+ "format": "float",
1047
+ "description": "경도",
1048
+ "example": 127.0276
1049
+ },
1050
+ "openTime": {
1051
+ "type": "string",
1052
+ "description": "영업 시작 시간",
1053
+ "example": "10:00"
1054
+ },
1055
+ "closeTime": {
1056
+ "type": "string",
1057
+ "description": "영업 종료 시간",
1058
+ "example": "22:00"
1059
+ },
1060
+ "options": {
1061
+ "type": "object",
1062
+ "description": "매장 옵션",
1063
+ "properties": {
1064
+ "parking": {
1065
+ "type": "boolean",
1066
+ "description": "주차 가능 여부"
1067
+ },
1068
+ "pickup": {
1069
+ "type": "boolean",
1070
+ "description": "픽업 가능 여부"
1071
+ },
1072
+ "taxFree": {
1073
+ "type": "boolean",
1074
+ "description": "면세 가능 여부"
1075
+ }
1076
+ }
1077
+ }
1078
+ }
1079
+ },
1080
+ "StoreInventory": {
1081
+ "type": "object",
1082
+ "description": "매장 재고 정보",
1083
+ "properties": {
1084
+ "storeCode": {
1085
+ "type": "string",
1086
+ "description": "매장 코드",
1087
+ "example": "ST001"
1088
+ },
1089
+ "storeName": {
1090
+ "type": "string",
1091
+ "description": "매장명",
1092
+ "example": "다이소 강남역점"
1093
+ },
1094
+ "address": {
1095
+ "type": "string",
1096
+ "description": "주소"
1097
+ },
1098
+ "distance": {
1099
+ "type": "string",
1100
+ "description": "거리",
1101
+ "example": "0.5km"
1102
+ },
1103
+ "quantity": {
1104
+ "type": "integer",
1105
+ "description": "재고 수량",
1106
+ "example": 12
1107
+ },
1108
+ "options": {
1109
+ "type": "object",
1110
+ "properties": {
1111
+ "parking": {
1112
+ "type": "boolean"
1113
+ },
1114
+ "pickup": {
1115
+ "type": "boolean"
1116
+ }
1117
+ }
1118
+ }
1119
+ }
1120
+ },
1121
+ "ProductSearchResponse": {
1122
+ "type": "object",
1123
+ "properties": {
1124
+ "success": {
1125
+ "type": "boolean",
1126
+ "example": true
1127
+ },
1128
+ "data": {
1129
+ "type": "object",
1130
+ "properties": {
1131
+ "products": {
1132
+ "type": "array",
1133
+ "items": {
1134
+ "$ref": "#/components/schemas/Product"
1135
+ }
1136
+ }
1137
+ }
1138
+ },
1139
+ "meta": {
1140
+ "type": "object",
1141
+ "properties": {
1142
+ "total": {
1143
+ "type": "integer",
1144
+ "description": "전체 결과 수"
1145
+ },
1146
+ "page": {
1147
+ "type": "integer",
1148
+ "description": "현재 페이지"
1149
+ },
1150
+ "pageSize": {
1151
+ "type": "integer",
1152
+ "description": "페이지당 결과 수"
1153
+ }
1154
+ }
1155
+ }
1156
+ }
1157
+ },
1158
+ "ProductDetailResponse": {
1159
+ "type": "object",
1160
+ "properties": {
1161
+ "success": {
1162
+ "type": "boolean",
1163
+ "example": true
1164
+ },
1165
+ "data": {
1166
+ "$ref": "#/components/schemas/ProductDetail"
1167
+ }
1168
+ }
1169
+ },
1170
+ "StoreSearchResponse": {
1171
+ "type": "object",
1172
+ "properties": {
1173
+ "success": {
1174
+ "type": "boolean",
1175
+ "example": true
1176
+ },
1177
+ "data": {
1178
+ "type": "object",
1179
+ "properties": {
1180
+ "stores": {
1181
+ "type": "array",
1182
+ "items": {
1183
+ "$ref": "#/components/schemas/Store"
1184
+ }
1185
+ }
1186
+ }
1187
+ },
1188
+ "meta": {
1189
+ "type": "object",
1190
+ "properties": {
1191
+ "total": {
1192
+ "type": "integer",
1193
+ "description": "전체 결과 수"
1194
+ }
1195
+ }
1196
+ }
1197
+ }
1198
+ },
1199
+ "InventoryResponse": {
1200
+ "type": "object",
1201
+ "properties": {
1202
+ "success": {
1203
+ "type": "boolean",
1204
+ "example": true
1205
+ },
1206
+ "data": {
1207
+ "type": "object",
1208
+ "properties": {
1209
+ "productId": {
1210
+ "type": "string",
1211
+ "description": "제품 ID"
1212
+ },
1213
+ "location": {
1214
+ "type": "object",
1215
+ "properties": {
1216
+ "latitude": {
1217
+ "type": "number",
1218
+ "format": "float"
1219
+ },
1220
+ "longitude": {
1221
+ "type": "number",
1222
+ "format": "float"
1223
+ }
1224
+ }
1225
+ },
1226
+ "onlineStock": {
1227
+ "type": "integer",
1228
+ "description": "온라인 재고 수량",
1229
+ "example": 150
1230
+ },
1231
+ "storeInventory": {
1232
+ "type": "object",
1233
+ "properties": {
1234
+ "totalStores": {
1235
+ "type": "integer",
1236
+ "description": "전체 매장 수"
1237
+ },
1238
+ "inStockCount": {
1239
+ "type": "integer",
1240
+ "description": "재고 있는 매장 수"
1241
+ },
1242
+ "stores": {
1243
+ "type": "array",
1244
+ "items": {
1245
+ "$ref": "#/components/schemas/StoreInventory"
1246
+ }
1247
+ }
1248
+ }
1249
+ }
1250
+ }
1251
+ },
1252
+ "meta": {
1253
+ "type": "object",
1254
+ "properties": {
1255
+ "total": {
1256
+ "type": "integer"
1257
+ },
1258
+ "page": {
1259
+ "type": "integer"
1260
+ },
1261
+ "pageSize": {
1262
+ "type": "integer"
1263
+ }
1264
+ }
1265
+ }
1266
+ }
1267
+ },
1268
+ "OliveyoungStore": {
1269
+ "type": "object",
1270
+ "description": "올리브영 매장 정보",
1271
+ "properties": {
1272
+ "storeCode": {
1273
+ "type": "string",
1274
+ "example": "D176"
1275
+ },
1276
+ "storeName": {
1277
+ "type": "string",
1278
+ "example": "올리브영 명동 타운"
1279
+ },
1280
+ "address": {
1281
+ "type": "string",
1282
+ "example": "서울특별시 중구 명동길 53"
1283
+ },
1284
+ "latitude": {
1285
+ "type": "number",
1286
+ "format": "float",
1287
+ "example": 37.56409158
1288
+ },
1289
+ "longitude": {
1290
+ "type": "number",
1291
+ "format": "float",
1292
+ "example": 126.9851771
1293
+ },
1294
+ "pickupYn": {
1295
+ "type": "boolean",
1296
+ "example": false
1297
+ },
1298
+ "o2oRemainQuantity": {
1299
+ "type": "integer",
1300
+ "example": 0
1301
+ }
1302
+ }
1303
+ },
1304
+ "OliveyoungProduct": {
1305
+ "type": "object",
1306
+ "description": "올리브영 상품 재고 정보",
1307
+ "properties": {
1308
+ "goodsNumber": {
1309
+ "type": "string",
1310
+ "example": "A000000200614"
1311
+ },
1312
+ "goodsName": {
1313
+ "type": "string",
1314
+ "example": "달바 퍼플 톤업 선크림 듀오 기획"
1315
+ },
1316
+ "priceToPay": {
1317
+ "type": "integer",
1318
+ "example": 32130
1319
+ },
1320
+ "originalPrice": {
1321
+ "type": "integer",
1322
+ "example": 51000
1323
+ },
1324
+ "discountRate": {
1325
+ "type": "integer",
1326
+ "example": 37
1327
+ },
1328
+ "o2oStockFlag": {
1329
+ "type": "boolean",
1330
+ "example": true
1331
+ },
1332
+ "o2oRemainQuantity": {
1333
+ "type": "integer",
1334
+ "example": 0
1335
+ }
1336
+ }
1337
+ },
1338
+ "OliveyoungStoreSearchResponse": {
1339
+ "type": "object",
1340
+ "properties": {
1341
+ "success": {
1342
+ "type": "boolean",
1343
+ "example": true
1344
+ },
1345
+ "data": {
1346
+ "type": "object",
1347
+ "properties": {
1348
+ "stores": {
1349
+ "type": "array",
1350
+ "items": {
1351
+ "$ref": "#/components/schemas/OliveyoungStore"
1352
+ }
1353
+ }
1354
+ }
1355
+ },
1356
+ "meta": {
1357
+ "type": "object",
1358
+ "properties": {
1359
+ "total": {
1360
+ "type": "integer"
1361
+ },
1362
+ "page": {
1363
+ "type": "integer"
1364
+ },
1365
+ "pageSize": {
1366
+ "type": "integer"
1367
+ }
1368
+ }
1369
+ }
1370
+ }
1371
+ },
1372
+ "OliveyoungInventoryResponse": {
1373
+ "type": "object",
1374
+ "properties": {
1375
+ "success": {
1376
+ "type": "boolean",
1377
+ "example": true
1378
+ },
1379
+ "data": {
1380
+ "type": "object",
1381
+ "properties": {
1382
+ "keyword": {
1383
+ "type": "string",
1384
+ "example": "선크림"
1385
+ },
1386
+ "location": {
1387
+ "type": "object",
1388
+ "properties": {
1389
+ "latitude": {
1390
+ "type": "number",
1391
+ "format": "float"
1392
+ },
1393
+ "longitude": {
1394
+ "type": "number",
1395
+ "format": "float"
1396
+ }
1397
+ }
1398
+ },
1399
+ "nearbyStores": {
1400
+ "type": "object",
1401
+ "properties": {
1402
+ "totalCount": {
1403
+ "type": "integer"
1404
+ },
1405
+ "stores": {
1406
+ "type": "array",
1407
+ "items": {
1408
+ "$ref": "#/components/schemas/OliveyoungStore"
1409
+ }
1410
+ }
1411
+ }
1412
+ },
1413
+ "inventory": {
1414
+ "type": "object",
1415
+ "properties": {
1416
+ "totalCount": {
1417
+ "type": "integer"
1418
+ },
1419
+ "nextPage": {
1420
+ "type": "boolean"
1421
+ },
1422
+ "products": {
1423
+ "type": "array",
1424
+ "items": {
1425
+ "$ref": "#/components/schemas/OliveyoungProduct"
1426
+ }
1427
+ }
1428
+ }
1429
+ }
1430
+ }
1431
+ },
1432
+ "meta": {
1433
+ "type": "object",
1434
+ "properties": {
1435
+ "total": {
1436
+ "type": "integer"
1437
+ },
1438
+ "page": {
1439
+ "type": "integer"
1440
+ },
1441
+ "pageSize": {
1442
+ "type": "integer"
1443
+ }
1444
+ }
1445
+ }
1446
+ }
1447
+ },
1448
+ "MegaboxTheater": {
1449
+ "type": "object",
1450
+ "properties": {
1451
+ "theaterId": {
1452
+ "type": "string",
1453
+ "example": "1372"
1454
+ },
1455
+ "theaterName": {
1456
+ "type": "string",
1457
+ "example": "강남"
1458
+ },
1459
+ "address": {
1460
+ "type": "string",
1461
+ "example": "서울특별시 강남구 강남대로 438"
1462
+ },
1463
+ "latitude": {
1464
+ "type": "number",
1465
+ "format": "float",
1466
+ "example": 37.4982
1467
+ },
1468
+ "longitude": {
1469
+ "type": "number",
1470
+ "format": "float",
1471
+ "example": 127.0264
1472
+ },
1473
+ "distanceKm": {
1474
+ "type": "number",
1475
+ "format": "float",
1476
+ "example": 0.5
1477
+ }
1478
+ }
1479
+ },
1480
+ "MegaboxShowtime": {
1481
+ "type": "object",
1482
+ "properties": {
1483
+ "scheduleId": {
1484
+ "type": "string",
1485
+ "example": "2603041372011"
1486
+ },
1487
+ "movieId": {
1488
+ "type": "string",
1489
+ "example": "25104500"
1490
+ },
1491
+ "movieName": {
1492
+ "type": "string",
1493
+ "example": "미키 17"
1494
+ },
1495
+ "theaterId": {
1496
+ "type": "string",
1497
+ "example": "1372"
1498
+ },
1499
+ "theaterName": {
1500
+ "type": "string",
1501
+ "example": "강남"
1502
+ },
1503
+ "playDate": {
1504
+ "type": "string",
1505
+ "example": "20260304"
1506
+ },
1507
+ "startTime": {
1508
+ "type": "string",
1509
+ "example": "09:30"
1510
+ },
1511
+ "endTime": {
1512
+ "type": "string",
1513
+ "example": "11:20"
1514
+ },
1515
+ "totalSeats": {
1516
+ "type": "integer",
1517
+ "example": 120
1518
+ },
1519
+ "remainingSeats": {
1520
+ "type": "integer",
1521
+ "example": 42
1522
+ }
1523
+ }
1524
+ },
1525
+ "MegaboxTheaterSearchResponse": {
1526
+ "type": "object",
1527
+ "properties": {
1528
+ "success": {
1529
+ "type": "boolean",
1530
+ "example": true
1531
+ },
1532
+ "data": {
1533
+ "type": "object",
1534
+ "properties": {
1535
+ "location": {
1536
+ "type": "object",
1537
+ "properties": {
1538
+ "latitude": {
1539
+ "type": "number",
1540
+ "format": "float"
1541
+ },
1542
+ "longitude": {
1543
+ "type": "number",
1544
+ "format": "float"
1545
+ }
1546
+ }
1547
+ },
1548
+ "playDate": {
1549
+ "type": "string"
1550
+ },
1551
+ "areaCode": {
1552
+ "type": "string"
1553
+ },
1554
+ "theaters": {
1555
+ "type": "array",
1556
+ "items": {
1557
+ "$ref": "#/components/schemas/MegaboxTheater"
1558
+ }
1559
+ }
1560
+ }
1561
+ },
1562
+ "meta": {
1563
+ "type": "object",
1564
+ "properties": {
1565
+ "total": {
1566
+ "type": "integer"
1567
+ },
1568
+ "pageSize": {
1569
+ "type": "integer"
1570
+ }
1571
+ }
1572
+ }
1573
+ }
1574
+ },
1575
+ "MegaboxMovieListResponse": {
1576
+ "type": "object",
1577
+ "properties": {
1578
+ "success": {
1579
+ "type": "boolean",
1580
+ "example": true
1581
+ },
1582
+ "data": {
1583
+ "type": "object",
1584
+ "properties": {
1585
+ "playDate": {
1586
+ "type": "string"
1587
+ },
1588
+ "filters": {
1589
+ "type": "object",
1590
+ "properties": {
1591
+ "theaterId": {
1592
+ "type": "string",
1593
+ "nullable": true
1594
+ },
1595
+ "movieId": {
1596
+ "type": "string",
1597
+ "nullable": true
1598
+ },
1599
+ "areaCode": {
1600
+ "type": "string"
1601
+ }
1602
+ }
1603
+ },
1604
+ "theaters": {
1605
+ "type": "array",
1606
+ "items": {
1607
+ "type": "object",
1608
+ "properties": {
1609
+ "theaterId": {
1610
+ "type": "string"
1611
+ },
1612
+ "theaterName": {
1613
+ "type": "string"
1614
+ }
1615
+ }
1616
+ }
1617
+ },
1618
+ "movies": {
1619
+ "type": "array",
1620
+ "items": {
1621
+ "type": "object",
1622
+ "properties": {
1623
+ "movieId": {
1624
+ "type": "string"
1625
+ },
1626
+ "movieName": {
1627
+ "type": "string"
1628
+ },
1629
+ "movieStatus": {
1630
+ "type": "string"
1631
+ }
1632
+ }
1633
+ }
1634
+ },
1635
+ "showtimes": {
1636
+ "type": "array",
1637
+ "items": {
1638
+ "$ref": "#/components/schemas/MegaboxShowtime"
1639
+ }
1640
+ }
1641
+ }
1642
+ },
1643
+ "meta": {
1644
+ "type": "object",
1645
+ "properties": {
1646
+ "total": {
1647
+ "type": "integer"
1648
+ }
1649
+ }
1650
+ }
1651
+ }
1652
+ },
1653
+ "MegaboxSeatListResponse": {
1654
+ "type": "object",
1655
+ "properties": {
1656
+ "success": {
1657
+ "type": "boolean",
1658
+ "example": true
1659
+ },
1660
+ "data": {
1661
+ "type": "object",
1662
+ "properties": {
1663
+ "playDate": {
1664
+ "type": "string"
1665
+ },
1666
+ "filters": {
1667
+ "type": "object",
1668
+ "properties": {
1669
+ "theaterId": {
1670
+ "type": "string",
1671
+ "nullable": true
1672
+ },
1673
+ "movieId": {
1674
+ "type": "string",
1675
+ "nullable": true
1676
+ },
1677
+ "areaCode": {
1678
+ "type": "string"
1679
+ }
1680
+ }
1681
+ },
1682
+ "seats": {
1683
+ "type": "array",
1684
+ "items": {
1685
+ "$ref": "#/components/schemas/MegaboxShowtime"
1686
+ }
1687
+ }
1688
+ }
1689
+ },
1690
+ "meta": {
1691
+ "type": "object",
1692
+ "properties": {
1693
+ "total": {
1694
+ "type": "integer"
1695
+ },
1696
+ "pageSize": {
1697
+ "type": "integer"
1698
+ }
1699
+ }
1700
+ }
1701
+ }
1702
+ },
1703
+ "CgvTheater": {
1704
+ "type": "object",
1705
+ "properties": {
1706
+ "theaterCode": {
1707
+ "type": "string",
1708
+ "example": "0056"
1709
+ },
1710
+ "theaterName": {
1711
+ "type": "string",
1712
+ "example": "CGV강남"
1713
+ },
1714
+ "regionCode": {
1715
+ "type": "string",
1716
+ "example": "01"
1717
+ }
1718
+ }
1719
+ },
1720
+ "CgvMovie": {
1721
+ "type": "object",
1722
+ "properties": {
1723
+ "movieCode": {
1724
+ "type": "string",
1725
+ "example": "200001"
1726
+ },
1727
+ "movieName": {
1728
+ "type": "string",
1729
+ "example": "테스트 영화"
1730
+ },
1731
+ "rating": {
1732
+ "type": "string",
1733
+ "example": "12"
1734
+ }
1735
+ }
1736
+ },
1737
+ "CgvTimetable": {
1738
+ "type": "object",
1739
+ "properties": {
1740
+ "scheduleId": {
1741
+ "type": "string",
1742
+ "example": "SCH1"
1743
+ },
1744
+ "movieCode": {
1745
+ "type": "string",
1746
+ "example": "200001"
1747
+ },
1748
+ "movieName": {
1749
+ "type": "string",
1750
+ "example": "테스트 영화"
1751
+ },
1752
+ "theaterCode": {
1753
+ "type": "string",
1754
+ "example": "0056"
1755
+ },
1756
+ "theaterName": {
1757
+ "type": "string",
1758
+ "example": "CGV강남"
1759
+ },
1760
+ "playDate": {
1761
+ "type": "string",
1762
+ "example": "20260304"
1763
+ },
1764
+ "startTime": {
1765
+ "type": "string",
1766
+ "example": "09:30"
1767
+ },
1768
+ "endTime": {
1769
+ "type": "string",
1770
+ "example": "11:20"
1771
+ },
1772
+ "totalSeats": {
1773
+ "type": "integer",
1774
+ "example": 150
1775
+ },
1776
+ "remainingSeats": {
1777
+ "type": "integer",
1778
+ "example": 42
1779
+ }
1780
+ }
1781
+ },
1782
+ "CgvTheaterSearchResponse": {
1783
+ "type": "object",
1784
+ "properties": {
1785
+ "success": {
1786
+ "type": "boolean",
1787
+ "example": true
1788
+ },
1789
+ "data": {
1790
+ "type": "object",
1791
+ "properties": {
1792
+ "playDate": {
1793
+ "type": "string"
1794
+ },
1795
+ "filters": {
1796
+ "type": "object",
1797
+ "properties": {
1798
+ "regionCode": {
1799
+ "type": "string",
1800
+ "nullable": true
1801
+ }
1802
+ }
1803
+ },
1804
+ "theaters": {
1805
+ "type": "array",
1806
+ "items": {
1807
+ "$ref": "#/components/schemas/CgvTheater"
1808
+ }
1809
+ }
1810
+ }
1811
+ },
1812
+ "meta": {
1813
+ "type": "object",
1814
+ "properties": {
1815
+ "total": {
1816
+ "type": "integer"
1817
+ },
1818
+ "pageSize": {
1819
+ "type": "integer"
1820
+ }
1821
+ }
1822
+ }
1823
+ }
1824
+ },
1825
+ "CgvMovieSearchResponse": {
1826
+ "type": "object",
1827
+ "properties": {
1828
+ "success": {
1829
+ "type": "boolean",
1830
+ "example": true
1831
+ },
1832
+ "data": {
1833
+ "type": "object",
1834
+ "properties": {
1835
+ "playDate": {
1836
+ "type": "string"
1837
+ },
1838
+ "filters": {
1839
+ "type": "object",
1840
+ "properties": {
1841
+ "theaterCode": {
1842
+ "type": "string",
1843
+ "nullable": true
1844
+ }
1845
+ }
1846
+ },
1847
+ "movies": {
1848
+ "type": "array",
1849
+ "items": {
1850
+ "$ref": "#/components/schemas/CgvMovie"
1851
+ }
1852
+ }
1853
+ }
1854
+ },
1855
+ "meta": {
1856
+ "type": "object",
1857
+ "properties": {
1858
+ "total": {
1859
+ "type": "integer"
1860
+ }
1861
+ }
1862
+ }
1863
+ }
1864
+ },
1865
+ "CgvTimetableResponse": {
1866
+ "type": "object",
1867
+ "properties": {
1868
+ "success": {
1869
+ "type": "boolean",
1870
+ "example": true
1871
+ },
1872
+ "data": {
1873
+ "type": "object",
1874
+ "properties": {
1875
+ "playDate": {
1876
+ "type": "string"
1877
+ },
1878
+ "filters": {
1879
+ "type": "object",
1880
+ "properties": {
1881
+ "theaterCode": {
1882
+ "type": "string",
1883
+ "nullable": true
1884
+ },
1885
+ "movieCode": {
1886
+ "type": "string",
1887
+ "nullable": true
1888
+ }
1889
+ }
1890
+ },
1891
+ "timetable": {
1892
+ "type": "array",
1893
+ "items": {
1894
+ "$ref": "#/components/schemas/CgvTimetable"
1895
+ }
1896
+ }
1897
+ }
1898
+ },
1899
+ "meta": {
1900
+ "type": "object",
1901
+ "properties": {
1902
+ "total": {
1903
+ "type": "integer"
1904
+ },
1905
+ "pageSize": {
1906
+ "type": "integer"
1907
+ }
1908
+ }
1909
+ }
1910
+ }
1911
+ },
1912
+ "ErrorResponse": {
1913
+ "type": "object",
1914
+ "properties": {
1915
+ "success": {
1916
+ "type": "boolean",
1917
+ "example": false
1918
+ },
1919
+ "error": {
1920
+ "type": "object",
1921
+ "properties": {
1922
+ "code": {
1923
+ "type": "string",
1924
+ "description": "에러 코드",
1925
+ "example": "MISSING_QUERY"
1926
+ },
1927
+ "message": {
1928
+ "type": "string",
1929
+ "description": "에러 메시지",
1930
+ "example": "검색어(q)를 입력해주세요."
1931
+ }
1932
+ }
1933
+ }
1934
+ }
1935
+ }
1936
+ }
1937
+ }
1938
+ }