"""Targets router (spec §3.4). Thin handlers — business logic in services/targets.py.""" from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.orm import Session from database import get_db from schemas import TargetCreate, TargetRead, TargetUpdate from services import targets as svc router = APIRouter(prefix="/api/targets", tags=["targets"]) @router.get("", response_model=list[TargetRead]) def list_targets(db: Session = Depends(get_db)): return svc.list_targets(db) @router.get("/current", response_model=TargetRead) def current_target(db: Session = Depends(get_db)): target = svc.get_current_target(db) if target is None: raise HTTPException(status_code=404, detail="No active target") return target @router.post("", response_model=TargetRead, status_code=201) def create_target(data: TargetCreate, db: Session = Depends(get_db)): """Create a new target. Auto-closes the previous active target.""" try: return svc.create_target(db, data) except ValueError as e: raise HTTPException(status_code=422, detail=str(e)) @router.put("/{target_id}", response_model=TargetRead) def update_target(target_id: int, data: TargetUpdate, db: Session = Depends(get_db)): """Update a target's values and/or date range. The single-active-target invariant is preserved.""" try: result = svc.update_target(db, target_id, data) except ValueError as e: raise HTTPException(status_code=422, detail=str(e)) except svc.ActiveTargetConflictError as e: raise HTTPException(status_code=409, detail=str(e)) if result is None: raise HTTPException(status_code=404, detail="Target not found") return result