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
@@ -0,0 +1,419 @@
1
+ /**
2
+ * OpenAPI 컴포넌트 스키마 정의
3
+ */
4
+ import { OPENAPI_CGV_COMPONENT_SCHEMAS } from './openapiSpecComponentsCgv.js';
5
+ export const OPENAPI_COMPONENTS = {
6
+ schemas: {
7
+ Product: {
8
+ type: 'object',
9
+ description: '제품 정보',
10
+ properties: {
11
+ id: { type: 'string', description: '제품 ID', example: '1234567890' },
12
+ name: { type: 'string', description: '제품명', example: 'PP 수납박스 대형' },
13
+ price: { type: 'integer', description: '가격 (원)', example: 5000 },
14
+ imageUrl: {
15
+ type: 'string',
16
+ description: '제품 이미지 URL',
17
+ example: 'https://img.daisomall.co.kr/...',
18
+ },
19
+ soldOut: { type: 'boolean', description: '품절 여부', example: false },
20
+ isNew: { type: 'boolean', description: '신상품 여부', example: false },
21
+ pickupAvailable: { type: 'boolean', description: '매장 픽업 가능 여부', example: true },
22
+ },
23
+ },
24
+ ProductDetail: {
25
+ type: 'object',
26
+ description: '제품 상세 정보',
27
+ properties: {
28
+ id: { type: 'string', description: '제품 ID' },
29
+ name: { type: 'string', description: '제품명' },
30
+ price: { type: 'integer', description: '가격 (원)' },
31
+ currency: { type: 'string', description: '통화', example: 'KRW' },
32
+ imageUrl: { type: 'string', description: '제품 이미지 URL' },
33
+ brand: { type: 'string', description: '브랜드명' },
34
+ soldOut: { type: 'boolean', description: '품절 여부' },
35
+ isNew: { type: 'boolean', description: '신상품 여부' },
36
+ },
37
+ },
38
+ Store: {
39
+ type: 'object',
40
+ description: '매장 정보',
41
+ properties: {
42
+ name: { type: 'string', description: '매장명', example: '다이소 강남역점' },
43
+ phone: { type: 'string', description: '전화번호', example: '02-1234-5678' },
44
+ address: {
45
+ type: 'string',
46
+ description: '주소',
47
+ example: '서울특별시 강남구 강남대로 123',
48
+ },
49
+ lat: { type: 'number', format: 'float', description: '위도', example: 37.4979 },
50
+ lng: { type: 'number', format: 'float', description: '경도', example: 127.0276 },
51
+ openTime: { type: 'string', description: '영업 시작 시간', example: '10:00' },
52
+ closeTime: { type: 'string', description: '영업 종료 시간', example: '22:00' },
53
+ options: {
54
+ type: 'object',
55
+ description: '매장 옵션',
56
+ properties: {
57
+ parking: { type: 'boolean', description: '주차 가능 여부' },
58
+ pickup: { type: 'boolean', description: '픽업 가능 여부' },
59
+ taxFree: { type: 'boolean', description: '면세 가능 여부' },
60
+ },
61
+ },
62
+ },
63
+ },
64
+ StoreInventory: {
65
+ type: 'object',
66
+ description: '매장 재고 정보',
67
+ properties: {
68
+ storeCode: { type: 'string', description: '매장 코드', example: 'ST001' },
69
+ storeName: { type: 'string', description: '매장명', example: '다이소 강남역점' },
70
+ address: { type: 'string', description: '주소' },
71
+ distance: { type: 'string', description: '거리', example: '0.5km' },
72
+ quantity: { type: 'integer', description: '재고 수량', example: 12 },
73
+ options: {
74
+ type: 'object',
75
+ properties: {
76
+ parking: { type: 'boolean' },
77
+ pickup: { type: 'boolean' },
78
+ },
79
+ },
80
+ },
81
+ },
82
+ ProductSearchResponse: {
83
+ type: 'object',
84
+ properties: {
85
+ success: { type: 'boolean', example: true },
86
+ data: {
87
+ type: 'object',
88
+ properties: {
89
+ products: { type: 'array', items: { $ref: '#/components/schemas/Product' } },
90
+ },
91
+ },
92
+ meta: {
93
+ type: 'object',
94
+ properties: {
95
+ total: { type: 'integer', description: '전체 결과 수' },
96
+ page: { type: 'integer', description: '현재 페이지' },
97
+ pageSize: { type: 'integer', description: '페이지당 결과 수' },
98
+ },
99
+ },
100
+ },
101
+ },
102
+ ProductDetailResponse: {
103
+ type: 'object',
104
+ properties: {
105
+ success: { type: 'boolean', example: true },
106
+ data: { $ref: '#/components/schemas/ProductDetail' },
107
+ },
108
+ },
109
+ StoreSearchResponse: {
110
+ type: 'object',
111
+ properties: {
112
+ success: { type: 'boolean', example: true },
113
+ data: {
114
+ type: 'object',
115
+ properties: {
116
+ stores: { type: 'array', items: { $ref: '#/components/schemas/Store' } },
117
+ },
118
+ },
119
+ meta: {
120
+ type: 'object',
121
+ properties: { total: { type: 'integer', description: '전체 결과 수' } },
122
+ },
123
+ },
124
+ },
125
+ InventoryResponse: {
126
+ type: 'object',
127
+ properties: {
128
+ success: { type: 'boolean', example: true },
129
+ data: {
130
+ type: 'object',
131
+ properties: {
132
+ productId: { type: 'string', description: '제품 ID' },
133
+ location: {
134
+ type: 'object',
135
+ properties: {
136
+ latitude: { type: 'number', format: 'float' },
137
+ longitude: { type: 'number', format: 'float' },
138
+ },
139
+ },
140
+ onlineStock: { type: 'integer', description: '온라인 재고 수량', example: 150 },
141
+ storeInventory: {
142
+ type: 'object',
143
+ properties: {
144
+ totalStores: { type: 'integer', description: '전체 매장 수' },
145
+ inStockCount: { type: 'integer', description: '재고 있는 매장 수' },
146
+ stores: {
147
+ type: 'array',
148
+ items: { $ref: '#/components/schemas/StoreInventory' },
149
+ },
150
+ },
151
+ },
152
+ },
153
+ },
154
+ meta: {
155
+ type: 'object',
156
+ properties: {
157
+ total: { type: 'integer' },
158
+ page: { type: 'integer' },
159
+ pageSize: { type: 'integer' },
160
+ },
161
+ },
162
+ },
163
+ },
164
+ OliveyoungStore: {
165
+ type: 'object',
166
+ description: '올리브영 매장 정보',
167
+ properties: {
168
+ storeCode: { type: 'string', example: 'D176' },
169
+ storeName: { type: 'string', example: '올리브영 명동 타운' },
170
+ address: { type: 'string', example: '서울특별시 중구 명동길 53' },
171
+ latitude: { type: 'number', format: 'float', example: 37.56409158 },
172
+ longitude: { type: 'number', format: 'float', example: 126.9851771 },
173
+ pickupYn: { type: 'boolean', example: false },
174
+ o2oRemainQuantity: { type: 'integer', example: 0 },
175
+ },
176
+ },
177
+ OliveyoungProduct: {
178
+ type: 'object',
179
+ description: '올리브영 상품 재고 정보',
180
+ properties: {
181
+ goodsNumber: { type: 'string', example: 'A000000200614' },
182
+ goodsName: { type: 'string', example: '달바 퍼플 톤업 선크림 듀오 기획' },
183
+ priceToPay: { type: 'integer', example: 32130 },
184
+ originalPrice: { type: 'integer', example: 51000 },
185
+ discountRate: { type: 'integer', example: 37 },
186
+ o2oStockFlag: { type: 'boolean', example: true },
187
+ o2oRemainQuantity: { type: 'integer', example: 0 },
188
+ },
189
+ },
190
+ OliveyoungStoreSearchResponse: {
191
+ type: 'object',
192
+ properties: {
193
+ success: { type: 'boolean', example: true },
194
+ data: {
195
+ type: 'object',
196
+ properties: {
197
+ stores: {
198
+ type: 'array',
199
+ items: { $ref: '#/components/schemas/OliveyoungStore' },
200
+ },
201
+ },
202
+ },
203
+ meta: {
204
+ type: 'object',
205
+ properties: {
206
+ total: { type: 'integer' },
207
+ page: { type: 'integer' },
208
+ pageSize: { type: 'integer' },
209
+ },
210
+ },
211
+ },
212
+ },
213
+ OliveyoungInventoryResponse: {
214
+ type: 'object',
215
+ properties: {
216
+ success: { type: 'boolean', example: true },
217
+ data: {
218
+ type: 'object',
219
+ properties: {
220
+ keyword: { type: 'string', example: '선크림' },
221
+ location: {
222
+ type: 'object',
223
+ properties: {
224
+ latitude: { type: 'number', format: 'float' },
225
+ longitude: { type: 'number', format: 'float' },
226
+ },
227
+ },
228
+ nearbyStores: {
229
+ type: 'object',
230
+ properties: {
231
+ totalCount: { type: 'integer' },
232
+ stores: {
233
+ type: 'array',
234
+ items: { $ref: '#/components/schemas/OliveyoungStore' },
235
+ },
236
+ },
237
+ },
238
+ inventory: {
239
+ type: 'object',
240
+ properties: {
241
+ totalCount: { type: 'integer' },
242
+ nextPage: { type: 'boolean' },
243
+ products: {
244
+ type: 'array',
245
+ items: { $ref: '#/components/schemas/OliveyoungProduct' },
246
+ },
247
+ },
248
+ },
249
+ },
250
+ },
251
+ meta: {
252
+ type: 'object',
253
+ properties: {
254
+ total: { type: 'integer' },
255
+ page: { type: 'integer' },
256
+ pageSize: { type: 'integer' },
257
+ },
258
+ },
259
+ },
260
+ },
261
+ MegaboxTheater: {
262
+ type: 'object',
263
+ properties: {
264
+ theaterId: { type: 'string', example: '1372' },
265
+ theaterName: { type: 'string', example: '강남' },
266
+ address: { type: 'string', example: '서울특별시 강남구 강남대로 438' },
267
+ latitude: { type: 'number', format: 'float', example: 37.4982 },
268
+ longitude: { type: 'number', format: 'float', example: 127.0264 },
269
+ distanceKm: { type: 'number', format: 'float', example: 0.5 },
270
+ },
271
+ },
272
+ MegaboxShowtime: {
273
+ type: 'object',
274
+ properties: {
275
+ scheduleId: { type: 'string', example: '2603041372011' },
276
+ movieId: { type: 'string', example: '25104500' },
277
+ movieName: { type: 'string', example: '미키 17' },
278
+ theaterId: { type: 'string', example: '1372' },
279
+ theaterName: { type: 'string', example: '강남' },
280
+ playDate: { type: 'string', example: '20260304' },
281
+ startTime: { type: 'string', example: '09:30' },
282
+ endTime: { type: 'string', example: '11:20' },
283
+ totalSeats: { type: 'integer', example: 120 },
284
+ remainingSeats: { type: 'integer', example: 42 },
285
+ },
286
+ },
287
+ MegaboxTheaterSearchResponse: {
288
+ type: 'object',
289
+ properties: {
290
+ success: { type: 'boolean', example: true },
291
+ data: {
292
+ type: 'object',
293
+ properties: {
294
+ location: {
295
+ type: 'object',
296
+ properties: {
297
+ latitude: { type: 'number', format: 'float' },
298
+ longitude: { type: 'number', format: 'float' },
299
+ },
300
+ },
301
+ playDate: { type: 'string' },
302
+ areaCode: { type: 'string' },
303
+ theaters: {
304
+ type: 'array',
305
+ items: { $ref: '#/components/schemas/MegaboxTheater' },
306
+ },
307
+ },
308
+ },
309
+ meta: {
310
+ type: 'object',
311
+ properties: {
312
+ total: { type: 'integer' },
313
+ pageSize: { type: 'integer' },
314
+ },
315
+ },
316
+ },
317
+ },
318
+ MegaboxMovieListResponse: {
319
+ type: 'object',
320
+ properties: {
321
+ success: { type: 'boolean', example: true },
322
+ data: {
323
+ type: 'object',
324
+ properties: {
325
+ playDate: { type: 'string' },
326
+ filters: {
327
+ type: 'object',
328
+ properties: {
329
+ theaterId: { type: 'string', nullable: true },
330
+ movieId: { type: 'string', nullable: true },
331
+ areaCode: { type: 'string' },
332
+ },
333
+ },
334
+ theaters: {
335
+ type: 'array',
336
+ items: {
337
+ type: 'object',
338
+ properties: {
339
+ theaterId: { type: 'string' },
340
+ theaterName: { type: 'string' },
341
+ },
342
+ },
343
+ },
344
+ movies: {
345
+ type: 'array',
346
+ items: {
347
+ type: 'object',
348
+ properties: {
349
+ movieId: { type: 'string' },
350
+ movieName: { type: 'string' },
351
+ movieStatus: { type: 'string' },
352
+ },
353
+ },
354
+ },
355
+ showtimes: {
356
+ type: 'array',
357
+ items: { $ref: '#/components/schemas/MegaboxShowtime' },
358
+ },
359
+ },
360
+ },
361
+ meta: {
362
+ type: 'object',
363
+ properties: {
364
+ total: { type: 'integer' },
365
+ },
366
+ },
367
+ },
368
+ },
369
+ MegaboxSeatListResponse: {
370
+ type: 'object',
371
+ properties: {
372
+ success: { type: 'boolean', example: true },
373
+ data: {
374
+ type: 'object',
375
+ properties: {
376
+ playDate: { type: 'string' },
377
+ filters: {
378
+ type: 'object',
379
+ properties: {
380
+ theaterId: { type: 'string', nullable: true },
381
+ movieId: { type: 'string', nullable: true },
382
+ areaCode: { type: 'string' },
383
+ },
384
+ },
385
+ seats: {
386
+ type: 'array',
387
+ items: { $ref: '#/components/schemas/MegaboxShowtime' },
388
+ },
389
+ },
390
+ },
391
+ meta: {
392
+ type: 'object',
393
+ properties: {
394
+ total: { type: 'integer' },
395
+ pageSize: { type: 'integer' },
396
+ },
397
+ },
398
+ },
399
+ },
400
+ ...OPENAPI_CGV_COMPONENT_SCHEMAS,
401
+ ErrorResponse: {
402
+ type: 'object',
403
+ properties: {
404
+ success: { type: 'boolean', example: false },
405
+ error: {
406
+ type: 'object',
407
+ properties: {
408
+ code: { type: 'string', description: '에러 코드', example: 'MISSING_QUERY' },
409
+ message: {
410
+ type: 'string',
411
+ description: '에러 메시지',
412
+ example: '검색어(q)를 입력해주세요.',
413
+ },
414
+ },
415
+ },
416
+ },
417
+ },
418
+ },
419
+ };
@@ -0,0 +1,123 @@
1
+ /**
2
+ * OpenAPI CGV 컴포넌트 스키마 정의
3
+ */
4
+ export const OPENAPI_CGV_COMPONENT_SCHEMAS = {
5
+ CgvTheater: {
6
+ type: 'object',
7
+ properties: {
8
+ theaterCode: { type: 'string', example: '0056' },
9
+ theaterName: { type: 'string', example: 'CGV강남' },
10
+ regionCode: { type: 'string', example: '01' },
11
+ },
12
+ },
13
+ CgvMovie: {
14
+ type: 'object',
15
+ properties: {
16
+ movieCode: { type: 'string', example: '200001' },
17
+ movieName: { type: 'string', example: '테스트 영화' },
18
+ rating: { type: 'string', example: '12' },
19
+ },
20
+ },
21
+ CgvTimetable: {
22
+ type: 'object',
23
+ properties: {
24
+ scheduleId: { type: 'string', example: 'SCH1' },
25
+ movieCode: { type: 'string', example: '200001' },
26
+ movieName: { type: 'string', example: '테스트 영화' },
27
+ theaterCode: { type: 'string', example: '0056' },
28
+ theaterName: { type: 'string', example: 'CGV강남' },
29
+ playDate: { type: 'string', example: '20260304' },
30
+ startTime: { type: 'string', example: '09:30' },
31
+ endTime: { type: 'string', example: '11:20' },
32
+ totalSeats: { type: 'integer', example: 150 },
33
+ remainingSeats: { type: 'integer', example: 42 },
34
+ },
35
+ },
36
+ CgvTheaterSearchResponse: {
37
+ type: 'object',
38
+ properties: {
39
+ success: { type: 'boolean', example: true },
40
+ data: {
41
+ type: 'object',
42
+ properties: {
43
+ playDate: { type: 'string' },
44
+ filters: {
45
+ type: 'object',
46
+ properties: {
47
+ regionCode: { type: 'string', nullable: true },
48
+ },
49
+ },
50
+ theaters: {
51
+ type: 'array',
52
+ items: { $ref: '#/components/schemas/CgvTheater' },
53
+ },
54
+ },
55
+ },
56
+ meta: {
57
+ type: 'object',
58
+ properties: {
59
+ total: { type: 'integer' },
60
+ pageSize: { type: 'integer' },
61
+ },
62
+ },
63
+ },
64
+ },
65
+ CgvMovieSearchResponse: {
66
+ type: 'object',
67
+ properties: {
68
+ success: { type: 'boolean', example: true },
69
+ data: {
70
+ type: 'object',
71
+ properties: {
72
+ playDate: { type: 'string' },
73
+ filters: {
74
+ type: 'object',
75
+ properties: {
76
+ theaterCode: { type: 'string', nullable: true },
77
+ },
78
+ },
79
+ movies: {
80
+ type: 'array',
81
+ items: { $ref: '#/components/schemas/CgvMovie' },
82
+ },
83
+ },
84
+ },
85
+ meta: {
86
+ type: 'object',
87
+ properties: {
88
+ total: { type: 'integer' },
89
+ },
90
+ },
91
+ },
92
+ },
93
+ CgvTimetableResponse: {
94
+ type: 'object',
95
+ properties: {
96
+ success: { type: 'boolean', example: true },
97
+ data: {
98
+ type: 'object',
99
+ properties: {
100
+ playDate: { type: 'string' },
101
+ filters: {
102
+ type: 'object',
103
+ properties: {
104
+ theaterCode: { type: 'string', nullable: true },
105
+ movieCode: { type: 'string', nullable: true },
106
+ },
107
+ },
108
+ timetable: {
109
+ type: 'array',
110
+ items: { $ref: '#/components/schemas/CgvTimetable' },
111
+ },
112
+ },
113
+ },
114
+ meta: {
115
+ type: 'object',
116
+ properties: {
117
+ total: { type: 'integer' },
118
+ pageSize: { type: 'integer' },
119
+ },
120
+ },
121
+ },
122
+ },
123
+ };
@@ -0,0 +1,149 @@
1
+ /**
2
+ * OpenAPI 경로 정의 (CGV)
3
+ */
4
+ export const OPENAPI_PATHS_CGV = {
5
+ '/api/cgv/theaters': {
6
+ get: {
7
+ operationId: 'cgvFindTheaters',
8
+ summary: 'CGV 극장 목록 조회',
9
+ description: '날짜/지역 코드 조건으로 CGV 극장 목록을 조회합니다.',
10
+ parameters: [
11
+ {
12
+ name: 'playDate',
13
+ in: 'query',
14
+ required: false,
15
+ description: '조회 날짜 (YYYYMMDD)',
16
+ schema: { type: 'string', example: '20260304' },
17
+ },
18
+ {
19
+ name: 'regionCode',
20
+ in: 'query',
21
+ required: false,
22
+ description: '지역 코드 (예: 01 서울)',
23
+ schema: { type: 'string', example: '01' },
24
+ },
25
+ {
26
+ name: 'limit',
27
+ in: 'query',
28
+ required: false,
29
+ description: '최대 결과 수',
30
+ schema: { type: 'integer', default: 30, minimum: 1, maximum: 100 },
31
+ },
32
+ ],
33
+ responses: {
34
+ '200': {
35
+ description: '조회 성공',
36
+ content: {
37
+ 'application/json': {
38
+ schema: { $ref: '#/components/schemas/CgvTheaterSearchResponse' },
39
+ },
40
+ },
41
+ },
42
+ '500': {
43
+ description: 'CGV API 호출 실패',
44
+ content: {
45
+ 'application/json': {
46
+ schema: { $ref: '#/components/schemas/ErrorResponse' },
47
+ },
48
+ },
49
+ },
50
+ },
51
+ },
52
+ },
53
+ '/api/cgv/movies': {
54
+ get: {
55
+ operationId: 'cgvSearchMovies',
56
+ summary: 'CGV 영화 목록 조회',
57
+ description: '날짜/극장 조건으로 CGV 영화 목록을 조회합니다.',
58
+ parameters: [
59
+ {
60
+ name: 'playDate',
61
+ in: 'query',
62
+ required: false,
63
+ description: '조회 날짜 (YYYYMMDD)',
64
+ schema: { type: 'string', example: '20260304' },
65
+ },
66
+ {
67
+ name: 'theaterCode',
68
+ in: 'query',
69
+ required: false,
70
+ description: '극장 코드 (예: 0056)',
71
+ schema: { type: 'string', example: '0056' },
72
+ },
73
+ ],
74
+ responses: {
75
+ '200': {
76
+ description: '조회 성공',
77
+ content: {
78
+ 'application/json': {
79
+ schema: { $ref: '#/components/schemas/CgvMovieSearchResponse' },
80
+ },
81
+ },
82
+ },
83
+ '500': {
84
+ description: 'CGV API 호출 실패',
85
+ content: {
86
+ 'application/json': {
87
+ schema: { $ref: '#/components/schemas/ErrorResponse' },
88
+ },
89
+ },
90
+ },
91
+ },
92
+ },
93
+ },
94
+ '/api/cgv/timetable': {
95
+ get: {
96
+ operationId: 'cgvGetTimetable',
97
+ summary: 'CGV 시간표 조회',
98
+ description: '날짜/극장/영화 조건으로 CGV 상영 시간표를 조회합니다.',
99
+ parameters: [
100
+ {
101
+ name: 'playDate',
102
+ in: 'query',
103
+ required: false,
104
+ description: '조회 날짜 (YYYYMMDD)',
105
+ schema: { type: 'string', example: '20260304' },
106
+ },
107
+ {
108
+ name: 'theaterCode',
109
+ in: 'query',
110
+ required: false,
111
+ description: '극장 코드',
112
+ schema: { type: 'string' },
113
+ },
114
+ {
115
+ name: 'movieCode',
116
+ in: 'query',
117
+ required: false,
118
+ description: '영화 코드',
119
+ schema: { type: 'string' },
120
+ },
121
+ {
122
+ name: 'limit',
123
+ in: 'query',
124
+ required: false,
125
+ description: '최대 결과 수',
126
+ schema: { type: 'integer', default: 50, minimum: 1, maximum: 200 },
127
+ },
128
+ ],
129
+ responses: {
130
+ '200': {
131
+ description: '조회 성공',
132
+ content: {
133
+ 'application/json': {
134
+ schema: { $ref: '#/components/schemas/CgvTimetableResponse' },
135
+ },
136
+ },
137
+ },
138
+ '500': {
139
+ description: 'CGV API 호출 실패',
140
+ content: {
141
+ 'application/json': {
142
+ schema: { $ref: '#/components/schemas/ErrorResponse' },
143
+ },
144
+ },
145
+ },
146
+ },
147
+ },
148
+ },
149
+ };