feat: storefront subscription access guard + module-driven nav + URL rename
Add StorefrontAccessMiddleware that blocks storefront access for stores without an active subscription, returning a multilingual unavailable page (en/fr/de/lb) for page requests and JSON 403 for API requests. Multi-platform aware: resolves subscription for detected platform with fallback to primary. Also includes yesterday's session work: - Module-driven storefront navigation via FrontendType.STOREFRONT menu declarations - shop/ → storefront/ URL rename across 30+ templates - Subscription context (tier_code) passed to storefront templates Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -146,6 +146,29 @@ def get_context_for_frontend(
|
||||
f"[CONTEXT] {len(modules_with_providers)} modules have providers but none contributed"
|
||||
)
|
||||
|
||||
# Pass enabled module codes to templates for conditional rendering
|
||||
context["enabled_modules"] = enabled_module_codes
|
||||
|
||||
# For storefront, build nav menu structure from module declarations
|
||||
if frontend_type == FrontendType.STOREFRONT:
|
||||
from app.modules.core.services.menu_discovery_service import (
|
||||
menu_discovery_service,
|
||||
)
|
||||
|
||||
platform_id = platform.id if platform else None
|
||||
sections = menu_discovery_service.get_menu_sections_for_frontend(
|
||||
db, FrontendType.STOREFRONT, platform_id
|
||||
)
|
||||
# Build dict of section_id -> list of enabled items for easy template access
|
||||
storefront_nav: dict[str, list] = {}
|
||||
for section in sections:
|
||||
enabled_items = [
|
||||
item for item in section.items if item.is_module_enabled
|
||||
]
|
||||
if enabled_items:
|
||||
storefront_nav[section.id] = enabled_items
|
||||
context["storefront_nav"] = storefront_nav
|
||||
|
||||
# Add any extra context passed by the caller
|
||||
if extra_context:
|
||||
context.update(extra_context)
|
||||
@@ -318,6 +341,10 @@ def get_storefront_context(
|
||||
)
|
||||
base_url = f"{full_prefix}{store.subdomain}/"
|
||||
|
||||
# Read subscription info set by StorefrontAccessMiddleware
|
||||
subscription = getattr(request.state, "subscription", None)
|
||||
subscription_tier = getattr(request.state, "subscription_tier", None)
|
||||
|
||||
# Build storefront-specific base context
|
||||
storefront_base = {
|
||||
"store": store,
|
||||
@@ -325,6 +352,11 @@ def get_storefront_context(
|
||||
"clean_path": clean_path,
|
||||
"access_method": access_method,
|
||||
"base_url": base_url,
|
||||
"enabled_modules": set(),
|
||||
"storefront_nav": {},
|
||||
"subscription": subscription,
|
||||
"subscription_tier": subscription_tier,
|
||||
"tier_code": subscription_tier.code if subscription_tier else None,
|
||||
}
|
||||
|
||||
# If no db session, return just the base context
|
||||
|
||||
Reference in New Issue
Block a user