"""API schemas (Pydantic) for PlannedLeaveDay. Schemas validate request bodies and shape responses. Separate from domain entities so the wire format can evolve independently. """ from datetime import date, datetime from uuid import UUID from pydantic import BaseModel from app.entities.planned_leave import PlannedLeaveDay class PlannedLeaveDayResponse(BaseModel): """Read-only wire shape. `planned_leave_day` is purely derived output now (restructure step 3b) — there is no `PlannedLeaveDayCreate`/`Update` model any more; every write goes through `POST /api/plan/sync(-with- wish)` or `POST /api/day-assertions`. `is_pinned` is NOT a column on the entity (migration 010 dropped it) — it is computed live from `DayAssertion` and passed in explicitly by the caller (see `PlanningService._annotate_pinned`), so a lock icon in the calendar UI keeps working unchanged even though nothing on `planned_leave_day` itself carries that state any more. """ id: UUID workspace_id: UUID child_id: UUID parent_personal_data_uuid: UUID date: date day_type: str is_dubbeldag: bool wish_id: UUID | None is_pinned: bool created_at: datetime | None updated_at: datetime | None @classmethod def from_entity( cls, entity: PlannedLeaveDay, is_pinned: bool = False ) -> "PlannedLeaveDayResponse": return cls( id=entity.id, workspace_id=entity.workspace_id, child_id=entity.child_id, parent_personal_data_uuid=entity.parent_personal_data_uuid, date=entity.date, day_type=entity.day_type, is_dubbeldag=entity.is_dubbeldag, wish_id=entity.wish_id, is_pinned=is_pinned, created_at=entity.created_at, updated_at=entity.updated_at, )