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

@@ -147,6 +147,7 @@ marketplace_module = ModuleDefinition(
icon="download",
route="/store/{store_code}/marketplace",
order=30,
requires_permission="marketplace.view_integration",
),
],
),
@@ -162,6 +163,7 @@ marketplace_module = ModuleDefinition(
icon="external-link",
route="/store/{store_code}/letzshop",
order=20,
requires_permission="marketplace.view_integration",
),
],
),

View File

@@ -91,5 +91,15 @@
"manage_integration_desc": "Marktplatz-Integration konfigurieren",
"sync_products": "Produkte synchronisieren",
"sync_products_desc": "Produkte mit dem Marktplatz synchronisieren"
},
"onboarding": {
"connect_api": {
"title": "Letzshop-API verbinden",
"description": "Konfigurieren Sie Ihren API-Schlüssel für die Synchronisation mit Letzshop"
},
"import_products": {
"title": "Produkte importieren",
"description": "Importieren Sie Ihren Produktkatalog von Letzshop"
}
}
}

View File

@@ -1,109 +1,119 @@
{
"menu": {
"marketplace": "Marketplace",
"letzshop": "Letzshop",
"products_inventory": "Products & Inventory",
"marketplace_import": "Marketplace Import",
"sales_orders": "Sales & Orders",
"letzshop_orders": "Letzshop Orders"
},
"permissions": {
"view_integration": "View Integration",
"view_integration_desc": "View marketplace integration settings",
"manage_integration": "Manage Integration",
"manage_integration_desc": "Configure marketplace integration",
"sync_products": "Sync Products",
"sync_products_desc": "Synchronize products with marketplace"
},
"marketplace": {
"title": "Marketplace",
"import": "Import",
"export": "Export",
"sync": "Sync",
"source": "Source",
"source_url": "Source URL",
"import_products": "Import Products",
"start_import": "Start Import",
"importing": "Importing...",
"import_complete": "Import Complete",
"import_failed": "Import Failed",
"import_history": "Import History",
"job_id": "Job ID",
"started_at": "Started At",
"completed_at": "Completed At",
"duration": "Duration",
"imported_count": "Imported",
"error_count": "Errors",
"total_processed": "Total Processed",
"progress": "Progress",
"no_import_jobs": "No import jobs yet",
"start_first_import": "Start your first import using the form above"
},
"letzshop": {
"title": "Letzshop Integration",
"connection": "Connection",
"credentials": "Credentials",
"api_key": "API Key",
"api_endpoint": "API Endpoint",
"auto_sync": "Auto Sync",
"sync_interval": "Sync Interval",
"every_hour": "Every hour",
"every_day": "Every day",
"test_connection": "Test Connection",
"save_credentials": "Save Credentials",
"connection_success": "Connection successful",
"connection_failed": "Connection failed",
"last_sync": "Last Sync",
"sync_status": "Sync Status",
"import_orders": "Import Orders",
"export_products": "Export Products",
"no_credentials": "Configure your API key in Settings to get started",
"carriers": {
"dhl": "DHL",
"ups": "UPS",
"fedex": "FedEx",
"dpd": "DPD",
"gls": "GLS",
"post_luxembourg": "Post Luxembourg",
"other": "Other"
"menu": {
"marketplace": "Marketplace",
"letzshop": "Letzshop",
"products_inventory": "Products & Inventory",
"marketplace_import": "Marketplace Import",
"sales_orders": "Sales & Orders",
"letzshop_orders": "Letzshop Orders"
},
"permissions": {
"view_integration": "View Integration",
"view_integration_desc": "View marketplace integration settings",
"manage_integration": "Manage Integration",
"manage_integration_desc": "Configure marketplace integration",
"sync_products": "Sync Products",
"sync_products_desc": "Synchronize products with marketplace"
},
"marketplace": {
"title": "Marketplace",
"import": "Import",
"export": "Export",
"sync": "Sync",
"source": "Source",
"source_url": "Source URL",
"import_products": "Import Products",
"start_import": "Start Import",
"importing": "Importing...",
"import_complete": "Import Complete",
"import_failed": "Import Failed",
"import_history": "Import History",
"job_id": "Job ID",
"started_at": "Started At",
"completed_at": "Completed At",
"duration": "Duration",
"imported_count": "Imported",
"error_count": "Errors",
"total_processed": "Total Processed",
"progress": "Progress",
"no_import_jobs": "No import jobs yet",
"start_first_import": "Start your first import using the form above"
},
"letzshop": {
"title": "Letzshop Integration",
"connection": "Connection",
"credentials": "Credentials",
"api_key": "API Key",
"api_endpoint": "API Endpoint",
"auto_sync": "Auto Sync",
"sync_interval": "Sync Interval",
"every_hour": "Every hour",
"every_day": "Every day",
"test_connection": "Test Connection",
"save_credentials": "Save Credentials",
"connection_success": "Connection successful",
"connection_failed": "Connection failed",
"last_sync": "Last Sync",
"sync_status": "Sync Status",
"import_orders": "Import Orders",
"export_products": "Export Products",
"no_credentials": "Configure your API key in Settings to get started",
"carriers": {
"dhl": "DHL",
"ups": "UPS",
"fedex": "FedEx",
"dpd": "DPD",
"gls": "GLS",
"post_luxembourg": "Post Luxembourg",
"other": "Other"
}
},
"messages": {
"no_error_details_available": "No error details available",
"failed_to_load_error_details": "Failed to load error details",
"copied_to_clipboard": "Copied to clipboard",
"failed_to_copy_to_clipboard": "Failed to copy to clipboard",
"please_configure_api_key_first": "Please configure your API key first",
"please_enter_api_key": "Please enter an API key",
"please_fill_in_all_fields": "Please fill in all fields"
},
"confirmations": {
"remove_letzshop_credentials": "Are you sure you want to remove your Letzshop credentials?",
"confirm_order": "Confirm this order?",
"reject_order": "Reject this order? This action cannot be undone.",
"remove_letzshop_config_store": "Are you sure you want to remove Letzshop configuration for this store?",
"decline_order": "Are you sure you want to decline this order? All items will be marked as unavailable.",
"confirm_all_items": "Are you sure you want to confirm all items in this order?",
"decline_all_items": "Are you sure you want to decline all items in this order?",
"remove_letzshop_config": "Are you sure you want to remove the Letzshop configuration? This will disable all Letzshop features for this store.",
"ignore_exception": "Are you sure you want to ignore this exception? The order will still be blocked from confirmation."
},
"features": {
"letzshop_sync": {
"name": "Lëtzshop Sync",
"description": "Synchronize products with Lëtzshop marketplace"
},
"api_access": {
"name": "API Access",
"description": "Access to the platform API"
},
"webhooks": {
"name": "Webhooks",
"description": "Real-time event notifications via webhooks"
},
"custom_integrations": {
"name": "Custom Integrations",
"description": "Build custom integrations with the platform"
}
},
"onboarding": {
"connect_api": {
"title": "Connect Letzshop API",
"description": "Configure your API key to sync with Letzshop"
},
"import_products": {
"title": "Import your products",
"description": "Import your product catalog from Letzshop"
}
}
},
"messages": {
"no_error_details_available": "No error details available",
"failed_to_load_error_details": "Failed to load error details",
"copied_to_clipboard": "Copied to clipboard",
"failed_to_copy_to_clipboard": "Failed to copy to clipboard",
"please_configure_api_key_first": "Please configure your API key first",
"please_enter_api_key": "Please enter an API key",
"please_fill_in_all_fields": "Please fill in all fields"
},
"confirmations": {
"remove_letzshop_credentials": "Are you sure you want to remove your Letzshop credentials?",
"confirm_order": "Confirm this order?",
"reject_order": "Reject this order? This action cannot be undone.",
"remove_letzshop_config_store": "Are you sure you want to remove Letzshop configuration for this store?",
"decline_order": "Are you sure you want to decline this order? All items will be marked as unavailable.",
"confirm_all_items": "Are you sure you want to confirm all items in this order?",
"decline_all_items": "Are you sure you want to decline all items in this order?",
"remove_letzshop_config": "Are you sure you want to remove the Letzshop configuration? This will disable all Letzshop features for this store.",
"ignore_exception": "Are you sure you want to ignore this exception? The order will still be blocked from confirmation."
},
"features": {
"letzshop_sync": {
"name": "Lëtzshop Sync",
"description": "Synchronize products with Lëtzshop marketplace"
},
"api_access": {
"name": "API Access",
"description": "Access to the platform API"
},
"webhooks": {
"name": "Webhooks",
"description": "Real-time event notifications via webhooks"
},
"custom_integrations": {
"name": "Custom Integrations",
"description": "Build custom integrations with the platform"
}
}
}

View File

@@ -91,5 +91,15 @@
"manage_integration_desc": "Configurer l'intégration marketplace",
"sync_products": "Synchroniser les produits",
"sync_products_desc": "Synchroniser les produits avec le marketplace"
},
"onboarding": {
"connect_api": {
"title": "Connecter l'API Letzshop",
"description": "Configurez votre clé API pour synchroniser avec Letzshop"
},
"import_products": {
"title": "Importer vos produits",
"description": "Importez votre catalogue de produits depuis Letzshop"
}
}
}

