- API-004: Add noqa for factory-pattern auth in user_account routes and payments admin - MDL-003: Add from_attributes to MerchantStoreDetailResponse schema - EXC-003: Suppress broad except in merchant_store_service and admin_subscription_service (intentional fallbacks for optional billing module) - NAM-002: Rename onboarding files to *_service.py suffix and update all imports - JS-001: Add file-level noqa for dev-toolbar.js (console interceptor by design) - JS-005: Add init guards to dashboard.js and customer-detail.js - IMPORT-004: Break circular deps by removing orders from inventory requires and marketplace from orders requires; add IMPORT-002 suppression for lazy cross-imports - MOD-025: Remove unused OnboardingAlreadyCompletedException Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
155 lines
4.6 KiB
Python
155 lines
4.6 KiB
Python
# app/modules/contracts/onboarding.py
|
|
"""
|
|
Onboarding provider protocol for module-driven post-signup onboarding.
|
|
|
|
Each module defines its own onboarding steps (what needs to be configured)
|
|
and provides completion checks. The core module's OnboardingAggregator
|
|
discovers and aggregates all providers into a dashboard checklist.
|
|
|
|
Benefits:
|
|
- Modules own their onboarding steps (billing module doesn't need to know)
|
|
- Steps appear/disappear based on which modules are enabled
|
|
- Easy to add new steps (just implement protocol in your module)
|
|
- Dashboard banner guides merchants without blocking signup
|
|
|
|
Usage:
|
|
# 1. Implement the protocol in your module
|
|
class MarketplaceOnboardingProvider:
|
|
@property
|
|
def onboarding_category(self) -> str:
|
|
return "marketplace"
|
|
|
|
def get_onboarding_steps(self) -> list[OnboardingStepDefinition]:
|
|
return [
|
|
OnboardingStepDefinition(
|
|
key="marketplace.connect_api",
|
|
title_key="marketplace.onboarding.connect_api.title",
|
|
description_key="marketplace.onboarding.connect_api.description",
|
|
icon="plug",
|
|
route_template="/store/{store_code}/letzshop",
|
|
order=200,
|
|
)
|
|
]
|
|
|
|
def is_step_completed(self, db, store_id, step_key) -> bool:
|
|
...
|
|
|
|
# 2. Register in module definition
|
|
def _get_onboarding_provider():
|
|
from app.modules.marketplace.services.marketplace_onboarding_service import (
|
|
marketplace_onboarding_provider,
|
|
)
|
|
return marketplace_onboarding_provider
|
|
|
|
marketplace_module = ModuleDefinition(
|
|
code="marketplace",
|
|
onboarding_provider=_get_onboarding_provider,
|
|
# ...
|
|
)
|
|
|
|
# 3. Steps appear automatically in dashboard when module is enabled
|
|
"""
|
|
|
|
from dataclasses import dataclass
|
|
from typing import TYPE_CHECKING, Protocol, runtime_checkable
|
|
|
|
if TYPE_CHECKING:
|
|
from sqlalchemy.orm import Session
|
|
|
|
|
|
@dataclass
|
|
class OnboardingStepDefinition:
|
|
"""
|
|
Definition of a single onboarding step.
|
|
|
|
Attributes:
|
|
key: Unique identifier (e.g., "marketplace.connect_api")
|
|
Format: "{module}.{step_name}" for consistency
|
|
title_key: i18n key for display title
|
|
description_key: i18n key for description text
|
|
icon: Lucide icon name for UI display (e.g., "plug", "package")
|
|
route_template: URL template with {store_code} placeholder
|
|
order: Display sort order (lower = first). Default 100.
|
|
category: Grouping category (typically matches module code)
|
|
"""
|
|
|
|
key: str
|
|
title_key: str
|
|
description_key: str
|
|
icon: str
|
|
route_template: str
|
|
order: int = 100
|
|
category: str = ""
|
|
|
|
|
|
@dataclass
|
|
class OnboardingStepStatus:
|
|
"""
|
|
An onboarding step paired with its completion status.
|
|
|
|
Attributes:
|
|
step: The step definition
|
|
completed: Whether the step has been completed
|
|
"""
|
|
|
|
step: OnboardingStepDefinition
|
|
completed: bool
|
|
|
|
|
|
@runtime_checkable
|
|
class OnboardingProviderProtocol(Protocol):
|
|
"""
|
|
Protocol for modules that provide onboarding steps.
|
|
|
|
Each module implements this to declare what setup steps are needed
|
|
after signup. The core module's OnboardingAggregator discovers and
|
|
aggregates all providers into a dashboard checklist banner.
|
|
|
|
Implementation Notes:
|
|
- Providers should be stateless (all data via db session)
|
|
- Return empty list from get_onboarding_steps() if no steps needed
|
|
- is_step_completed() should be efficient (called per step per page load)
|
|
- Use consistent key format: "{category}.{step_name}"
|
|
"""
|
|
|
|
@property
|
|
def onboarding_category(self) -> str:
|
|
"""
|
|
Category name for this provider's onboarding steps.
|
|
|
|
Should match the module code (e.g., "marketplace", "tenancy").
|
|
"""
|
|
...
|
|
|
|
def get_onboarding_steps(self) -> list[OnboardingStepDefinition]:
|
|
"""
|
|
Get onboarding step definitions provided by this module.
|
|
|
|
Returns:
|
|
List of OnboardingStepDefinition objects
|
|
"""
|
|
...
|
|
|
|
def is_step_completed(
|
|
self, db: "Session", store_id: int, step_key: str
|
|
) -> bool:
|
|
"""
|
|
Check if a specific onboarding step is completed for a store.
|
|
|
|
Args:
|
|
db: Database session for queries
|
|
store_id: ID of the store to check
|
|
step_key: The step key to check (from OnboardingStepDefinition.key)
|
|
|
|
Returns:
|
|
True if the step is completed
|
|
"""
|
|
...
|
|
|
|
|
|
__all__ = [
|
|
"OnboardingStepDefinition",
|
|
"OnboardingStepStatus",
|
|
"OnboardingProviderProtocol",
|
|
]
|