from datetime import date from typing import Optional from fastapi import APIRouter, Depends, HTTPException from sqlalchemy import select from sqlalchemy.exc import IntegrityError from sqlalchemy.orm import Session from database import get_db from models import FlockHistory, User from schemas import FlockHistoryCreate, FlockHistoryUpdate, FlockHistoryOut from auth import get_current_user router = APIRouter(prefix="/api/flock", tags=["flock"]) @router.get("", response_model=list[FlockHistoryOut]) def list_flock_history( db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): q = ( select(FlockHistory) .where(FlockHistory.user_id == current_user.id) .order_by(FlockHistory.date.desc()) .limit(500) ) return db.scalars(q).all() @router.get("/current", response_model=Optional[FlockHistoryOut]) def get_current_flock( db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): q = ( select(FlockHistory) .where(FlockHistory.user_id == current_user.id) .order_by(FlockHistory.date.desc()) .limit(1) ) return db.scalars(q).first() @router.get("/at/{target_date}", response_model=Optional[FlockHistoryOut]) def get_flock_at_date( target_date: date, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): q = ( select(FlockHistory) .where(FlockHistory.user_id == current_user.id) .where(FlockHistory.date <= target_date) .order_by(FlockHistory.date.desc()) .limit(1) ) return db.scalars(q).first() @router.post("", response_model=FlockHistoryOut, status_code=201) def create_flock_entry( body: FlockHistoryCreate, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): record = FlockHistory(**body.model_dump(), user_id=current_user.id) db.add(record) try: db.commit() except IntegrityError: db.rollback() raise HTTPException(status_code=409, detail=f"A flock entry for {body.date} already exists.") db.refresh(record) return record @router.put("/{record_id}", response_model=FlockHistoryOut) def update_flock_entry( record_id: int, body: FlockHistoryUpdate, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): record = db.scalars( select(FlockHistory) .where(FlockHistory.id == record_id, FlockHistory.user_id == current_user.id) ).first() if not record: raise HTTPException(status_code=404, detail="Record not found") for field, value in body.model_dump(exclude_none=True).items(): setattr(record, field, value) try: db.commit() except IntegrityError: db.rollback() raise HTTPException(status_code=409, detail="A flock entry for that date already exists.") db.refresh(record) return record @router.delete("/{record_id}", status_code=204) def delete_flock_entry( record_id: int, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ): record = db.scalars( select(FlockHistory) .where(FlockHistory.id == record_id, FlockHistory.user_id == current_user.id) ).first() if not record: raise HTTPException(status_code=404, detail="Record not found") db.delete(record) db.commit()