"""Domain entity: PlannedDayExclusion. "The planner may not place leave for THIS parent, for THIS child, on THIS date." One row is one user instruction, recorded when the user removes a single day out of a planner-placed period ("this day" in the calendar's three-way remove). Without it, the next `POST /api/plan/sync` would simply re-derive the day from the wish — the wish still says "a full week", and nothing anywhere said that one date was off the table. Deliberately NOT modelled as a `DayOverride`. A `DayOverride` answers a *calendar* question ("is this date a working day for this workspace?"), is workspace-wide, and is applied inside `is_free_day`. This answers a *planning* question ("may a leave day be placed here?"), is per parent and per child, and is applied where a window is funded. Folding the second into the first would mean a removed Tuesday silently became a non-working day for everyone and everything, analytics included. Keyed per parent (see `PlannedDayExclusionService`): a both-parents period places one day per parent on the same date, and removing one parent's day must not silently remove the other's. The allocator only drops the date from a window entirely when no responsible parent may take it — see `_Ledger._excluded_window_dates`. """ from dataclasses import dataclass from datetime import date, datetime from uuid import UUID @dataclass class PlannedDayExclusion: """One (workspace, child, parent, date) the planner must leave empty.""" id: UUID workspace_id: UUID child_id: UUID parent_personal_data_uuid: UUID date: date created_at: datetime | None = None updated_at: datetime | None = None