added feeding data objects and workflow
This commit is contained in:
@@ -0,0 +1,158 @@
|
||||
"""Feeding log management router."""
|
||||
|
||||
from typing import Annotated
|
||||
from fastapi import APIRouter, HTTPException, Depends
|
||||
|
||||
from baby_monitor.models.feeding import (
|
||||
CreateFeedingRequest,
|
||||
UpdateFeedingRequest,
|
||||
FeedingResponse,
|
||||
)
|
||||
from baby_monitor.routers.auth import verify_token
|
||||
from baby_monitor.repositories.feeding.sqlite_feeding import (
|
||||
SQLiteFeedingRepository,
|
||||
)
|
||||
from baby_monitor.repositories.dependencies.get_feeding_repository import (
|
||||
get_feeding_repository,
|
||||
)
|
||||
from baby_monitor.repositories.child.sqlite_child import SQLiteChildRepository
|
||||
from baby_monitor.repositories.dependencies.get_child_repository import (
|
||||
get_child_repository,
|
||||
)
|
||||
|
||||
router = APIRouter(prefix="/api/feedings", tags=["feedings"])
|
||||
|
||||
|
||||
@router.post("", response_model=FeedingResponse, status_code=201)
|
||||
def create_feeding(
|
||||
request: CreateFeedingRequest,
|
||||
user_id: Annotated[int, Depends(verify_token)],
|
||||
feeding_repo: Annotated[SQLiteFeedingRepository, Depends(get_feeding_repository)],
|
||||
child_repo: Annotated[SQLiteChildRepository, Depends(get_child_repository)],
|
||||
) -> FeedingResponse:
|
||||
"""Create a new feeding log entry."""
|
||||
# Verify the child belongs to the authenticated user
|
||||
child = child_repo.get_by_id(request.child_id)
|
||||
if not child:
|
||||
raise HTTPException(status_code=404, detail="Child not found")
|
||||
|
||||
if child["user_id"] != user_id:
|
||||
raise HTTPException(status_code=403, detail="Access denied to this child")
|
||||
|
||||
feeding = feeding_repo.create(
|
||||
child_id=request.child_id,
|
||||
start_time=request.start_time,
|
||||
end_time=request.end_time,
|
||||
feeding_type=request.feeding_type.value,
|
||||
)
|
||||
|
||||
return FeedingResponse(**feeding)
|
||||
|
||||
|
||||
@router.get("/active", response_model=FeedingResponse | None)
|
||||
def get_active_feeding(
|
||||
user_id: Annotated[int, Depends(verify_token)],
|
||||
feeding_repo: Annotated[SQLiteFeedingRepository, Depends(get_feeding_repository)],
|
||||
child_repo: Annotated[SQLiteChildRepository, Depends(get_child_repository)],
|
||||
) -> FeedingResponse | None:
|
||||
"""Get the current active feeding (where end_time is null) for the user."""
|
||||
feedings = feeding_repo.get_by_user_id(user_id)
|
||||
|
||||
# Find the first feeding with no end_time
|
||||
for feeding in feedings:
|
||||
if feeding["end_time"] is None:
|
||||
# Get child info to include in response
|
||||
child = child_repo.get_by_id(feeding["child_id"])
|
||||
response_data = feeding.copy()
|
||||
if child:
|
||||
response_data["child_name"] = child["name"]
|
||||
return FeedingResponse(**response_data)
|
||||
|
||||
return None
|
||||
|
||||
|
||||
@router.get("", response_model=list[FeedingResponse])
|
||||
def get_user_feedings(
|
||||
user_id: Annotated[int, Depends(verify_token)],
|
||||
feeding_repo: Annotated[SQLiteFeedingRepository, Depends(get_feeding_repository)],
|
||||
) -> list[FeedingResponse]:
|
||||
"""Get all feeding logs for the authenticated user's children."""
|
||||
feedings = feeding_repo.get_by_user_id(user_id)
|
||||
return [FeedingResponse(**feeding) for feeding in feedings]
|
||||
|
||||
|
||||
@router.get("/{feeding_id}", response_model=FeedingResponse)
|
||||
def get_feeding(
|
||||
feeding_id: int,
|
||||
user_id: Annotated[int, Depends(verify_token)],
|
||||
feeding_repo: Annotated[SQLiteFeedingRepository, Depends(get_feeding_repository)],
|
||||
child_repo: Annotated[SQLiteChildRepository, Depends(get_child_repository)],
|
||||
) -> FeedingResponse:
|
||||
"""Get a specific feeding log by ID."""
|
||||
feeding = feeding_repo.get_by_id(feeding_id)
|
||||
|
||||
if not feeding:
|
||||
raise HTTPException(status_code=404, detail="Feeding log not found")
|
||||
|
||||
# Verify the feeding belongs to user's child
|
||||
child = child_repo.get_by_id(feeding["child_id"])
|
||||
if not child or child["user_id"] != user_id:
|
||||
raise HTTPException(status_code=403, detail="Access denied")
|
||||
|
||||
return FeedingResponse(**feeding)
|
||||
|
||||
|
||||
@router.put("/{feeding_id}", response_model=FeedingResponse)
|
||||
def update_feeding(
|
||||
feeding_id: int,
|
||||
request: UpdateFeedingRequest,
|
||||
user_id: Annotated[int, Depends(verify_token)],
|
||||
feeding_repo: Annotated[SQLiteFeedingRepository, Depends(get_feeding_repository)],
|
||||
child_repo: Annotated[SQLiteChildRepository, Depends(get_child_repository)],
|
||||
) -> FeedingResponse:
|
||||
"""Update a feeding log entry."""
|
||||
feeding = feeding_repo.get_by_id(feeding_id)
|
||||
|
||||
if not feeding:
|
||||
raise HTTPException(status_code=404, detail="Feeding log not found")
|
||||
|
||||
# Verify ownership
|
||||
child = child_repo.get_by_id(feeding["child_id"])
|
||||
if not child or child["user_id"] != user_id:
|
||||
raise HTTPException(status_code=403, detail="Access denied")
|
||||
|
||||
# Update the feeding
|
||||
updated_feeding = feeding_repo.update(
|
||||
feeding_id=feeding_id,
|
||||
start_time=request.start_time,
|
||||
end_time=request.end_time,
|
||||
feeding_type=request.feeding_type.value if request.feeding_type else None,
|
||||
)
|
||||
|
||||
if not updated_feeding:
|
||||
raise HTTPException(status_code=500, detail="Update failed")
|
||||
|
||||
return FeedingResponse(**updated_feeding)
|
||||
|
||||
|
||||
@router.delete("/{feeding_id}", status_code=204)
|
||||
def delete_feeding(
|
||||
feeding_id: int,
|
||||
user_id: Annotated[int, Depends(verify_token)],
|
||||
feeding_repo: Annotated[SQLiteFeedingRepository, Depends(get_feeding_repository)],
|
||||
child_repo: Annotated[SQLiteChildRepository, Depends(get_child_repository)],
|
||||
) -> None:
|
||||
"""Delete a feeding log entry."""
|
||||
feeding = feeding_repo.get_by_id(feeding_id)
|
||||
|
||||
if not feeding:
|
||||
raise HTTPException(status_code=404, detail="Feeding log not found")
|
||||
|
||||
# Verify ownership
|
||||
child = child_repo.get_by_id(feeding["child_id"])
|
||||
if not child or child["user_id"] != user_id:
|
||||
raise HTTPException(status_code=403, detail="Access denied")
|
||||
|
||||
success = feeding_repo.delete(feeding_id)
|
||||
if not success:
|
||||
raise HTTPException(status_code=500, detail="Delete failed")
|
||||
Reference in New Issue
Block a user