feat: add multi-language (i18n) support for vendor dashboard and storefront

- Add database fields for language preferences:
  - Vendor: dashboard_language, storefront_language, storefront_languages
  - User: preferred_language
  - Customer: preferred_language

- Add language middleware for request-level language detection:
  - Cookie-based persistence
  - Browser Accept-Language fallback
  - Vendor storefront language constraints

- Add language API endpoints (/api/v1/language/*):
  - POST /set - Set language preference
  - GET /current - Get current language info
  - GET /list - List available languages
  - DELETE /clear - Clear preference

- Add i18n utilities (app/utils/i18n.py):
  - JSON-based translation loading
  - Jinja2 template integration
  - Language resolution helpers

- Add reusable language selector macros for templates
- Add languageSelector() Alpine.js component
- Add translation files (en, fr, de, lb) in static/locales/
- Add architecture rules documentation for language implementation
- Update marketplace-product-detail.js to use native language names

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-13 22:36:09 +01:00
parent d21cd366dc
commit d2b05441fc
30 changed files with 4615 additions and 33 deletions

20
main.py
View File

@@ -39,6 +39,7 @@ from app.exceptions.handler import setup_exception_handlers
# Import page routers
from app.routes import admin_pages, shop_pages, vendor_pages
from middleware.context import ContextMiddleware
from middleware.language import LanguageMiddleware
from middleware.logging import LoggingMiddleware
from middleware.theme_context import ThemeContextMiddleware
@@ -89,13 +90,15 @@ app.add_middleware(
# Desired execution order:
# 1. VendorContextMiddleware (detect vendor, extract clean_path)
# 2. ContextMiddleware (detect context using clean_path)
# 3. ThemeContextMiddleware (load theme)
# 4. LoggingMiddleware (log all requests)
# 3. LanguageMiddleware (detect language based on context)
# 4. ThemeContextMiddleware (load theme)
# 5. LoggingMiddleware (log all requests)
#
# Therefore we add them in REVERSE:
# - Add ThemeContextMiddleware FIRST (runs LAST in request)
# - Add ContextMiddleware SECOND
# - Add VendorContextMiddleware THIRD
# - Add LanguageMiddleware SECOND (runs after context)
# - Add ContextMiddleware THIRD
# - Add VendorContextMiddleware FOURTH
# - Add LoggingMiddleware LAST (runs FIRST for timing)
# ============================================================================
@@ -111,6 +114,10 @@ app.add_middleware(LoggingMiddleware)
logger.info("Adding ThemeContextMiddleware (detects and loads theme)")
app.add_middleware(ThemeContextMiddleware)
# Add language middleware (detects language after context is determined)
logger.info("Adding LanguageMiddleware (detects language based on context)")
app.add_middleware(LanguageMiddleware)
# Add context detection middleware (runs after vendor context extraction)
logger.info("Adding ContextMiddleware (detects context type using clean_path)")
app.add_middleware(ContextMiddleware)
@@ -125,8 +132,9 @@ logger.info(" Execution order (request →):")
logger.info(" 1. LoggingMiddleware (timing)")
logger.info(" 2. VendorContextMiddleware (vendor detection)")
logger.info(" 3. ContextMiddleware (context detection)")
logger.info(" 4. ThemeContextMiddleware (theme loading)")
logger.info(" 5. FastAPI Router")
logger.info(" 4. LanguageMiddleware (language detection)")
logger.info(" 5. ThemeContextMiddleware (theme loading)")
logger.info(" 6. FastAPI Router")
logger.info("=" * 80)
# ========================================