refactor: split table models into Base/Table/Public for proper FastAPI serialization
Add ProductBase, ProductPublic, ProductWithInventory and SkinConditionSnapshotBase, SkinConditionSnapshotPublic. Table models now inherit from their Base counterpart and override JSON fields with sa_column. All field_serializer hacks removed; FastAPI response models use the non-table Public classes so Pydantic coerces raw DB dicts → typed models cleanly. ProductCreate and SnapshotCreate now simply inherit their respective Base classes. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
479be25112
commit
c09acc7c81
15 changed files with 225 additions and 198 deletions
|
|
@ -2,12 +2,16 @@ from datetime import date
|
|||
from typing import Optional
|
||||
from uuid import UUID, uuid4
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException
|
||||
from fastapi import APIRouter, Depends
|
||||
from sqlmodel import Session, SQLModel, select
|
||||
|
||||
from db import get_session
|
||||
from innercontext.api.utils import get_or_404
|
||||
from innercontext.models import SkinConditionSnapshot
|
||||
from innercontext.models import (
|
||||
SkinConditionSnapshot,
|
||||
SkinConditionSnapshotBase,
|
||||
SkinConditionSnapshotPublic,
|
||||
)
|
||||
from innercontext.models.enums import (
|
||||
BarrierState,
|
||||
OverallSkinState,
|
||||
|
|
@ -24,23 +28,8 @@ router = APIRouter()
|
|||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
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 SnapshotCreate(SkinConditionSnapshotBase):
|
||||
pass
|
||||
|
||||
|
||||
class SnapshotUpdate(SQLModel):
|
||||
|
|
@ -62,17 +51,12 @@ class SnapshotUpdate(SQLModel):
|
|||
notes: Optional[str] = None
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Helper
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Routes
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
@router.get("", response_model=list[SkinConditionSnapshot])
|
||||
@router.get("", response_model=list[SkinConditionSnapshotPublic])
|
||||
def list_snapshots(
|
||||
from_date: Optional[date] = None,
|
||||
to_date: Optional[date] = None,
|
||||
|
|
@ -89,10 +73,8 @@ def list_snapshots(
|
|||
return session.exec(stmt).all()
|
||||
|
||||
|
||||
@router.post("", response_model=SkinConditionSnapshot, status_code=201)
|
||||
def create_snapshot(
|
||||
data: SnapshotCreate, session: Session = Depends(get_session)
|
||||
):
|
||||
@router.post("", response_model=SkinConditionSnapshotPublic, 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()
|
||||
|
|
@ -100,12 +82,12 @@ def create_snapshot(
|
|||
return snapshot
|
||||
|
||||
|
||||
@router.get("/{snapshot_id}", response_model=SkinConditionSnapshot)
|
||||
@router.get("/{snapshot_id}", response_model=SkinConditionSnapshotPublic)
|
||||
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)
|
||||
@router.patch("/{snapshot_id}", response_model=SkinConditionSnapshotPublic)
|
||||
def update_snapshot(
|
||||
snapshot_id: UUID,
|
||||
data: SnapshotUpdate,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue