"""签到 endpoint。 路由前缀 `/api/v1/signin`: GET /status 今日签到状态 + 14 天档位 POST / 执行今日签到 POST /boost 签到后看广告膨胀金币 """ from __future__ import annotations import logging from fastapi import APIRouter, HTTPException, status from app.api.deps import CurrentUser, DbSession from app.repositories import signin as crud_signin from app.schemas.welfare import ( SigninBoostRequest, SigninBoostResultOut, SigninResultOut, SigninStatusOut, ) logger = logging.getLogger("shagua.signin") router = APIRouter(prefix="/api/v1/signin", tags=["signin"]) @router.get("/status", response_model=SigninStatusOut, summary="今日签到状态") def signin_status(user: CurrentUser, db: DbSession) -> SigninStatusOut: st = crud_signin.get_status(db, user.id) return SigninStatusOut.model_validate(st, from_attributes=True) @router.post("", response_model=SigninResultOut, summary="执行今日签到") def do_signin(user: CurrentUser, db: DbSession) -> SigninResultOut: try: record, balance = crud_signin.do_signin(db, user.id) except crud_signin.AlreadySignedError as e: raise HTTPException(status_code=status.HTTP_409_CONFLICT, detail="already signed today") from e logger.info( "signin ok user_id=%d day=%d streak=%d coin=%d", user.id, record.cycle_day, record.streak, record.coin_awarded, ) return SigninResultOut( coin_awarded=record.coin_awarded, cycle_day=record.cycle_day, streak=record.streak, coin_balance=balance, ) @router.post("/boost", response_model=SigninBoostResultOut, summary="签到后看广告膨胀金币") def boost_signin( payload: SigninBoostRequest, user: CurrentUser, db: DbSession ) -> SigninBoostResultOut: try: record, balance = crud_signin.boost_today_signin( db, user.id, ad_ref_id=payload.ad_ref_id ) except crud_signin.NotSignedTodayError as e: raise HTTPException(status_code=status.HTTP_409_CONFLICT, detail="not signed today") from e except crud_signin.AlreadyBoostedError as e: raise HTTPException(status_code=status.HTTP_409_CONFLICT, detail="already boosted today") from e logger.info( "signin boost ok user_id=%d date=%s coin=%d", user.id, record.signin_date, record.coin_awarded, ) return SigninBoostResultOut( coin_awarded=record.coin_awarded, coin_balance=balance, signin_date=record.signin_date.isoformat(), )