Add food tag remap feature and show menu tags in restaurant cards

- LLM extraction prompt: foods_mentioned max 10, Korean only, prioritized
- New /remap-foods API endpoint for bulk LLM re-extraction
- Admin UI: "메뉴태그 재생성" button with SSE progress bar
- Backend: attach foods_mentioned to restaurant list API response
- Restaurant cards: display food tags (orange, max 5 visible)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
joungmin
2026-03-09 11:21:05 +09:00
parent a5b3598f8a
commit 54d21afd52
6 changed files with 237 additions and 2 deletions

View File

@@ -110,7 +110,7 @@ _EXTRACT_PROMPT = """\
- cuisine_type: 아래 목록에서 가장 적합한 것을 선택 (string, 필수). 반드시 아래 목록 중 하나를 사용:
{cuisine_types}
- price_range: 가격대 (예: 1만원대, 2-3만원) (string | null)
- foods_mentioned: 언급된 메뉴 (string[])
- foods_mentioned: 언급된 대표 메뉴 (string[], 최대 10개, 우선순위 높은 순, 반드시 한글로 작성)
- evaluation: 평가 내용 (string | null)
- guests: 함께한 게스트 (string[])

View File

@@ -314,8 +314,31 @@ def get_all(
for row in cur.fetchall():
ch_map.setdefault(row[0], []).append(row[1])
# Attach aggregated foods_mentioned for each restaurant
foods_sql = f"""
SELECT vr.restaurant_id, vr.foods_mentioned
FROM video_restaurants vr
WHERE vr.restaurant_id IN ({placeholders})
"""
foods_map: dict[str, list[str]] = {}
with conn() as c:
cur = c.cursor()
cur.execute(foods_sql, ch_params)
for row in cur.fetchall():
raw = row[1].read() if hasattr(row[1], "read") else row[1]
if raw:
try:
items = json.loads(raw) if isinstance(raw, str) else raw
if isinstance(items, list):
for f in items:
if isinstance(f, str) and f not in foods_map.get(row[0], []):
foods_map.setdefault(row[0], []).append(f)
except Exception:
pass
for r in restaurants:
r["channels"] = ch_map.get(r["id"], [])
r["foods_mentioned"] = foods_map.get(r["id"], [])[:10]
return restaurants