feat: platform-aware storefront routing and billing improvements

Overhaul storefront URL routing to be platform-aware:
- Dev: /platforms/{code}/storefront/{store_code}/
- Prod: subdomain.platform.lu/ (internally rewritten to /storefront/)
- Add subdomain detection in PlatformContextMiddleware
- Add /storefront/ path rewrite for prod mode (subdomain/custom domain)
- Remove all silent platform fallbacks (platform_id=1)
- Add require_platform dependency for clean endpoint validation
- Update route registration, templates, module definitions, base_url calc
- Update StoreContextMiddleware for /storefront/ path detection
- Remove /stores/ from FrontendDetector STOREFRONT_PATH_PREFIXES

Billing service improvements:
- Add store_platform_sync_service to keep store_platforms in sync
- Make tier lookups platform-aware across billing services
- Add tiers for all platforms in seed data
- Add demo subscriptions to seed

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-23 23:42:41 +01:00
parent d36783a7f1
commit 32acc76b49
56 changed files with 951 additions and 306 deletions

View File

@@ -418,7 +418,7 @@ def create_admin_settings(db: Session) -> int:
def create_subscription_tiers(db: Session, platform: Platform) -> int:
"""Create default subscription tiers for the OMS platform."""
"""Create default subscription tiers for a platform."""
tier_defs = [
{
@@ -458,11 +458,14 @@ def create_subscription_tiers(db: Session, platform: Platform) -> int:
tiers_created = 0
for tdef in tier_defs:
existing = db.execute(
select(SubscriptionTier).where(SubscriptionTier.code == tdef["code"])
select(SubscriptionTier).where(
SubscriptionTier.code == tdef["code"],
SubscriptionTier.platform_id == platform.id,
)
).scalar_one_or_none()
if existing:
print_warning(f"Tier already exists: {existing.name} ({existing.code})")
print_warning(f"Tier already exists: {existing.name} ({existing.code}) for {platform.name}")
continue
tier = SubscriptionTier(
@@ -620,13 +623,10 @@ def initialize_production(db: Session, auth_manager: AuthManager):
print_step(5, "Creating admin settings...")
create_admin_settings(db)
# Step 6: Seed subscription tiers
# Step 6: Seed subscription tiers for all platforms
print_step(6, "Seeding subscription tiers...")
oms_platform = next((p for p in platforms if p.code == "oms"), None)
if oms_platform:
create_subscription_tiers(db, oms_platform)
else:
print_warning("OMS platform not found, skipping tier seeding")
for platform in platforms:
create_subscription_tiers(db, platform)
# Step 7: Create platform module records
print_step(7, "Creating platform module records...")