"""Appointment domain policies — Phase 14.1.""" from __future__ import annotations from app.models.types import AppointmentLifecycleAction, AppointmentStatus from app.validators.appointments import ( ensure_appointment_lifecycle_transition, target_status_for, validate_reason, ) class AppointmentLifecyclePolicy: REQUIRES_REASON = frozenset( {AppointmentLifecycleAction.CANCEL, AppointmentLifecycleAction.NO_SHOW} ) def assert_transition( self, *, action: AppointmentLifecycleAction, current: AppointmentStatus, reason: str | None = None, ) -> tuple[AppointmentStatus, str | None]: ensure_appointment_lifecycle_transition(action=action, current=current) cleaned = validate_reason(reason, required=action in self.REQUIRES_REASON) return target_status_for(action), cleaned