feat: multi-module improvements across merchant, store, i18n, and customer systems
All checks were successful
CI / ruff (push) Successful in 12s
CI / pytest (push) Successful in 50m57s
CI / validate (push) Successful in 24s
CI / dependency-scanning (push) Successful in 29s
CI / docs (push) Successful in 40s
CI / deploy (push) Successful in 51s

- Fix platform-grouped merchant sidebar menu with core items at root level
- Add merchant store management (detail page, create store, team page)
- Fix store settings 500 error by removing dead stripe/API tab
- Move onboarding translations to module-owned locale files
- Fix onboarding banner i18n with server-side rendering + context inheritance
- Refactor login language selectors to use languageSelector() function (LANG-002)
- Move HTTPException handling to global exception handler in merchant routes (API-003)
- Add language selector to all login pages and portal headers
- Fix customer module: drop order stats from customer model, add to orders module
- Fix admin menu config visibility for super admin platform context
- Fix storefront auth and layout issues
- Add missing i18n translations for onboarding steps (en/fr/de/lb)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-08 23:48:25 +01:00
parent f141cc4e6a
commit a77a8a3a98
113 changed files with 3741 additions and 2923 deletions

View File

@@ -110,3 +110,62 @@ class TestMenuServiceMerchantRendering:
without_ids = {s.id for s in without_loyalty}
assert "loyalty" in with_ids
assert "loyalty" not in without_ids
@pytest.mark.unit
@pytest.mark.core
class TestMenuServiceMerchantByPlatform:
"""Test get_merchant_menu_by_platform grouping logic."""
def setup_method(self):
self.service = MenuService()
def test_core_sections_contain_only_core_items(self, db):
"""Core sections should only have items from core modules."""
from app.modules.core.services.menu_discovery_service import (
menu_discovery_service,
)
from app.modules.registry import MODULES
core_codes = {code for code, mod in MODULES.items() if mod.is_core}
core_sections = menu_discovery_service.get_menu_sections_for_frontend(
db,
FrontendType.MERCHANT,
enabled_module_codes=core_codes,
)
for section in core_sections:
section.items = [i for i in section.items if i.module_code in core_codes]
for section in core_sections:
for item in section.items:
assert item.module_code in core_codes, (
f"Non-core item '{item.id}' (module={item.module_code}) "
f"found in core section '{section.id}'"
)
def test_non_core_sections_for_loyalty(self, db):
"""Non-core modules like loyalty produce merchant menu sections."""
from app.modules.core.services.menu_discovery_service import (
menu_discovery_service,
)
from app.modules.registry import MODULES
core_codes = {code for code, mod in MODULES.items() if mod.is_core}
non_core = {"loyalty"}
sections = menu_discovery_service.get_menu_sections_for_frontend(
db,
FrontendType.MERCHANT,
enabled_module_codes=non_core,
)
sections = [
s
for s in sections
if any(i.module_code in non_core for i in s.items)
]
assert len(sections) > 0, "Loyalty module should produce merchant menu sections"
for section in sections:
for item in section.items:
assert item.module_code not in core_codes