feat: production routing support for subdomain and custom domain modes
Some checks failed
CI / ruff (push) Successful in 10s
CI / pytest (push) Failing after 45m18s
CI / validate (push) Successful in 24s
CI / dependency-scanning (push) Successful in 30s
CI / docs (push) Has been skipped
CI / deploy (push) Has been skipped

Double-mount store routes at /store/* and /store/{store_code}/* so the
same handlers work in dev path-based, prod path-based, prod subdomain,
and prod custom-domain modes.  Wire StorePlatform.custom_subdomain into
StoreContextMiddleware for per-platform subdomain overrides.  Add admin
custom-domain management UI, fix stale /shop/ reset link, add
/merchants/ to reserved paths, and server-render window.STORE_CODE for
JS that previously parsed the URL.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-26 00:15:06 +01:00
parent 6a82d7c12d
commit ce5b54f27b
36 changed files with 822 additions and 151 deletions

18
main.py
View File

@@ -417,13 +417,18 @@ for route_info in merchant_page_routes:
# =============================================================================
# STORE PAGES
# =============================================================================
# Store dashboard pages - Register at TWO prefixes:
# 1. /store/* (for prod: subdomain/custom domain, after path rewrite by middleware)
# 2. /store/{store_code}/* (for dev: path-based, after /platforms/{code}/ strip)
logger.info("Auto-discovering store page routes...")
store_page_routes = get_store_page_routes()
logger.info(f" Found {len(store_page_routes)} store page route modules")
# Mount 1: /store/* (production subdomain/custom domain — store resolved by middleware)
logger.info(" Registering store routes at /store/*")
for route_info in store_page_routes:
prefix = f"/store{route_info.custom_prefix}" if route_info.custom_prefix else "/store"
logger.info(f" Registering {route_info.module_code} store pages at {prefix} (priority={route_info.priority})")
logger.info(f" - {route_info.module_code} at {prefix} (priority={route_info.priority})")
app.include_router(
route_info.router,
prefix=prefix,
@@ -431,6 +436,17 @@ for route_info in store_page_routes:
include_in_schema=route_info.include_in_schema,
)
# Mount 2: /store/{store_code}/* (dev path-based + production path-based demo/trial)
logger.info(" Registering store routes at /store/{store_code}/*")
for route_info in store_page_routes:
prefix = f"/store/{{store_code}}{route_info.custom_prefix}" if route_info.custom_prefix else "/store/{store_code}"
app.include_router(
route_info.router,
prefix=prefix,
tags=route_info.tags,
include_in_schema=False,
)
# =============================================================================
# STOREFRONT PAGES (Customer Shop)
# =============================================================================