import logging from fastapi import APIRouter, Depends, HTTPException, Request, status from pydantic import BaseModel try: from banban.security import get_current_user_id from banban.service.child import ChildService except ModuleNotFoundError: from banban.security import get_current_user_id from banban.service.child import ChildService router = APIRouter(prefix="/children", tags=["children"]) logger = logging.getLogger("banban.children") class ChildCreateRequest(BaseModel): child_name: str child_gender: int = 2 child_birthday: str | None = None class ChildResponse(BaseModel): child_id: int child_name: str child_gender: int child_birthday: str | None = None status: int class ChildUpdateRequest(BaseModel): child_name: str | None = None child_gender: int | None = None child_birthday: str | None = None class ChildListResponse(BaseModel): items: list[ChildResponse] total: int next_cursor: int | None = None @router.post("", response_model=ChildResponse, status_code=status.HTTP_201_CREATED) async def create_child( payload: ChildCreateRequest, request: Request, current_user_id: int = Depends(get_current_user_id), ) -> ChildResponse: service = ChildService() child = await service.create(current_user_id, payload.child_name, payload.child_gender, payload.child_birthday) return ChildResponse(**child) @router.get("", response_model=ChildListResponse) async def list_children( request: Request, cursor: int | None = None, limit: int = 20, current_user_id: int = Depends(get_current_user_id), ) -> ChildListResponse: service = ChildService() rows, has_more = await service.list_children(current_user_id, limit, cursor) next_cursor = rows[-1]["child_id"] if has_more and rows else None items = [ChildResponse(**row) for row in rows] return ChildListResponse(items=items, total=len(items), next_cursor=next_cursor) @router.get("/{child_id}", response_model=ChildResponse) async def get_child( child_id: int, request: Request, current_user_id: int = Depends(get_current_user_id), ) -> ChildResponse: del request service = ChildService() child = await service.get(child_id, current_user_id) if not child: raise HTTPException(status_code=404, detail="child not found") return ChildResponse(**child) @router.patch("/{child_id}", response_model=ChildResponse) async def update_child( child_id: int, payload: ChildUpdateRequest, request: Request, current_user_id: int = Depends(get_current_user_id), ) -> ChildResponse: service = ChildService() try: child = await service.update(child_id, current_user_id, payload.child_name, payload.child_gender, payload.child_birthday) except PermissionError: raise HTTPException(status_code=403, detail="no permission to access this child") if not child: raise HTTPException(status_code=404, detail="child not found") return ChildResponse(**child) @router.delete("/{child_id}", status_code=status.HTTP_204_NO_CONTENT) async def delete_child( child_id: int, request: Request, current_user_id: int = Depends(get_current_user_id), ) -> None: del request service = ChildService() deleted = await service.delete(child_id, current_user_id) if not deleted: raise HTTPException(status_code=404, detail="child not found")