TorbatYar/backend/services/experience/app/providers/contracts.py
Mortezakoohjani 203671a7bf feat(experience): ship Experience Platform phases 11.0-11.10
Add the experience service with sites through analytics/AI hooks, migrations through 0011, and phase docs/manifests marking the track complete.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-27 11:43:10 +03:30

137 lines
3.7 KiB
Python

"""Platform capability contracts — interfaces only; no implementations in Experience."""
from __future__ import annotations
from typing import Any, Protocol
from uuid import UUID
class AccountingProvider(Protocol):
"""Contract for Accounting. Experience must not post journals."""
async def resolve_account_ref(
self, *, tenant_id: UUID, reference: str
) -> dict[str, Any]: ...
class CRMProvider(Protocol):
"""Contract for CRM. Experience stores external contact/org refs only."""
async def resolve_contact(
self, *, tenant_id: UUID, contact_ref: str
) -> dict[str, Any]: ...
class LoyaltyProvider(Protocol):
"""Contract for Loyalty. Experience must not own points/ledger."""
async def resolve_member(
self, *, tenant_id: UUID, member_ref: str
) -> dict[str, Any]: ...
class CommunicationProvider(Protocol):
"""Contract for Communication. Experience must not own SMS providers."""
async def send(
self,
*,
tenant_id: UUID,
channel: str,
template_key: str,
to: str,
payload: dict[str, Any],
) -> None: ...
class NotificationProvider(Protocol):
"""Contract for Notification fanout."""
async def notify(
self,
*,
tenant_id: UUID,
channel: str,
template_key: str,
payload: dict[str, Any],
) -> None: ...
class StorageProvider(Protocol):
"""Contract for File Storage. Experience stores media refs only."""
async def resolve_file(
self, *, tenant_id: UUID, file_ref: str
) -> dict[str, Any]: ...
class AIProvider(Protocol):
"""Contract for AI Platform. Experience must not own model inference."""
async def generate_content(
self, *, tenant_id: UUID, task: str, context: dict[str, Any]
) -> dict[str, Any]: ...
class IdentityProvider(Protocol):
"""Contract for Identity. Experience stores external_user_ref only."""
async def resolve_user(
self, *, tenant_id: UUID, user_ref: str
) -> dict[str, Any]: ...
class RenderEngineProvider(Protocol):
"""Contract for pluggable render/SSG engines — adapters live in Experience."""
async def render_preview(
self, *, tenant_id: UUID, request: dict[str, Any]
) -> dict[str, Any]: ...
class ThemeMarketplaceProvider(Protocol):
"""Contract for external theme packs — adapters live in Experience."""
async def resolve_theme_pack(
self, *, tenant_id: UUID, request: dict[str, Any]
) -> dict[str, Any]: ...
class HospitalityProvider(Protocol):
"""Contract for Hospitality menu/venue refs — Experience must not own menus."""
async def resolve_menu_ref(
self, *, tenant_id: UUID, menu_ref: str
) -> dict[str, Any]: ...
class MarketplaceProvider(Protocol):
"""Contract for Marketplace catalog refs — Experience must not own products."""
async def resolve_product_ref(
self, *, tenant_id: UUID, product_ref: str
) -> dict[str, Any]: ...
class SportsCenterProvider(Protocol):
"""Contract for Sports Center entity refs."""
async def resolve_member_ref(
self, *, tenant_id: UUID, member_ref: str
) -> dict[str, Any]: ...
class DeliveryProvider(Protocol):
"""Contract for Delivery job refs on campaign pages."""
async def resolve_job_ref(
self, *, tenant_id: UUID, job_ref: str
) -> dict[str, Any]: ...
class AutomationProvider(Protocol):
"""Contract for Automation triggers from form/publish events."""
async def emit_trigger(
self, *, tenant_id: UUID, trigger_key: str, payload: dict[str, Any]
) -> None: ...