"""Availability, shifts & working zones DTOs — Phase 10.3.""" from __future__ import annotations from datetime import datetime from uuid import UUID from pydantic import BaseModel, ConfigDict, Field from app.models.types import ( DriverAvailabilityStatus, ShiftAssignmentStatus, ShiftStatus, WorkingZoneStatus, ) from app.schemas.common import ORMBase _FORBID = ConfigDict(extra="forbid") class DriverAvailabilityUpsert(BaseModel): model_config = _FORBID status: DriverAvailabilityStatus effective_from: datetime | None = None effective_until: datetime | None = None notes: str | None = None metadata_json: dict | None = None version: int | None = Field(default=None, ge=1) class DriverAvailabilityRead(ORMBase): id: UUID tenant_id: UUID driver_id: UUID status: DriverAvailabilityStatus effective_from: datetime | None effective_until: datetime | None notes: str | None metadata_json: dict | None version: int is_deleted: bool created_by: str | None updated_by: str | None created_at: datetime updated_at: datetime class ShiftCreate(BaseModel): model_config = _FORBID organization_id: UUID hub_id: UUID | None = None code: str = Field(max_length=50) name: str = Field(max_length=255) status: ShiftStatus = ShiftStatus.DRAFT starts_at: datetime ends_at: datetime metadata_json: dict | None = None class ShiftUpdate(BaseModel): model_config = _FORBID hub_id: UUID | None = None name: str | None = Field(default=None, max_length=255) status: ShiftStatus | None = None starts_at: datetime | None = None ends_at: datetime | None = None metadata_json: dict | None = None version: int = Field(ge=1) class ShiftRead(ORMBase): id: UUID tenant_id: UUID organization_id: UUID hub_id: UUID | None code: str name: str status: ShiftStatus starts_at: datetime ends_at: datetime metadata_json: dict | None version: int is_deleted: bool created_by: str | None updated_by: str | None created_at: datetime updated_at: datetime class ShiftListResponse(BaseModel): items: list[ShiftRead] total: int page: int page_size: int class ShiftAssignmentCreate(BaseModel): model_config = _FORBID driver_id: UUID notes: str | None = None metadata_json: dict | None = None class ShiftAssignmentUpdate(BaseModel): model_config = _FORBID status: ShiftAssignmentStatus | None = None notes: str | None = None metadata_json: dict | None = None class ShiftAssignmentRead(ORMBase): id: UUID tenant_id: UUID shift_id: UUID driver_id: UUID status: ShiftAssignmentStatus notes: str | None metadata_json: dict | None is_deleted: bool created_by: str | None updated_by: str | None created_at: datetime updated_at: datetime class WorkingZoneCreate(BaseModel): model_config = _FORBID organization_id: UUID code: str = Field(max_length=50) name: str = Field(max_length=255) status: WorkingZoneStatus = WorkingZoneStatus.ACTIVE geo_boundary_ref: str | None = Field(default=None, max_length=255) metadata_json: dict | None = None class WorkingZoneUpdate(BaseModel): model_config = _FORBID name: str | None = Field(default=None, max_length=255) status: WorkingZoneStatus | None = None geo_boundary_ref: str | None = Field(default=None, max_length=255) metadata_json: dict | None = None version: int = Field(ge=1) class WorkingZoneRead(ORMBase): id: UUID tenant_id: UUID organization_id: UUID code: str name: str status: WorkingZoneStatus geo_boundary_ref: str | None metadata_json: dict | None version: int is_deleted: bool created_by: str | None updated_by: str | None created_at: datetime updated_at: datetime class WorkingZoneListResponse(BaseModel): items: list[WorkingZoneRead] total: int page: int page_size: int