from dataclasses import dataclass from datetime import date from typing import Literal, NewType, Optional, Tuple, Union PlaceRef = NewType("PlaceRef", str) SlotCode = Literal["AM", "PM", "AD"] @dataclass(frozen=True) class LogJobRequest: client_ref: str place_ref: PlaceRef appointment_date: date appointment_time: SlotCode short_description: str long_description: str @dataclass(frozen=True) class JobLogged: job_no: str logged_info: str @dataclass(frozen=True) class AbriRequestRejected: code: str message: str LogJobResult = Union[JobLogged, AbriRequestRejected] @dataclass(frozen=True) class AmendJobRequest: job_no: str appointment_date: date appointment_time: SlotCode resource: Optional[str] = None @dataclass(frozen=True) class AppointmentAmended: job_no: str appointment_date: str appointment_time: str AmendJobResult = Union[AppointmentAmended, AbriRequestRejected] @dataclass(frozen=True) class Tenant: """A tenancy signatory, minimised to the fields the HubSpot sync needs. Person title, per-person references, the main-contact flag and tenancy dates are deliberately dropped at parse time (data minimisation); mobile and telephone are the single best number of each kind, pre-selected by priority, and secondary_number is the best of the numbers they left unused. """ forenames: str surname: str mobile: Optional[str] telephone: Optional[str] secondary_number: Optional[str] vulnerabilities: Tuple[str, ...] @dataclass(frozen=True) class TenancyData: """Tenancy signatories for a place; the reference is PII-safe.""" tenancy_reference: str tenants: Tuple[Tenant, ...] GetTenantDataResult = Union[TenancyData, AbriRequestRejected]