Initial commit: Tasteby - YouTube restaurant map service

Backend (FastAPI + Oracle ADB), Frontend (Next.js), daemon worker.
Features: channel/video/restaurant management, semantic search,
Google OAuth, user reviews.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
joungmin
2026-03-06 13:47:19 +09:00
commit 36bec10bd0
54 changed files with 9727 additions and 0 deletions

View File

@@ -0,0 +1,52 @@
"""Video API routes."""
from fastapi import APIRouter, Query
from core.db import conn
from core.pipeline import process_pending
router = APIRouter()
@router.get("")
def list_videos(
status: str | None = None,
limit: int = Query(50, le=200),
offset: int = Query(0, ge=0),
):
conditions = []
params: dict = {"lim": limit, "off": offset}
if status:
conditions.append("v.status = :st")
params["st"] = status
where = ("WHERE " + " AND ".join(conditions)) if conditions else ""
sql = f"""
SELECT v.id, v.video_id, v.title, v.url, v.status,
v.published_at, c.channel_name
FROM videos v
JOIN channels c ON c.id = v.channel_id
{where}
ORDER BY v.published_at DESC NULLS LAST
OFFSET :off ROWS FETCH NEXT :lim ROWS ONLY
"""
with conn() as c:
cur = c.cursor()
cur.execute(sql, params)
cols = [d[0].lower() for d in cur.description]
rows = cur.fetchall()
results = []
for row in rows:
d = dict(zip(cols, row))
if d.get("published_at"):
d["published_at"] = d["published_at"].isoformat()
results.append(d)
return results
@router.post("/process")
def trigger_processing(limit: int = Query(5, le=20)):
"""Manually trigger processing of pending videos."""
count = process_pending(limit)
return {"restaurants_extracted": count}