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:
@@ -0,0 +1,84 @@
|
||||
"""add_language_settings_to_vendor_user_customer
|
||||
|
||||
Revision ID: fcfdc02d5138
|
||||
Revises: b412e0b49c2e
|
||||
Create Date: 2025-12-13 20:08:27.120863
|
||||
|
||||
This migration adds language preference fields to support multi-language UI:
|
||||
- Vendor: default_language, dashboard_language, storefront_language
|
||||
- User: preferred_language
|
||||
- Customer: preferred_language
|
||||
|
||||
Supported languages: en (English), fr (French), de (German), lb (Luxembourgish)
|
||||
"""
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = 'fcfdc02d5138'
|
||||
down_revision: Union[str, None] = 'b412e0b49c2e'
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
# ========================================================================
|
||||
# Vendor language settings
|
||||
# ========================================================================
|
||||
# default_language: Default language for vendor content (products, etc.)
|
||||
op.add_column(
|
||||
'vendors',
|
||||
sa.Column('default_language', sa.String(5), nullable=False, server_default='fr')
|
||||
)
|
||||
# dashboard_language: Language for vendor team dashboard UI
|
||||
op.add_column(
|
||||
'vendors',
|
||||
sa.Column('dashboard_language', sa.String(5), nullable=False, server_default='fr')
|
||||
)
|
||||
# storefront_language: Default language for customer-facing shop
|
||||
op.add_column(
|
||||
'vendors',
|
||||
sa.Column('storefront_language', sa.String(5), nullable=False, server_default='fr')
|
||||
)
|
||||
# storefront_languages: JSON array of enabled languages for storefront
|
||||
# Allows vendors to enable/disable specific languages
|
||||
op.add_column(
|
||||
'vendors',
|
||||
sa.Column(
|
||||
'storefront_languages',
|
||||
sa.JSON,
|
||||
nullable=False,
|
||||
server_default='["fr", "de", "en"]'
|
||||
)
|
||||
)
|
||||
|
||||
# ========================================================================
|
||||
# User language preference
|
||||
# ========================================================================
|
||||
# preferred_language: User's preferred UI language (NULL = use context default)
|
||||
op.add_column(
|
||||
'users',
|
||||
sa.Column('preferred_language', sa.String(5), nullable=True)
|
||||
)
|
||||
|
||||
# ========================================================================
|
||||
# Customer language preference
|
||||
# ========================================================================
|
||||
# preferred_language: Customer's preferred language (NULL = use storefront default)
|
||||
op.add_column(
|
||||
'customers',
|
||||
sa.Column('preferred_language', sa.String(5), nullable=True)
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
# Remove columns in reverse order
|
||||
op.drop_column('customers', 'preferred_language')
|
||||
op.drop_column('users', 'preferred_language')
|
||||
op.drop_column('vendors', 'storefront_languages')
|
||||
op.drop_column('vendors', 'storefront_language')
|
||||
op.drop_column('vendors', 'dashboard_language')
|
||||
op.drop_column('vendors', 'default_language')
|
||||
Reference in New Issue
Block a user