daiso 1.0.6 → 1.0.8

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 (42) hide show
  1. package/README.md +83 -4
  2. package/dist/api/actionsProxy.js +116 -21
  3. package/dist/api/compareHandlers.js +26 -0
  4. package/dist/api/configStatus.js +5 -1
  5. package/dist/api/gs25Handlers.js +45 -10
  6. package/dist/api/healthChecks.js +50 -9
  7. package/dist/api/placesHandlers.js +44 -0
  8. package/dist/api/routes/compareRoutes.js +9 -0
  9. package/dist/api/routes/healthRoutes.js +1 -1
  10. package/dist/api/routes/placesRoutes.js +9 -0
  11. package/dist/cli/commandOptions.js +65 -6
  12. package/dist/cli/commands/convenience.js +38 -0
  13. package/dist/cli.js +5 -1
  14. package/dist/cliHelp.js +25 -6
  15. package/dist/cliRenderer.js +24 -2
  16. package/dist/core/registry.js +33 -2
  17. package/dist/index.js +22 -3
  18. package/dist/pages/openapiFullSpec.js +6 -0
  19. package/dist/pages/openapiSpecActions.js +315 -42
  20. package/dist/pages/openapiSpecPathsCompare.js +59 -0
  21. package/dist/pages/openapiSpecPathsPlaces.js +85 -0
  22. package/dist/pages/promptReferenceText.js +5 -0
  23. package/dist/pages/promptRetailCinemaText.js +41 -3
  24. package/dist/services/compare/client.js +133 -0
  25. package/dist/services/compare/index.js +17 -0
  26. package/dist/services/compare/tools/compareProducts.js +45 -0
  27. package/dist/services/compare/types.js +1 -0
  28. package/dist/services/gs25/api.js +3 -0
  29. package/dist/services/gs25/client.js +211 -35
  30. package/dist/services/gs25/index.js +11 -3
  31. package/dist/services/gs25/tools/checkInventory.js +39 -12
  32. package/dist/services/gs25/tools/findNearbyStores.js +19 -5
  33. package/dist/services/gs25/tools/searchProducts.js +11 -4
  34. package/dist/services/oliveyoung/client.js +90 -41
  35. package/dist/services/places/client.js +116 -0
  36. package/dist/services/places/index.js +23 -0
  37. package/dist/services/places/tools/searchNearby.js +56 -0
  38. package/dist/services/places/types.js +1 -0
  39. package/dist/utils/zyte.js +45 -18
  40. package/openapi.json +29 -0
  41. package/openapi.yaml +20 -0
  42. package/package.json +3 -2
@@ -14,48 +14,321 @@ const ACTION_QUERY_PARAMETERS = [
14
14
  enum: ACTION_QUERY_ACTIONS,
15
15
  },
16
16
  },
