diff --git a/app/modules/loyalty/templates/loyalty/storefront/dashboard.html b/app/modules/loyalty/templates/loyalty/storefront/dashboard.html index edbc11b8..4e70cecd 100644 --- a/app/modules/loyalty/templates/loyalty/storefront/dashboard.html +++ b/app/modules/loyalty/templates/loyalty/storefront/dashboard.html @@ -230,5 +230,5 @@ {% endblock %} {% block extra_scripts %} - + {% endblock %} diff --git a/app/modules/loyalty/templates/loyalty/storefront/enroll.html b/app/modules/loyalty/templates/loyalty/storefront/enroll.html index 2673239b..81fcb138 100644 --- a/app/modules/loyalty/templates/loyalty/storefront/enroll.html +++ b/app/modules/loyalty/templates/loyalty/storefront/enroll.html @@ -119,7 +119,7 @@ class="w-full py-3 px-4 text-white font-semibold rounded-lg transition-colors disabled:opacity-50" :style="'background-color: ' + (program?.card_color || 'var(--color-primary)')"> - + @@ -170,5 +170,5 @@ {% endblock %} {% block extra_scripts %} - + {% endblock %} diff --git a/app/modules/loyalty/templates/loyalty/storefront/history.html b/app/modules/loyalty/templates/loyalty/storefront/history.html index f3f94c4a..91faa089 100644 --- a/app/modules/loyalty/templates/loyalty/storefront/history.html +++ b/app/modules/loyalty/templates/loyalty/storefront/history.html @@ -105,5 +105,5 @@ {% endblock %} {% block extra_scripts %} - + {% endblock %} diff --git a/middleware/store_context.py b/middleware/store_context.py index 6e756537..c79e9c6b 100644 --- a/middleware/store_context.py +++ b/middleware/store_context.py @@ -295,13 +295,17 @@ class StoreContextManager: Extract store context from Referer header. Used for storefront API requests where store context comes from the page - that made the API call (e.g., JavaScript on /stores/orion/storefront/products - calling /api/v1/storefront/products). + that made the API call (e.g., JavaScript on /storefront/FASHIONHUB/loyalty/join + calling /api/v1/storefront/loyalty/program). + + Platform-aware: uses request.state.platform.domain (e.g. rewardflow.lu) + for subdomain detection, not just settings.main_domain (wizard.lu). Extracts store from Referer URL patterns: - - http://localhost:8000/stores/orion/storefront/... → orion - - http://orion.platform.com/storefront/... → orion (subdomain) # noqa - - http://custom-domain.com/storefront/... → custom-domain.com # noqa + - localhost:8000/platforms/loyalty/storefront/FASHIONHUB/... → FASHIONHUB (dev path) + - rewardflow.lu/storefront/FASHIONHUB/... → FASHIONHUB (prod platform domain path) + - fashionhub.rewardflow.lu/... → fashionhub (prod platform subdomain) + - custom-domain.com/... → custom-domain.com (prod custom domain) Returns store context dict or None if unable to extract. """ @@ -331,20 +335,34 @@ class StoreContextManager: }, ) - # Method 1: Path-based detection from referer path (local hosts only) - # /platforms/oms/storefront/WIZATECH/products → WIZATECH - # /stores/orion/storefront/products → orion - # /storefront/WIZATECH/products → WIZATECH - # Note: For subdomain/custom domain hosts, the store code is NOT in the path - # (e.g., orion.platform.com/storefront/products — "products" is a page, not a store) + # Determine platform domain for platform-aware detection + # (e.g. rewardflow.lu from the loyalty platform object) + platform = getattr(request.state, "platform", None) + platform_own_domain = getattr(platform, "domain", None) if platform else None + is_platform_domain = ( + platform_own_domain and referer_host == platform_own_domain + ) + is_subdomain_of_platform = ( + platform_own_domain + and referer_host != platform_own_domain + and referer_host.endswith(f".{platform_own_domain}") + ) + + # Method 1: Path-based detection from referer path + # Works on localhost (dev) AND on platform domains (prod path-based routing) + # /platforms/oms/storefront/WIZATECH/products → WIZATECH (dev) + # /storefront/FASHIONHUB/loyalty/join → FASHIONHUB (prod platform domain) + # Note: For subdomain hosts, path segments after /storefront/ are pages, not store codes is_local_referer = referer_host in ("localhost", "127.0.0.1", "testserver") - if is_local_referer and referer_path.startswith("/platforms/"): + use_path_detection = is_local_referer or is_platform_domain + + if use_path_detection and referer_path.startswith("/platforms/"): # Strip /platforms/{code}/ to get clean path after_platforms = referer_path[11:] # Remove "/platforms/" parts = after_platforms.split("/", 1) referer_path = "/" + parts[1] if len(parts) > 1 and parts[1] else "/" - if is_local_referer and referer_path.startswith(("/stores/", "/store/", "/storefront/")): + if use_path_detection and referer_path.startswith(("/stores/", "/store/", "/storefront/")): if referer_path.startswith("/storefront/"): prefix = "/storefront/" elif referer_path.startswith("/stores/"): @@ -371,7 +389,25 @@ class StoreContextManager: } # Method 2: Subdomain detection from referer host - # orion.platform.com → orion + # fashionhub.rewardflow.lu → fashionhub (platform subdomain) + # store1.wizard.lu → store1 (main domain subdomain) + if is_subdomain_of_platform: + subdomain = referer_host.split(".")[0] + logger.debug( + f"[STORE] Extracted store from Referer platform subdomain: {subdomain}", + extra={ + "subdomain": subdomain, + "method": "referer_platform_subdomain", + "platform_domain": platform_own_domain, + }, + ) + return { + "subdomain": subdomain, + "detection_method": "referer_subdomain", + "host": referer_host, + "referer": referer, + } + main_domain = getattr(settings, "main_domain", "platform.com") if "." in referer_host: parts = referer_host.split(".") @@ -397,6 +433,8 @@ class StoreContextManager: # custom-shop.com → custom-shop.com is_custom_domain = ( referer_host + and not is_platform_domain + and not is_subdomain_of_platform and not referer_host.endswith(f".{main_domain}") and referer_host != main_domain and referer_host not in ["localhost", "127.0.0.1"]