160 lines
5.2 KiB
Python
160 lines
5.2 KiB
Python
"""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.interfaces import (
|
|
ChildRepositoryInterface,
|
|
FeedingRepositoryInterface,
|
|
)
|
|
from baby_monitor.repositories.dependencies import (
|
|
get_feeding_repository,
|
|
get_child_repository,
|
|
)
|
|
from baby_monitor.utils import verify_child_access
|
|
|
|
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[
|
|
FeedingRepositoryInterface, Depends(get_feeding_repository)
|
|
],
|
|
child_repo: Annotated[ChildRepositoryInterface, Depends(get_child_repository)],
|
|
) -> FeedingResponse:
|
|
"""Create a new feeding log entry."""
|
|
# Verify the child belongs to the authenticated user
|
|
verify_child_access(child_repo, request.child_id, user_id)
|
|
|
|
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[
|
|
FeedingRepositoryInterface, Depends(get_feeding_repository)
|
|
],
|
|
child_repo: Annotated[ChildRepositoryInterface, 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[
|
|
FeedingRepositoryInterface, 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[
|
|
FeedingRepositoryInterface, Depends(get_feeding_repository)
|
|
],
|
|
child_repo: Annotated[ChildRepositoryInterface, 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
|
|
verify_child_access(child_repo, feeding["child_id"], user_id)
|
|
|
|
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[
|
|
FeedingRepositoryInterface, Depends(get_feeding_repository)
|
|
],
|
|
child_repo: Annotated[ChildRepositoryInterface, 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
|
|
verify_child_access(child_repo, feeding["child_id"], user_id)
|
|
|
|
# Update the feeding
|
|
feeding_type_value = request.feeding_type.value if request.feeding_type else None
|
|
updated_feeding = feeding_repo.update(
|
|
feeding_id=feeding_id,
|
|
start_time=request.start_time,
|
|
end_time=request.end_time,
|
|
feeding_type=feeding_type_value,
|
|
)
|
|
|
|
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[
|
|
FeedingRepositoryInterface, Depends(get_feeding_repository)
|
|
],
|
|
child_repo: Annotated[ChildRepositoryInterface, 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
|
|
verify_child_access(child_repo, feeding["child_id"], user_id)
|
|
|
|
success = feeding_repo.delete(feeding_id)
|
|
if not success:
|
|
raise HTTPException(status_code=500, detail="Delete failed")
|