feat(lotto): briefing CRUD + 큐레이터 사용량 라우터
This commit is contained in:
53
backend/app/routers/briefing.py
Normal file
53
backend/app/routers/briefing.py
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
"""브리핑 저장/조회 + 큐레이터 사용량 엔드포인트."""
|
||||||
|
from typing import Any, Dict, List
|
||||||
|
from fastapi import APIRouter, HTTPException
|
||||||
|
from pydantic import BaseModel, Field
|
||||||
|
from .. import db
|
||||||
|
|
||||||
|
router = APIRouter(prefix="/api/lotto")
|
||||||
|
|
||||||
|
|
||||||
|
class BriefingRequest(BaseModel):
|
||||||
|
draw_no: int
|
||||||
|
picks: List[Dict[str, Any]]
|
||||||
|
narrative: Dict[str, Any]
|
||||||
|
confidence: int = Field(ge=0, le=100)
|
||||||
|
model: str
|
||||||
|
tokens_input: int = 0
|
||||||
|
tokens_output: int = 0
|
||||||
|
cache_read: int = 0
|
||||||
|
cache_write: int = 0
|
||||||
|
latency_ms: int = 0
|
||||||
|
source: str = "auto"
|
||||||
|
|
||||||
|
|
||||||
|
@router.post("/briefing", status_code=201)
|
||||||
|
def save_briefing(body: BriefingRequest):
|
||||||
|
bid = db.save_briefing(body.model_dump())
|
||||||
|
return {"ok": True, "id": bid}
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/briefing/latest")
|
||||||
|
def latest():
|
||||||
|
b = db.get_latest_briefing()
|
||||||
|
if not b:
|
||||||
|
raise HTTPException(404, "no briefing yet")
|
||||||
|
return b
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/briefing/{draw_no}")
|
||||||
|
def get_one(draw_no: int):
|
||||||
|
b = db.get_briefing(draw_no)
|
||||||
|
if not b:
|
||||||
|
raise HTTPException(404, f"no briefing for draw {draw_no}")
|
||||||
|
return b
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/briefing")
|
||||||
|
def history(limit: int = 10):
|
||||||
|
return {"briefings": db.list_briefings(limit)}
|
||||||
|
|
||||||
|
|
||||||
|
@router.get("/curator/usage")
|
||||||
|
def usage(days: int = 30):
|
||||||
|
return db.get_curator_usage(days)
|
||||||
Reference in New Issue
Block a user