Files
orion/app/modules/tenancy/services/tenancy_onboarding.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

56 lines
1.6 KiB
Python

# app/modules/tenancy/services/tenancy_onboarding.py
"""
Onboarding provider for the tenancy module.
Provides the "Customize your store" onboarding step that is always present
for all platforms. Completed when the store has a description or a logo.
"""
import logging
from sqlalchemy.orm import Session
from app.modules.contracts.onboarding import OnboardingStepDefinition
logger = logging.getLogger(__name__)
class TenancyOnboardingProvider:
"""Onboarding provider for tenancy module (always present)."""
@property
def onboarding_category(self) -> str:
return "tenancy"
def get_onboarding_steps(self) -> list[OnboardingStepDefinition]:
return [
OnboardingStepDefinition(
key="tenancy.customize_store",
title_key="onboarding.tenancy.customize_store.title",
description_key="onboarding.tenancy.customize_store.description",
icon="settings",
route_template="/store/{store_code}/settings",
order=100,
category="tenancy",
),
]
def is_step_completed(
self, db: Session, store_id: int, step_key: str
) -> bool:
if step_key != "tenancy.customize_store":
return False
from app.modules.tenancy.models.store import Store
store = db.query(Store).filter(Store.id == store_id).first()
if not store:
return False
has_description = bool(store.description and store.description.strip())
has_logo = bool(store.get_logo_url())
return has_description or has_logo
tenancy_onboarding_provider = TenancyOnboardingProvider()