"""Tracking & proof of delivery DTOs — Phase 10.7.""" from __future__ import annotations from datetime import datetime from uuid import UUID from pydantic import BaseModel, ConfigDict, Field from app.models.types import ( CustomerTrackingTokenStatus, ProofOfDeliveryStatus, TrackingSessionStatus, ) from app.schemas.common import ORMBase _FORBID = ConfigDict(extra="forbid") class TrackingSessionCreate(BaseModel): model_config = _FORBID dispatch_job_id: UUID | None = None driver_id: UUID | None = None metadata_json: dict | None = None class TrackingSessionUpdate(BaseModel): model_config = _FORBID status: TrackingSessionStatus | None = None metadata_json: dict | None = None version: int = Field(ge=1) class TrackingSessionRead(ORMBase): id: UUID tenant_id: UUID dispatch_job_id: UUID | None driver_id: UUID | None status: TrackingSessionStatus started_at: datetime | None ended_at: datetime | 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 TrackingSessionListResponse(BaseModel): items: list[TrackingSessionRead] total: int page: int page_size: int class TrackingPointCreate(BaseModel): model_config = _FORBID latitude: float = Field(ge=-90, le=90) longitude: float = Field(ge=-180, le=180) recorded_at: datetime metadata_json: dict | None = None class TrackingPointRead(ORMBase): id: UUID tenant_id: UUID tracking_session_id: UUID latitude: float longitude: float recorded_at: datetime metadata_json: dict | None created_at: datetime updated_at: datetime class ProofOfDeliveryCreate(BaseModel): model_config = _FORBID dispatch_job_id: UUID signature_file_ref: str | None = Field(default=None, max_length=255) photo_file_ref: str | None = Field(default=None, max_length=255) delivery_code: str | None = Field(default=None, max_length=50) notes: str | None = None metadata_json: dict | None = None class ProofOfDeliveryUpdate(BaseModel): model_config = _FORBID status: ProofOfDeliveryStatus | None = None signature_file_ref: str | None = Field(default=None, max_length=255) photo_file_ref: str | None = Field(default=None, max_length=255) delivery_code: str | None = Field(default=None, max_length=50) notes: str | None = None metadata_json: dict | None = None version: int = Field(ge=1) class ProofOfDeliveryRead(ORMBase): id: UUID tenant_id: UUID dispatch_job_id: UUID status: ProofOfDeliveryStatus signature_file_ref: str | None photo_file_ref: str | None delivery_code: str | None notes: str | None captured_at: datetime | 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 ProofOfDeliveryListResponse(BaseModel): items: list[ProofOfDeliveryRead] total: int page: int page_size: int class CustomerTrackingTokenCreate(BaseModel): model_config = _FORBID dispatch_job_id: UUID expires_at: datetime | None = None metadata_json: dict | None = None class CustomerTrackingTokenRead(ORMBase): id: UUID tenant_id: UUID dispatch_job_id: UUID token: str status: CustomerTrackingTokenStatus expires_at: datetime | None metadata_json: dict | None is_deleted: bool created_by: str | None updated_by: str | None created_at: datetime updated_at: datetime class CustomerTrackingTokenListResponse(BaseModel): items: list[CustomerTrackingTokenRead] total: int page: int page_size: int