17
- { name: 'q', in: 'query', required: false, description: '다이소 제품 검색어', schema: { type: 'string' } },
18
- { name: 'query', in: 'query', required: false, description: '세븐일레븐 상품 검색어', schema: { type: 'string' } },
19
- { name: 'itemCode', in: 'query', required: false, description: 'GS25 상품 코드', schema: { type: 'string' } },
20
- { name: 'productId', in: 'query', required: false, description: '제품 ID 또는 상세 조회용 path 파라미터. 상품명만 알면 먼저 daisoSearchProducts 또는 /api/daiso/products로 productId를 확인하세요.', schema: { type: 'string' } },
21
- { name: 'keyword', in: 'query', required: false, description: '공통 키워드 파라미터', schema: { type: 'string' } },
22
- { name: 'sido', in: 'query', required: false, description: '다이소 시/도', schema: { type: 'string' } },
23
- { name: 'gugun', in: 'query', required: false, description: '다이소 구/군', schema: { type: 'string' } },
24
- { name: 'dong', in: 'query', required: false, description: '다이소 동', schema: { type: 'string' } },
25
- { name: 'area', in: 'query', required: false, description: '롯데마트 지역', schema: { type: 'string' } },
26
- { name: 'area1', in: 'query', required: false, description: '이마트24 1차 지역', schema: { type: 'string' } },
27
- { name: 'area2', in: 'query', required: false, description: '이마트24 2차 지역', schema: { type: 'string' } },
28
- { name: 'areaCode', in: 'query', required: false, description: '메가박스 지역 코드', schema: { type: 'string' } },
29
- { name: 'brandVariant', in: 'query', required: false, description: '롯데마트 브랜드 변형', schema: { type: 'string' } },
30
- { name: 'lat', in: 'query', required: false, description: '위도', schema: { type: 'number', format: 'float' } },
31
- { name: 'lng', in: 'query', required: false, description: '경도', schema: { type: 'number', format: 'float' } },
32
- { name: 'page', in: 'query', required: false, description: '페이지 번호', schema: { type: 'integer' } },
33
- { name: 'pageIdx', in: 'query', required: false, description: '올리브영 페이지 번호', schema: { type: 'integer' } },
34
- { name: 'pageLimit', in: 'query', required: false, description: '롯데마트 추가 페이지 수', schema: { type: 'integer' } },
35
- { name: 'pageSize', in: 'query', required: false, description: '페이지 크기', schema: { type: 'integer' } },
36
- { name: 'size', in: 'query', required: false, description: '페이지 크기 또는 검색 크기', schema: { type: 'integer' } },
37
- { name: 'offset', in: 'query', required: false, description: 'CU 검색 오프셋', schema: { type: 'integer' } },
38
- { name: 'limit', in: 'query', required: false, description: '최대 결과 수', schema: { type: 'integer' } },
39
- { name: 'storeLimit', in: 'query', required: false, description: '매장 결과 제한 수', schema: { type: 'integer' } },
40
- { name: 'storeCode', in: 'query', required: false, description: '매장 코드. 다이소 진열 위치는 /api/daiso/inventory 응답의 storeInventory.stores[].storeCode에서 확인하세요.', schema: { type: 'string' } },
41
- { name: 'storeName', in: 'query', required: false, description: '매장명. 롯데마트 상품 조회에서 storeCode가 없을 때 사용하며, 모르면 먼저 lottemartFindNearbyStores 또는 /api/lottemart/stores로 확인하세요.', schema: { type: 'string' } },
42
- { name: 'storeKeyword', in: 'query', required: false, description: '매장 키워드', schema: { type: 'string' } },
43
- { name: 'playDate', in: 'query', required: false, description: '상영일(YYYYMMDD)', schema: { type: 'string' } },
44
- { name: 'regionCode', in: 'query', required: false, description: 'CGV 지역 코드', schema: { type: 'string' } },
45
- { name: 'theaterCode', in: 'query', required: false, description: 'CGV 극장 코드', schema: { type: 'string' } },
46
- { name: 'theaterId', in: 'query', required: false, description: '메가박스/롯데시네마 지점 ID', schema: { type: 'string' } },
47
- { name: 'movieCode', in: 'query', required: false, description: 'CGV 영화 코드', schema: { type: 'string' } },
48
- { name: 'movieId', in: 'query', required: false, description: '메가박스/롯데시네마 영화 ID', schema: { type: 'string' } },
49
- { name: 'pluCd', in: 'query', required: false, description: '이마트24 상품 PLU 코드', schema: { type: 'string' } },
50
- { name: 'bizNoArr', in: 'query', required: false, description: '이마트24 사업자번호 목록', schema: { type: 'string' } },
51
- { name: 'label', in: 'query', required: false, description: '세븐일레븐 인기 검색어 라벨', schema: { type: 'string' } },
52
- { name: 'sort', in: 'query', required: false, description: '정렬 기준', schema: { type: 'string' } },
53
- { name: 'searchSort', in: 'query', required: false, description: 'CU 검색 정렬 기준', schema: { type: 'string' } },
54
- { name: 'service24h', in: 'query', required: false, description: '이마트24 24시간 필터', schema: { type: 'boolean' } },
55
- { name: 'includeSoldOut', in: 'query', required: false, description: '올리브영 품절 포함 여부', schema: { type: 'boolean' } },
56
- { name: 'includeIssues', in: 'query', required: false, description: '세븐일레븐 이달의 행사지 포함 여부', schema: { type: 'boolean' } },
57
- { name: 'includeExhibition', in: 'query', required: false, description: '세븐일레븐 전시상품 포함 여부', schema: { type: 'boolean' } },
58
- { name: 'timeoutMs', in: 'query', required: false, description: '세븐일레븐 inventory 타임아웃', schema: { type: 'integer' } },
17
+ {
18
+ name: 'q',
19
+ in: 'query',
20
+ required: false,
21
+ description: '다이소 제품 검색어',
22
+ schema: { type: 'string' },
23
+ },
24
+ {
25
+ name: 'query',
26
+ in: 'query',
27
+ required: false,
28
+ description: '세븐일레븐 상품 검색어',
29
+ schema: { type: 'string' },
30
+ },
31
+ {
32
+ name: 'itemCode',
33
+ in: 'query',
34
+ required: false,
35
+ description: 'GS25 상품 코드',
36
+ schema: { type: 'string' },
37
+ },
38
+ {
39
+ name: 'productId',
40
+ in: 'query',
41
+ required: false,
42
+ description: '제품 ID 또는 상세 조회용 path 파라미터. 상품명만 알면 먼저 daisoSearchProducts 또는 /api/daiso/products로 productId를 확인하세요.',
43
+ schema: { type: 'string' },
44
+ },
45
+ {
46
+ name: 'keyword',
47
+ in: 'query',
48
+ required: false,
49
+ description: '공통 키워드 파라미터',
50
+ schema: { type: 'string' },
51
+ },
52
+ {
53
+ name: 'location',
54
+ in: 'query',
55
+ required: false,
56
+ description: '주변 장소 검색 지역/역/주소 키워드',
57
+ schema: { type: 'string' },
58
+ },
59
+ {
60
+ name: 'category',
61
+ in: 'query',
62
+ required: false,
63
+ description: '주변 장소 카테고리(restaurant, cafe, food, dessert, all)',
64
+ schema: { type: 'string' },
65
+ },
66
+ {
67
+ name: 'services',
68
+ in: 'query',
69
+ required: false,
70
+ description: '통합 비교 서비스 목록(daiso,gs25,seveneleven,emart24)',
71
+ schema: { type: 'string' },
72
+ },
73
+ {
74
+ name: 'sido',
75
+ in: 'query',
76
+ required: false,
77
+ description: '다이소 시/도',
78
+ schema: { type: 'string' },
79
+ },
80
+ {
81
+ name: 'gugun',
82
+ in: 'query',
83
+ required: false,
84
+ description: '다이소 구/군',
85
+ schema: { type: 'string' },
86
+ },
87
+ {
88
+ name: 'dong',
89
+ in: 'query',
90
+ required: false,
91
+ description: '다이소 동',
92
+ schema: { type: 'string' },
93
+ },
94
+ {
95
+ name: 'area',
96
+ in: 'query',
97
+ required: false,
98
+ description: '롯데마트 지역',
99
+ schema: { type: 'string' },
100
+ },
101
+ {
102
+ name: 'area1',
103
+ in: 'query',
104
+ required: false,
105
+ description: '이마트24 1차 지역',
106
+ schema: { type: 'string' },
107
+ },
108
+ {
109
+ name: 'area2',
110
+ in: 'query',
111
+ required: false,
112
+ description: '이마트24 2차 지역',
113
+ schema: { type: 'string' },
114
+ },
115
+ {
116
+ name: 'areaCode',
117
+ in: 'query',
118
+ required: false,
119
+ description: '메가박스 지역 코드',
120
+ schema: { type: 'string' },
121
+ },
122
+ {
123
+ name: 'brandVariant',
124
+ in: 'query',
125
+ required: false,
126
+ description: '롯데마트 브랜드 변형',
127
+ schema: { type: 'string' },
128
+ },
129
+ {
130
+ name: 'lat',
131
+ in: 'query',
132
+ required: false,
133
+ description: '위도',
134
+ schema: { type: 'number', format: 'float' },
135
+ },
136
+ {
137
+ name: 'lng',
138
+ in: 'query',
139
+ required: false,
140
+ description: '경도',
141
+ schema: { type: 'number', format: 'float' },
142
+ },
143
+ {
144
+ name: 'page',
145
+ in: 'query',
146
+ required: false,
147
+ description: '페이지 번호',
148
+ schema: { type: 'integer' },
149
+ },
150
+ {
151
+ name: 'pageIdx',
152
+ in: 'query',
153
+ required: false,
154
+ description: '올리브영 페이지 번호',
155
+ schema: { type: 'integer' },
156
+ },
157
+ {
158
+ name: 'pageLimit',
159
+ in: 'query',
160
+ required: false,
161
+ description: '롯데마트 추가 페이지 수',
162
+ schema: { type: 'integer' },
163
+ },
164
+ {
165
+ name: 'pageSize',
166
+ in: 'query',
167
+ required: false,
168
+ description: '페이지 크기',
169
+ schema: { type: 'integer' },
170
+ },
171
+ {
172
+ name: 'size',
173
+ in: 'query',
174
+ required: false,
175
+ description: '페이지 크기 또는 검색 크기',
176
+ schema: { type: 'integer' },
177
+ },
178
+ {
179
+ name: 'offset',
180
+ in: 'query',
181
+ required: false,
182
+ description: 'CU 검색 오프셋',
183
+ schema: { type: 'integer' },
184
+ },
185
+ {
186
+ name: 'limit',
187
+ in: 'query',
188
+ required: false,
189
+ description: '최대 결과 수',
190
+ schema: { type: 'integer' },
191
+ },
192
+ {
193
+ name: 'storeLimit',
194
+ in: 'query',
195
+ required: false,
196
+ description: '매장 결과 제한 수',
197
+ schema: { type: 'integer' },
198
+ },
199
+ {
200
+ name: 'storeCode',
201
+ in: 'query',
202
+ required: false,
203
+ description: '매장 코드. 다이소 진열 위치는 /api/daiso/inventory 응답의 storeInventory.stores[].storeCode에서 확인하세요.',
204
+ schema: { type: 'string' },
205
+ },
206
+ {
207
+ name: 'storeName',
208
+ in: 'query',
209
+ required: false,
210
+ description: '매장명. 롯데마트 상품 조회에서 storeCode가 없을 때 사용하며, 모르면 먼저 lottemartFindNearbyStores 또는 /api/lottemart/stores로 확인하세요.',
211
+ schema: { type: 'string' },
212
+ },
213
+ {
214
+ name: 'storeKeyword',
215
+ in: 'query',
216
+ required: false,
217
+ description: '매장 키워드',
218
+ schema: { type: 'string' },
219
+ },
220
+ {
221
+ name: 'playDate',
222
+ in: 'query',
223
+ required: false,
224
+ description: '상영일(YYYYMMDD)',
225
+ schema: { type: 'string' },
226
+ },
227
+ {
228
+ name: 'regionCode',
229
+ in: 'query',
230
+ required: false,
231
+ description: 'CGV 지역 코드',
232
+ schema: { type: 'string' },
233
+ },
234
+ {
235
+ name: 'theaterCode',
236
+ in: 'query',
237
+ required: false,
238
+ description: 'CGV 극장 코드',
239
+ schema: { type: 'string' },
240
+ },
241
+ {
242
+ name: 'theaterId',
243
+ in: 'query',
244
+ required: false,
245
+ description: '메가박스/롯데시네마 지점 ID',
246
+ schema: { type: 'string' },
247
+ },
248
+ {
249
+ name: 'movieCode',
250
+ in: 'query',
251
+ required: false,
252
+ description: 'CGV 영화 코드',
253
+ schema: { type: 'string' },
254
+ },
255
+ {
256
+ name: 'movieId',
257
+ in: 'query',
258
+ required: false,
259
+ description: '메가박스/롯데시네마 영화 ID',
260
+ schema: { type: 'string' },
261
+ },
262
+ {
263
+ name: 'pluCd',
264
+ in: 'query',
265
+ required: false,
266
+ description: '이마트24 상품 PLU 코드',
267
+ schema: { type: 'string' },
268
+ },
269
+ {
270
+ name: 'bizNoArr',
271
+ in: 'query',
272
+ required: false,
273
+ description: '이마트24 사업자번호 목록',
274
+ schema: { type: 'string' },
275
+ },
276
+ {
277
+ name: 'label',
278
+ in: 'query',
279
+ required: false,
280
+ description: '세븐일레븐 인기 검색어 라벨',
281
+ schema: { type: 'string' },
282
+ },
283
+ {
284
+ name: 'sort',
285
+ in: 'query',
286
+ required: false,
287
+ description: '정렬 기준',
288
+ schema: { type: 'string' },
289
+ },
290
+ {
291
+ name: 'searchSort',
292
+ in: 'query',
293
+ required: false,
294
+ description: 'CU 검색 정렬 기준',
295
+ schema: { type: 'string' },
296
+ },
297
+ {
298
+ name: 'service24h',
299
+ in: 'query',
300
+ required: false,
301
+ description: '이마트24 24시간 필터',
302
+ schema: { type: 'boolean' },
303
+ },
304
+ {
305
+ name: 'includeSoldOut',
306
+ in: 'query',
307
+ required: false,
308
+ description: '올리브영 품절 포함 여부',
309
+ schema: { type: 'boolean' },
310
+ },
311
+ {
312
+ name: 'includeIssues',
313
+ in: 'query',
314
+ required: false,
315
+ description: '세븐일레븐 이달의 행사지 포함 여부',
316
+ schema: { type: 'boolean' },
317
+ },
318
+ {
319
+ name: 'includeExhibition',
320
+ in: 'query',
321
+ required: false,
322
+ description: '세븐일레븐 전시상품 포함 여부',
323
+ schema: { type: 'boolean' },
324
+ },
325
+ {
326
+ name: 'timeoutMs',
327
+ in: 'query',
328
+ required: false,
329
+ description: '세븐일레븐 inventory 타임아웃',
330
+ schema: { type: 'integer' },
331
+ },
59
332
  ];
