48 lines
1.4 KiB
Python
48 lines
1.4 KiB
Python
"""공개 읽기 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)
|