Files
orion/app/modules/contracts/__init__.py
Samir Boulahtit ef9ea29643 feat: module-driven onboarding system + simplified 3-step signup
Add OnboardingProviderProtocol so modules declare their own post-signup
onboarding steps. The core OnboardingAggregator discovers enabled
providers and exposes a dashboard API (GET /dashboard/onboarding).
A session-scoped banner on the store dashboard shows a checklist that
guides merchants through setup without blocking signup.

Signup is simplified from 4 steps to 3 (Plan → Account → Payment):
store creation is merged into account creation, store language is
captured from the user's browsing language, and platform-specific
template branching is removed.

Includes 47 unit and integration tests covering all new providers,
the aggregator, the API endpoint, and the signup service changes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 23:39:42 +01:00

113 lines
3.2 KiB
Python

# app/modules/contracts/__init__.py
"""
Cross-module contracts using Protocol pattern.
This module defines type-safe interfaces for cross-module communication.
Modules depend on protocols rather than concrete implementations, enabling:
- Loose coupling between modules
- Testability through mock implementations
- Clear dependency boundaries
Usage:
from app.modules.contracts.cms import ContentServiceProtocol
class OrderService:
def __init__(self, content: ContentServiceProtocol | None = None):
self._content = content
@property
def content(self) -> ContentServiceProtocol:
if self._content is None:
from app.modules.cms.services import content_page_service
self._content = content_page_service
return self._content
Metrics Provider Pattern:
from app.modules.contracts.metrics import MetricsProviderProtocol, MetricValue
class OrderMetricsProvider:
@property
def metrics_category(self) -> str:
return "orders"
def get_store_metrics(self, db, store_id, context=None) -> list[MetricValue]:
return [MetricValue(key="orders.total", value=42, label="Total", category="orders")]
Widget Provider Pattern:
from app.modules.contracts.widgets import DashboardWidgetProviderProtocol, DashboardWidget
class OrderWidgetProvider:
@property
def widgets_category(self) -> str:
return "orders"
def get_store_widgets(self, db, store_id, context=None) -> list[DashboardWidget]:
return [DashboardWidget(key="orders.recent", widget_type="list", ...)]
"""
from app.modules.contracts.audit import (
AuditEvent,
AuditProviderProtocol,
)
from app.modules.contracts.base import ServiceProtocol
from app.modules.contracts.cms import ContentServiceProtocol, MediaUsageProviderProtocol
from app.modules.contracts.features import (
FeatureDeclaration,
FeatureProviderProtocol,
FeatureScope,
FeatureType,
FeatureUsage,
)
from app.modules.contracts.metrics import (
MetricsContext,
MetricsProviderProtocol,
MetricValue,
)
from app.modules.contracts.onboarding import (
OnboardingProviderProtocol,
OnboardingStepDefinition,
OnboardingStepStatus,
)
from app.modules.contracts.widgets import (
BreakdownWidget,
DashboardWidget,
DashboardWidgetProviderProtocol,
ListWidget,
WidgetBreakdownItem,
WidgetContext,
WidgetListItem,
)
__all__ = [
# Base protocols
"ServiceProtocol",
# CMS protocols
"ContentServiceProtocol",
"MediaUsageProviderProtocol",
# Audit protocols
"AuditEvent",
"AuditProviderProtocol",
# Feature protocols
"FeatureType",
"FeatureScope",
"FeatureDeclaration",
"FeatureUsage",
"FeatureProviderProtocol",
# Metrics protocols
"MetricValue",
"MetricsContext",
"MetricsProviderProtocol",
# Onboarding protocols
"OnboardingStepDefinition",
"OnboardingStepStatus",
"OnboardingProviderProtocol",
# Widget protocols
"WidgetContext",
"WidgetListItem",
"WidgetBreakdownItem",
"ListWidget",
"BreakdownWidget",
"DashboardWidget",
"DashboardWidgetProviderProtocol",
]