TICKET-003: Daily log write path

- POST/PUT/DELETE /api/log, GET /api/log?date= with embedded food
- sort_order auto-appends per day; hard delete for log entries
- Soft-deleted foods rejected for new logs (404) but render in history
- Full suite green (87 passed)
This commit is contained in:
Craig
2026-07-26 13:15:46 +01:00
parent 601c0d461e
commit 87d7eca468
4 changed files with 564 additions and 12 deletions
+25
View File
@@ -103,6 +103,30 @@ class LogEntryCreate(BaseModel):
date: date # client-supplied YYYY-MM-DD (spec §8.1 rule 8)
class LogEntryUpdate(BaseModel):
"""Schema for PUT /api/log/{id}. All fields optional — only supplied
fields are updated. Send {"meal_slot": null} to clear the slot."""
quantity: float | None = Field(default=None, gt=0)
meal_slot: MealSlot | None = None
sort_order: int | None = None
class LogFoodRead(BaseModel):
"""Embedded food reference in log entry responses (spec §3.3, §8.3 rule 1).
Includes name, brand, unit_type, and serving info so the frontend can render
log entries without N+1 lookups. Soft-deleted foods render here (§2.1)."""
model_config = ConfigDict(from_attributes=True)
id: int
name: str
brand: str | None
unit_type: UnitType
serving_size_g: float | None
serving_name: str | None
is_meal: bool
deleted_at: datetime | None
class LogEntryRead(BaseModel):
model_config = ConfigDict(from_attributes=True)
@@ -112,6 +136,7 @@ class LogEntryRead(BaseModel):
quantity: float
meal_slot: MealSlot | None
sort_order: int
food: LogFoodRead
# ── Targets ──────────────────────────────────────────────────────────────────