""" Base interface for anything that can fetch orders. To add a new source later (ShipStation, Odoo, ...): 1. Create app/services/shipstation_service.py 2. Subclass OrderService, implement fetch_orders() 3. Register it in app/services/__init__.py's SERVICE_REGISTRY 4. Add its settings to app/config.py's SETTINGS_SCHEMA The UI and database layers don't need to change at all. """ from __future__ import annotations from abc import ABC, abstractmethod from typing import List, TypedDict, Optional import datetime as dt class NormalizedOrder(TypedDict): """The common shape every service must translate its data into.""" source: str external_id: str ticket_number: Optional[str] company: str skus: List[str] line_items: List[dict] shipping_info: dict creator: Optional[str] description: Optional[str] tracking_numbers: List[dict] summary: str status: str source_created_at: Optional[dt.datetime] raw_data: dict class OrderService(ABC): """Common interface for every order source.""" #: short machine-friendly name, e.g. "jira", "shipstation", "odoo" name: str = "base" @abstractmethod def fetch_orders(self) -> List[NormalizedOrder]: """Fetch and return today's orders, normalized to NormalizedOrder.""" raise NotImplementedError def is_configured(self) -> bool: """Override to check that required settings are present.""" return True