"""공개 읽기 API — 경기 목록 / 경기 상세 (AI예측 + crowd 포함).""" from __future__ import annotations from fastapi import APIRouter, Depends, HTTPException, Query from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.orm import selectinload from ..database import get_db from ..domain import match_out from ..models import Match from ..schemas import MatchOut router = APIRouter(prefix="/api/matches", tags=["matches"]) @router.get("", response_model=list[MatchOut]) async def list_matches( lang: str = Query("ko"), db: AsyncSession = Depends(get_db), ) -> list[MatchOut]: rows = ( await db.execute( select(Match) .options(selectinload(Match.predictions), selectinload(Match.crowd)) .order_by(Match.kickoff_at) ) ).scalars().all() return [match_out(m, lang) for m in rows] @router.get("/{match_id}", response_model=MatchOut) async def get_match( match_id: str, lang: str = Query("ko"), db: AsyncSession = Depends(get_db), ) -> MatchOut: m = ( await db.execute( select(Match) .where(Match.match_id == match_id) .options(selectinload(Match.predictions), selectinload(Match.crowd)) ) ).scalars().first() if not m: raise HTTPException(status_code=404, detail="MATCH_NOT_FOUND") return match_out(m, lang)