60
333
  export function generateOpenApiSpec(baseUrl) {
61
334
  return {
@@ -0,0 +1,59 @@
1
+ export const OPENAPI_PATHS_COMPARE = {
2
+ '/api/compare/products': {
3
+ get: {
4
+ operationId: 'compareProducts',
5
+ summary: '키 없는 통합 상품 가격 후보 비교',
6
+ description: '새 외부 키 없이 다이소, GS25, 세븐일레븐, 이마트24 상품 검색을 묶어 가격 후보를 비교합니다.',
7
+ parameters: [
8
+ {
9
+ name: 'keyword',
10
+ in: 'query',
11
+ required: true,
12
+ description: '비교할 상품 검색어',
13
+ schema: { type: 'string' },
14
+ },
15
+ {
16
+ name: 'services',
17
+ in: 'query',
18
+ required: false,
19
+ description: '쉼표로 구분한 서비스 목록(daiso,gs25,seveneleven,emart24)',
20
+ schema: { type: 'string' },
21
+ },
22
+ {
23
+ name: 'limit',
24
+ in: 'query',
25
+ required: false,
26
+ description: '서비스별 최대 결과 수',
27
+ schema: { type: 'integer', default: 5, minimum: 1, maximum: 20 },
28
+ },
29
+ ],
30
+ responses: {
31
+ '200': {
32
+ description: '통합 상품 가격 후보 비교 결과',
33
+ content: {
34
+ 'application/json': {
35
+ schema: {
36
+ type: 'object',
37
+ properties: {
38
+ success: { type: 'boolean' },
39
+ data: {
40
+ type: 'object',
41
+ properties: {
42
+ keyword: { type: 'string' },
43
+ serviceCount: { type: 'integer' },
44
+ resultCount: { type: 'integer' },
45
+ bestPrice: { type: ['object', 'null'] },
46
+ results: { type: 'array', items: { type: 'object' } },
47
+ errors: { type: 'array', items: { type: 'object' } },
48
+ note: { type: 'string' },
49
+ },
50
+ },
51
+ },
52
+ },
53
+ },
54
+ },
55
+ },
56
+ },
57
+ },
58
+ },
59
+ };
@@ -0,0 +1,85 @@
1
+ /**
2
+ * OpenAPI 경로 정의 (장소 검색)
3
+ */
4
+ export const OPENAPI_PATHS_PLACES = {
5
+ '/api/places/search': {
6
+ get: {
7
+ operationId: 'placesSearchNearby',
8
+ summary: '음식점/카페 등 주변 장소 검색',
9
+ description: '네이버 지역 검색으로 특정 지역의 음식점, 카페, 디저트 가게 등 주변 장소를 조회합니다. 좌표 반경 검색이 아니라 키워드 기반 검색입니다.',
10
+ parameters: [
11
+ {
12
+ name: 'location',
13
+ in: 'query',
14
+ required: false,
15
+ description: '지역/역/주소 키워드 (예: 강남역, 성수동)',
16
+ schema: { type: 'string' },
17
+ },
18
+ {
19
+ name: 'keyword',
20
+ in: 'query',
21
+ required: false,
22
+ description: '직접 검색어 (예: 라멘, 브런치, 조용한 카페)',
23
+ schema: { type: 'string' },
24
+ },
25
+ {
26
+ name: 'category',
27
+ in: 'query',
28
+ required: false,
29
+ description: '장소 카테고리',
30
+ schema: {
31
+ type: 'string',
32
+ enum: ['restaurant', 'cafe', 'food', 'dessert', 'all'],
33
+ default: 'all',
34
+ },
35
+ },
36
+ {
37
+ name: 'limit',
38
+ in: 'query',
39
+ required: false,
40
+ description: '최대 결과 수',
41
+ schema: { type: 'integer', default: 5, minimum: 1, maximum: 5 },
42
+ },
43
+ {
44
+ name: 'sort',
45
+ in: 'query',
46
+ required: false,
47
+ description: '정렬 방식',
48
+ schema: { type: 'string', enum: ['random', 'comment'], default: 'random' },
49
+ },
50
+ ],
51
+ responses: {
52
+ '200': {
53
+ description: '검색 성공',
54
+ content: {
55
+ 'application/json': {
56
+ schema: {
57
+ type: 'object',
58
+ properties: {
59
+ success: { type: 'boolean' },
60
+ data: {
61
+ type: 'object',
62
+ properties: {
63
+ provider: { type: 'string', example: 'naverLocal' },
64
+ searchMode: { type: 'string', example: 'keyword' },
65
+ query: { type: 'string', example: '강남역 카페' },
66
+ places: { type: 'array', items: { type: 'object' } },
67
+ },
68
+ },
69
+ },
70
+ },
71
+ },
72
+ },
73
+ },
74
+ '400': {
75
+ description: '잘못된 요청 (위치/검색어 누락)',
76
+ content: {
77
+ 'application/json': {
78
+ schema: { $ref: '#/components/schemas/ErrorResponse' },
79
+ },
80
+ },
81
+ },
82
+ },
83
+ },
84
+ },
85
+ };
@@ -57,6 +57,7 @@ export function buildPromptReferenceText(baseUrl) {
57
57
  | LOTTEMART_STORE_SEARCH_FAILED | 롯데마트 매장 조회 실패 |
58
58
  | LOTTEMART_PRODUCT_SEARCH_FAILED | 롯데마트 상품 조회 실패 |
59
59
  | SEVENELEVEN_INVENTORY_CHECK_FAILED | 세븐일레븐 재고 조회 실패 |
60
+ | PLACES_SEARCH_FAILED | 주변 장소 검색 실패 |
60
61
 
61
62
  ---
62
63
 
@@ -97,6 +98,8 @@ export function buildPromptReferenceText(baseUrl) {
97
98
  11. **이마트24 재고 조회**: /api/emart24/inventory는 pluCd + storeKeyword 조합도 지원하므로, 상품 선택 뒤 매장 코드를 다시 모으지 않아도 됩니다.
98
99
  12. **올리브영 재고 해석**: inventory.products[].storeInventory.stores[]가 있으면 그 매장별 stockLabel과 remainQuantity를 우선 사용하고, inStock는 그 주변 매장 기준 결과로 해석합니다.
99
100
  13. **올리브영 상품 이미지 표시**: /api/oliveyoung/products 또는 oliveyoung_search_products 결과에 imageUrl이 있으면 목록형 답변에서도 각 상품 이미지를 생략하지 말고 모두 렌더링합니다. 특히 \`?l=ko\` 같은 query string을 삭제하지 말고 전체 URL 그대로 마크다운 이미지 src에 넣습니다.
101
+ 14. **통합 가격 후보 비교**: 사용자가 브랜드를 특정하지 않고 "어디가 싸?", "비교해줘"처럼 물으면 \`compare_products\` 또는 /api/compare/products를 먼저 사용합니다. 새 외부 키 없이 기존 상품 검색을 묶은 1차 가격 후보이므로 실제 재고/행사가는 각 서비스 상세 조회로 확인해야 합니다.
102
+ 15. **주변 음식점/카페 검색**: 음식점이나 카페만 물으면 \`places_search_nearby\` 또는 /api/places/search를 먼저 사용합니다. 이 기능은 네이버 지역 검색 기반 키워드 검색이므로 좌표 반경 검색처럼 단정하지 말고, \`searchMode: "keyword"\`임을 필요할 때 짧게 밝혀주세요.
100
103
 
101
104
  ---
102
105
 
@@ -121,6 +124,8 @@ MCP 연결 정보: ${baseUrl}/mcp
121
124
  - seveneleven_check_inventory: 세븐일레븐 재고 조회
122
125
  - seveneleven_get_search_popwords: 세븐일레븐 인기 검색어 조회
123
126
  - seveneleven_get_catalog_snapshot: 세븐일레븐 카탈로그 조회
127
+ - compare_products: 키 없는 통합 상품 가격 후보 비교
128
+ - places_search_nearby: 음식점/카페 등 주변 장소 검색
124
129
  - oliveyoung_search_products: 올리브영 상품 검색
125
130
  - oliveyoung_find_nearby_stores: 올리브영 주변 매장 탐색
126
131
  - oliveyoung_check_inventory: 올리브영 재고 파악
@@ -2,7 +2,45 @@
2
2
  * 프롬프트 리테일/영화 API 섹션
3
3
  */
4
4
  export function buildPromptRetailCinemaText(baseUrl) {
5
- return `### 6-1. 롯데마트 매장/상품 조회
5
+ return `### 6-0. 키 없는 통합 상품 가격 후보 비교
6
+
7
+ **설명**: 새 외부 API 키 없이 기존 다이소, GS25, 세븐일레븐, 이마트24 상품 검색을 묶어 가격 후보를 비교합니다. 실제 매장 재고와 행사가까지 확정하는 기능이 아니라 "어디가 싸 보이는지"를 빠르게 고르는 1차 검색입니다.
8
+
9
+ **URL**:
10
+ - ${baseUrl}/api/compare/products?keyword={검색어}
11
+
12
+ **선택 파라미터**:
13
+ - services: daiso,gs25,seveneleven,emart24 중 쉼표 구분 목록
14
+ - limit: 서비스별 최대 결과 수 (기본값: 5)
15
+
16
+ **예시**:
17
+ - ${baseUrl}/api/compare/products?keyword=콜라&limit=3
18
+ - ${baseUrl}/api/compare/products?keyword=컵라면&services=seveneleven,emart24
19
+
20
+ ---
21
+
22
+ ### 6-1. 주변 음식점/카페 검색
23
+
24
+ **설명**: 네이버 지역 검색으로 특정 지역의 음식점, 카페, 디저트 가게 등 주변 장소를 조회합니다. 좌표 반경 검색이 아니라 \`강남역 카페\` 같은 키워드 기반 검색입니다.
25
+
26
+ **URL**:
27
+ - ${baseUrl}/api/places/search?location={지역}&category={카테고리}
28
+ - ${baseUrl}/api/places/search?location={지역}&keyword={검색어}
29
+
30
+ **선택 파라미터**:
31
+ - location: 지역/역/주소 키워드 (예: 강남역, 성수동)
32
+ - category: restaurant, cafe, food, dessert, all
33
+ - keyword: 직접 검색어 (예: 라멘, 브런치, 조용한 카페)
34
+ - limit: 최대 결과 수 (기본값: 5, 네이버 지역 검색 최대 5)
35
+ - sort: random 또는 comment
36
+
37
+ **예시**:
38
+ - ${baseUrl}/api/places/search?location=강남역&category=cafe&limit=5
39
+ - ${baseUrl}/api/places/search?location=성수동&keyword=브런치&limit=5
40
+
41
+ ---
42
+
43
+ ### 6-2. 롯데마트 매장/상품 조회
6
44
 
7
45
  **설명**: 롯데마트 계열 매장 검색과 특정 매장 기준 상품 가격/재고 조회를 제공합니다.
8
46
 
@@ -28,7 +66,7 @@ export function buildPromptRetailCinemaText(baseUrl) {
28
66
 
29
67
  ---
30
68
 
31
- ### 6-2. GS25 매장/상품/재고 조회
69
+ ### 6-3. GS25 매장/상품/재고 조회
32
70
 
33
71
  **설명**: GS25 매장 탐색, 상품 키워드 검색, 재고 조회를 제공합니다.
34
72
 
@@ -52,7 +90,7 @@ export function buildPromptRetailCinemaText(baseUrl) {
52
90
 
53
91
  ---
54
92
 
55
- ### 6-3. 세븐일레븐 상품/매장/재고/인기검색어/카탈로그 조회
93
+ ### 6-4. 세븐일레븐 상품/매장/재고/인기검색어/카탈로그 조회
56
94
 
57
95
  **설명**: 세븐일레븐 상품 검색, 매장 검색, 재고 수량 조회, 인기 검색어, 카탈로그 스냅샷을 제공합니다.
58
96