"""# Summary Appointment-reminder pipeline family — port contracts (stage interfaces + root interface). The demo pipeline axis of the vet sample: each stage is a small, testable unit; the DI container wires the tree. """ from abc import ABC, abstractmethod from typing import Any class LoadPort(ABC): """Load the appointment the job refers to.""" @abstractmethod async def load(self, appointment_id: int) -> dict[str, Any]: """Return the appointment as a JSON-ready mapping.""" class ComposePort(ABC): """Compose the reminder message from the appointment context.""" @abstractmethod def compose(self, appointment: dict[str, Any], pet: dict[str, Any] | None, parent: dict[str, Any] | None) -> dict[str, Any]: """Return a reminder record ``{to, subject, body}``.""" class DeliverPort(ABC): """Deliver the composed reminder (log stub today, email/SMS adaptor later).""" @abstractmethod async def deliver(self, reminder: dict[str, Any]) -> dict[str, Any]: """Deliver the reminder and return it with a delivery marker.""" class AppointmentReminderPipelinePort(ABC): """Root of the appointment-reminder family. Notes: The slot annotations below are contracts. A concrete subclass re-annotates them with stage implementations; the DI container instantiates the tree. """ loader: LoadPort compose: ComposePort deliver: DeliverPort @abstractmethod async def run(self, appointment_id: int) -> dict[str, Any]: """Run the full stage chain and return the delivered reminder."""