from datetime import date from typing import Optional from uuid import UUID, uuid4 from fastapi import APIRouter, Depends, HTTPException from sqlmodel import Session, SQLModel, select from db import get_session from innercontext.models import SkinConditionSnapshot from innercontext.models.enums import ( BarrierState, OverallSkinState, SkinConcern, SkinTrend, SkinType, ) router = APIRouter() # --------------------------------------------------------------------------- # Schemas # --------------------------------------------------------------------------- class SnapshotCreate(SQLModel): snapshot_date: date overall_state: Optional[OverallSkinState] = None trend: Optional[SkinTrend] = None skin_type: Optional[SkinType] = None hydration_level: Optional[int] = None sebum_tzone: Optional[int] = None sebum_cheeks: Optional[int] = None sensitivity_level: Optional[int] = None barrier_state: Optional[BarrierState] = None active_concerns: list[SkinConcern] = [] risks: list[str] = [] priorities: list[str] = [] notes: Optional[str] = None class SnapshotUpdate(SQLModel): snapshot_date: Optional[date] = None overall_state: Optional[OverallSkinState] = None trend: Optional[SkinTrend] = None skin_type: Optional[SkinType] = None hydration_level: Optional[int] = None sebum_tzone: Optional[int] = None sebum_cheeks: Optional[int] = None sensitivity_level: Optional[int] = None barrier_state: Optional[BarrierState] = None active_concerns: Optional[list[SkinConcern]] = None risks: Optional[list[str]] = None priorities: Optional[list[str]] = None notes: Optional[str] = None # --------------------------------------------------------------------------- # Helper # --------------------------------------------------------------------------- def get_or_404(session: Session, model, record_id) -> object: obj = session.get(model, record_id) if obj is None: raise HTTPException(status_code=404, detail=f"{model.__name__} not found") return obj # --------------------------------------------------------------------------- # Routes # --------------------------------------------------------------------------- @router.get("", response_model=list[SkinConditionSnapshot]) def list_snapshots( from_date: Optional[date] = None, to_date: Optional[date] = None, overall_state: Optional[OverallSkinState] = None, session: Session = Depends(get_session), ): stmt = select(SkinConditionSnapshot) if from_date is not None: stmt = stmt.where(SkinConditionSnapshot.snapshot_date >= from_date) if to_date is not None: stmt = stmt.where(SkinConditionSnapshot.snapshot_date <= to_date) if overall_state is not None: stmt = stmt.where(SkinConditionSnapshot.overall_state == overall_state) return session.exec(stmt).all() @router.post("", response_model=SkinConditionSnapshot, status_code=201) def create_snapshot( data: SnapshotCreate, session: Session = Depends(get_session) ): snapshot = SkinConditionSnapshot(id=uuid4(), **data.model_dump()) session.add(snapshot) session.commit() session.refresh(snapshot) return snapshot @router.get("/{snapshot_id}", response_model=SkinConditionSnapshot) def get_snapshot(snapshot_id: UUID, session: Session = Depends(get_session)): return get_or_404(session, SkinConditionSnapshot, snapshot_id) @router.patch("/{snapshot_id}", response_model=SkinConditionSnapshot) def update_snapshot( snapshot_id: UUID, data: SnapshotUpdate, session: Session = Depends(get_session), ): snapshot = get_or_404(session, SkinConditionSnapshot, snapshot_id) for key, value in data.model_dump(exclude_unset=True).items(): setattr(snapshot, key, value) session.add(snapshot) session.commit() session.refresh(snapshot) return snapshot @router.delete("/{snapshot_id}", status_code=204) def delete_snapshot(snapshot_id: UUID, session: Session = Depends(get_session)): snapshot = get_or_404(session, SkinConditionSnapshot, snapshot_id) session.delete(snapshot) session.commit()