5372e8cbca
- GET /api/log/summary?date= with totals vs historical target - Nutrition math consolidated in services/nutrition.py (weight vs count) - Null nutrition contributes 0; meals contribute 0 (TODO TICKET-007) - Full suite green (104 passed)
54 lines
2.1 KiB
Python
54 lines
2.1 KiB
Python
"""Daily log router (spec §3.3). Thin handlers — business logic in services/log.py."""
|
|
|
|
from datetime import date
|
|
|
|
from fastapi import APIRouter, Depends, HTTPException
|
|
from sqlalchemy.orm import Session
|
|
|
|
from database import get_db
|
|
from schemas import DaySummaryResponse, LogEntryCreate, LogEntryRead, LogEntryUpdate
|
|
from services import log as svc
|
|
|
|
router = APIRouter(prefix="/api/log", tags=["log"])
|
|
|
|
|
|
@router.get("", response_model=list[LogEntryRead])
|
|
def get_log(date: date, db: Session = Depends(get_db)):
|
|
"""All entries for a client-supplied date, ordered by sort_order then id,
|
|
each with the referenced food embedded (§3.3)."""
|
|
return svc.get_log_entries(db, date)
|
|
|
|
|
|
@router.post("", response_model=LogEntryRead, status_code=201)
|
|
def create_log_entry(data: LogEntryCreate, db: Session = Depends(get_db)):
|
|
"""Add a log entry. food_id must reference a non-deleted food.
|
|
sort_order defaults to end of day. Unknown or soft-deleted food → 404."""
|
|
try:
|
|
return svc.create_log_entry(db, data)
|
|
except svc.FoodNotAvailableError as e:
|
|
raise HTTPException(status_code=404, detail=str(e))
|
|
|
|
|
|
@router.get("/summary", response_model=DaySummaryResponse)
|
|
def get_day_summary(date: date, db: Session = Depends(get_db)):
|
|
"""Computed nutrition totals for the day vs. the applicable target (§3.3)."""
|
|
return svc.get_day_summary(db, date)
|
|
|
|
|
|
@router.put("/{entry_id}", response_model=LogEntryRead)
|
|
def update_log_entry(entry_id: int, data: LogEntryUpdate, db: Session = Depends(get_db)):
|
|
"""Update quantity, meal_slot, and/or sort_order.
|
|
Only provided fields change; send {"meal_slot": null} to clear it."""
|
|
result = svc.update_log_entry(db, entry_id, data)
|
|
if result is None:
|
|
raise HTTPException(status_code=404, detail="Log entry not found")
|
|
return result
|
|
|
|
|
|
@router.delete("/{entry_id}")
|
|
def delete_log_entry(entry_id: int, db: Session = Depends(get_db)):
|
|
"""Hard-delete a log entry (§2.3 has no soft-delete)."""
|
|
if not svc.delete_log_entry(db, entry_id):
|
|
raise HTTPException(status_code=404, detail="Log entry not found")
|
|
return {"status": "ok"}
|