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,97 @@
"""Review API routes."""
from __future__ import annotations
from datetime import date
from typing import Optional
from fastapi import APIRouter, Depends, HTTPException, Query
from pydantic import BaseModel, Field
from core import review
from api.deps import get_current_user
router = APIRouter()
class ReviewCreate(BaseModel):
rating: float = Field(..., ge=0.5, le=5.0)
review_text: Optional[str] = None
visited_at: Optional[date] = None
class ReviewUpdate(BaseModel):
rating: Optional[float] = Field(None, ge=0.5, le=5.0)
review_text: Optional[str] = None
visited_at: Optional[date] = None
# --- Restaurant reviews ---
@router.get("/restaurants/{restaurant_id}/reviews")
def list_restaurant_reviews(
restaurant_id: str,
limit: int = Query(20, le=100),
offset: int = Query(0, ge=0),
):
"""List reviews for a restaurant (public)."""
reviews = review.get_reviews_for_restaurant(restaurant_id, limit=limit, offset=offset)
stats = review.get_restaurant_avg_rating(restaurant_id)
return {"reviews": reviews, **stats}
@router.post("/restaurants/{restaurant_id}/reviews", status_code=201)
def create_restaurant_review(
restaurant_id: str,
body: ReviewCreate,
current_user: dict = Depends(get_current_user),
):
"""Create a review for a restaurant (requires auth)."""
created = review.create_review(
user_id=current_user["sub"],
restaurant_id=restaurant_id,
rating=body.rating,
review_text=body.review_text,
visited_at=body.visited_at,
)
return created
@router.put("/reviews/{review_id}")
def update_review_route(
review_id: str,
body: ReviewUpdate,
current_user: dict = Depends(get_current_user),
):
"""Update a review (own review only)."""
updated = review.update_review(
review_id=review_id,
user_id=current_user["sub"],
rating=body.rating,
review_text=body.review_text,
visited_at=body.visited_at,
)
if not updated:
raise HTTPException(404, "Review not found or not yours")
return updated
@router.delete("/reviews/{review_id}", status_code=204)
def delete_review_route(
review_id: str,
current_user: dict = Depends(get_current_user),
):
"""Delete a review (own review only)."""
deleted = review.delete_review(review_id, current_user["sub"])
if not deleted:
raise HTTPException(404, "Review not found or not yours")
@router.get("/users/me/reviews")
def list_my_reviews(
limit: int = Query(20, le=100),
offset: int = Query(0, ge=0),
current_user: dict = Depends(get_current_user),
):
"""List current user's reviews."""
return review.get_user_reviews(current_user["sub"], limit=limit, offset=offset)