View File

@@ -91,5 +91,15 @@
"manage_integration_desc": "Marché-Integratioun konfiguréieren",
"sync_products": "Produiten synchroniséieren",
"sync_products_desc": "Produiten mam Marché synchroniséieren"
},
"onboarding": {
"connect_api": {
"title": "Letzshop-API verbannen",
"description": "Konfiguréiert Ären API-Schlëssel fir mat Letzshop ze synchroniséieren"
},
"import_products": {
"title": "Produkter importéieren",
"description": "Importéiert Äre Produktkatalog vu Letzshop"
}
}
}

View File

@@ -27,8 +27,8 @@ class MarketplaceOnboardingProvider:
return [
OnboardingStepDefinition(
key="marketplace.connect_api",
title_key="onboarding.marketplace.connect_api.title",
description_key="onboarding.marketplace.connect_api.description",
title_key="marketplace.onboarding.connect_api.title",
description_key="marketplace.onboarding.connect_api.description",
icon="plug",
route_template="/store/{store_code}/letzshop",
order=200,
@@ -36,8 +36,8 @@ class MarketplaceOnboardingProvider:
),
OnboardingStepDefinition(
key="marketplace.import_products",
title_key="onboarding.marketplace.import_products.title",
description_key="onboarding.marketplace.import_products.description",
title_key="marketplace.onboarding.import_products.title",
description_key="marketplace.onboarding.import_products.description",
icon="package",
route_template="/store/{store_code}/marketplace",
order=210,