"""``POST /reservations``、``GET /reservations``(T-P3-22 预约留资)。 topic 预留通用性,首期只有 full_report(全面报告上线提醒)。 幂等口径:重复预约返回已有记录(created=false,HTTP 仍 200)。 """ from __future__ import annotations from typing import Annotated from fastapi import APIRouter, Depends, Query from apps.api.deps import CurrentUserId, SessionDep from packages.report.reservation_service import ReservationService from packages.report.schemas import ( ReservationCreateRequest, ReservationListResponse, ReservationResponse, ) from packages.shared.response import ok router = APIRouter(prefix="/reservations", tags=["reservations"]) def reservation_service_dep(session: SessionDep) -> ReservationService: return ReservationService(session) ReservationServiceDep = Annotated[ReservationService, Depends(reservation_service_dep)] @router.post("", summary="预约留资(幂等:重复预约 created=false)") async def create_reservation( payload: ReservationCreateRequest, user_id: CurrentUserId, service: ReservationServiceDep, ) -> dict[str, object]: result = await service.reserve(user_id=user_id, topic=payload.topic) return ok( ReservationResponse( topic=result.reservation.topic, created=result.created, created_at=result.reservation.created_at, ).model_dump() ) @router.get("", summary="我的预约主题列表(topic 可选,缺省返回全部)") async def list_reservations( user_id: CurrentUserId, service: ReservationServiceDep, topic: str | None = Query(default=None, max_length=32), ) -> dict[str, object]: topics = await service.list_topics(user_id=user_id, topic=topic) return ok(ReservationListResponse(topics=topics).model_dump())