refactor: complete module-driven architecture migration

This commit completes the migration to a fully module-driven architecture:

## Models Migration
- Moved all domain models from models/database/ to their respective modules:
  - tenancy: User, Admin, Vendor, Company, Platform, VendorDomain, etc.
  - cms: MediaFile, VendorTheme
  - messaging: Email, VendorEmailSettings, VendorEmailTemplate
  - core: AdminMenuConfig
- models/database/ now only contains Base and TimestampMixin (infrastructure)

## Schemas Migration
- Moved all domain schemas from models/schema/ to their respective modules:
  - tenancy: company, vendor, admin, team, vendor_domain
  - cms: media, image, vendor_theme
  - messaging: email
- models/schema/ now only contains base.py and auth.py (infrastructure)

## Routes Migration
- Moved admin routes from app/api/v1/admin/ to modules:
  - menu_config.py -> core module
  - modules.py -> tenancy module
  - module_config.py -> tenancy module
- app/api/v1/admin/ now only aggregates auto-discovered module routes

## Menu System
- Implemented module-driven menu system with MenuDiscoveryService
- Extended FrontendType enum: PLATFORM, ADMIN, VENDOR, STOREFRONT
- Added MenuItemDefinition and MenuSectionDefinition dataclasses
- Each module now defines its own menu items in definition.py
- MenuService integrates with MenuDiscoveryService for template rendering

## Documentation
- Updated docs/architecture/models-structure.md
- Updated docs/architecture/menu-management.md
- Updated architecture validation rules for new exceptions

## Architecture Validation
- Updated MOD-019 rule to allow base.py in models/schema/
- Created core module exceptions.py and schemas/ directory
- All validation errors resolved (only warnings remain)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-02-01 21:02:56 +01:00
parent 09d7d282c6
commit d7a0ff8818
307 changed files with 5536 additions and 3826 deletions

View File

@@ -1,126 +1,203 @@
{
"title": "Gestion de contenu",
"description": "Gestion des pages de contenu, de la bibliothèque de médias et des thèmes",
"pages": {
"title": "Pages de contenu",
"subtitle": "Gérez les pages de contenu de la plateforme et des vendeurs",
"create": "Créer une page",
"edit": "Modifier la page",
"delete": "Supprimer la page",
"list": "Toutes les pages",
"empty": "Aucune page trouvée",
"empty_search": "Aucune page ne correspond à votre recherche",
"create_first": "Créer la première page"
},
"page": {
"title": "Titre de la page",
"slug": "Slug",
"slug_help": "Identifiant URL (minuscules, chiffres, tirets uniquement)",
"content": "Contenu",
"content_format": "Format du contenu",
"format_html": "HTML",
"format_markdown": "Markdown",
"platform": "Plateforme",
"vendor_override": "Remplacement vendeur",
"vendor_override_none": "Aucun (page par défaut)",
"vendor_override_help_default": "Ceci est une page par défaut pour toute la plateforme",
"vendor_override_help_vendor": "Cette page remplace la page par défaut pour le vendeur sélectionné"
},
"tiers": {
"platform": "Marketing plateforme",
"vendor_default": "Défaut vendeur",
"vendor_override": "Remplacement vendeur"
},
"seo": {
"title": "SEO & Métadonnées",
"meta_description": "Meta Description",
"meta_description_help": "caractères (150-160 recommandés)",
"meta_keywords": "Mots-clés",
"meta_keywords_placeholder": "mot-clé1, mot-clé2, mot-clé3"
},
"navigation": {
"title": "Navigation & Affichage",
"display_order": "Ordre d'affichage",
"display_order_help": "Plus bas = premier",
"show_in_header": "Afficher dans l'en-tête",
"show_in_footer": "Afficher dans le pied de page",
"show_in_legal": "Afficher dans les mentions légales",
"show_in_legal_help": "Barre en bas à côté du copyright"
},
"publishing": {
"published": "Publié",
"draft": "Brouillon",
"publish_help": "Rendre cette page visible au public"
},
"homepage": {
"title": "Sections de la page d'accueil",
"subtitle": "Contenu multilingue",
"loading": "Chargement des sections...",
"hero": {
"title": "Section Hero",
"badge_text": "Texte du badge",
"main_title": "Titre",
"subtitle": "Sous-titre",
"buttons": "Boutons",
"add_button": "Ajouter un bouton"
"platform": {
"nav": {
"pricing": "Tarifs",
"find_shop": "Trouvez votre boutique",
"start_trial": "Essai gratuit",
"admin_login": "Connexion Admin",
"vendor_login": "Connexion Vendeur",
"toggle_menu": "Basculer le menu",
"toggle_dark_mode": "Basculer le mode sombre"
},
"features": {
"title": "Section Fonctionnalités",
"section_title": "Titre de la section",
"cards": "Cartes de fonctionnalités",
"add_card": "Ajouter une carte",
"icon": "Nom de l'icône",
"feature_title": "Titre",
"feature_description": "Description"
"hero": {
"badge": "Essai gratuit de {trial_days} jours - Aucune carte de crédit requise",
"title": "OMS léger pour les vendeurs Letzshop",
"subtitle": "Gestion des commandes, stocks et facturation conçue pour le e-commerce luxembourgeois. Arrêtez de jongler avec les tableurs. Gérez votre entreprise.",
"cta_trial": "Essai gratuit",
"cta_find_shop": "Trouvez votre boutique Letzshop"
},
"pricing": {
"title": "Section Tarifs",
"section_title": "Titre de la section",
"use_tiers": "Utiliser les niveaux d'abonnement de la base de données",
"use_tiers_help": "Si activé, les cartes de tarifs sont extraites dynamiquement de la configuration des niveaux d'abonnement."
"title": "Tarification simple et transparente",
"subtitle": "Choisissez le plan adapté à votre entreprise. Tous les plans incluent un essai gratuit de {trial_days} jours.",
"monthly": "Mensuel",
"annual": "Annuel",
"save_months": "Économisez 2 mois !",
"most_popular": "LE PLUS POPULAIRE",
"recommended": "RECOMMANDÉ",
"contact_sales": "Contactez-nous",
"start_trial": "Essai gratuit",
"per_month": "/mois",
"per_year": "/an",
"custom": "Sur mesure",
"orders_per_month": "{count} commandes/mois",
"unlimited_orders": "Commandes illimitées",
"products_limit": "{count} produits",
"unlimited_products": "Produits illimités",
"team_members": "{count} membres d'équipe",
"unlimited_team": "Équipe illimitée",
"letzshop_sync": "Synchronisation Letzshop",
"eu_vat_invoicing": "Facturation TVA UE",
"analytics_dashboard": "Tableau de bord analytique",
"api_access": "Accès API",
"multi_channel": "Intégration multi-canal",
"products": "produits",
"team_member": "membre d'équipe",
"unlimited": "Illimité",
"order_history": "mois d'historique",
"trial_note": "Tous les plans incluent un essai gratuit de {trial_days} jours. Aucune carte de crédit requise.",
"back_home": "Retour à l'accueil"
},
"features": {
"letzshop_sync": "Synchronisation Letzshop",
"inventory_basic": "Gestion de stock de base",
"inventory_locations": "Emplacements d'entrepôt",
"inventory_purchase_orders": "Bons de commande",
"invoice_lu": "Facturation TVA Luxembourg",
"invoice_eu_vat": "Facturation TVA UE",
"invoice_bulk": "Facturation en masse",
"customer_view": "Liste des clients",
"customer_export": "Export clients",
"analytics_dashboard": "Tableau de bord analytique",
"accounting_export": "Export comptable",
"api_access": "Accès API",
"automation_rules": "Règles d'automatisation",
"team_roles": "Rôles et permissions",
"white_label": "Option marque blanche",
"multi_vendor": "Support multi-vendeurs",
"custom_integrations": "Intégrations personnalisées",
"sla_guarantee": "Garantie SLA",
"dedicated_support": "Gestionnaire de compte dédié"
},
"addons": {
"title": "Améliorez votre plateforme",
"subtitle": "Ajoutez votre marque, e-mail professionnel et sécurité renforcée.",
"per_year": "/an",
"per_month": "/mois",
"custom_domain": "Domaine personnalisé",
"custom_domain_desc": "Utilisez votre propre domaine (mondomaine.com)",
"premium_ssl": "SSL Premium",
"premium_ssl_desc": "Certificat EV pour les badges de confiance",
"email_package": "Pack Email",
"email_package_desc": "Adresses e-mail professionnelles"
},
"find_shop": {
"title": "Trouvez votre boutique Letzshop",
"subtitle": "Vous vendez déjà sur Letzshop ? Entrez l'URL de votre boutique pour commencer.",
"placeholder": "Entrez votre URL Letzshop (ex: letzshop.lu/vendors/ma-boutique)",
"button": "Trouver ma boutique",
"claim_shop": "Réclamer cette boutique",
"already_claimed": "Déjà réclamée",
"no_account": "Vous n'avez pas de compte Letzshop ?",
"signup_letzshop": "Inscrivez-vous d'abord sur Letzshop",
"then_connect": ", puis revenez connecter votre boutique.",
"search_placeholder": "Entrez l'URL Letzshop ou le nom de la boutique...",
"search_button": "Rechercher",
"examples": "Exemples :",
"claim_button": "Réclamez cette boutique et démarrez l'essai gratuit",
"not_found": "Nous n'avons pas trouvé de boutique Letzshop avec cette URL. Vérifiez et réessayez.",
"or_signup": "Ou inscrivez-vous sans connexion Letzshop",
"need_help": "Besoin d'aide ?",
"no_account_yet": "Vous n'avez pas encore de compte Letzshop ? Pas de problème !",
"create_letzshop": "Créer un compte Letzshop",
"signup_without": "S'inscrire sans Letzshop",
"looking_up": "Recherche de votre boutique...",
"found": "Trouvé :",
"claimed_badge": "Déjà réclamée"
},
"signup": {
"step_plan": "Choisir le plan",
"step_shop": "Réclamer la boutique",
"step_account": "Compte",
"step_payment": "Paiement",
"choose_plan": "Choisissez votre plan",
"save_percent": "Économisez {percent}%",
"trial_info": "Nous collecterons vos informations de paiement, mais vous ne serez pas débité avant la fin de l'essai.",
"connect_shop": "Connectez votre boutique Letzshop",
"connect_optional": "Optionnel : Liez votre compte Letzshop pour synchroniser automatiquement les commandes.",
"connect_continue": "Connecter et continuer",
"skip_step": "Passer cette étape",
"create_account": "Créez votre compte",
"first_name": "Prénom",
"last_name": "Nom",
"company_name": "Nom de l'entreprise",
"email": "E-mail",
"password": "Mot de passe",
"password_hint": "Minimum 8 caractères",
"continue": "Continuer",
"continue_payment": "Continuer vers le paiement",
"back": "Retour",
"add_payment": "Ajouter un moyen de paiement",
"no_charge_note": "Vous ne serez pas débité avant la fin de votre essai de {trial_days} jours.",
"processing": "Traitement en cours...",
"start_trial": "Démarrer l'essai gratuit",
"creating_account": "Création de votre compte..."
},
"success": {
"title": "Bienvenue sur Wizamart !",
"subtitle": "Votre compte a été créé et votre essai gratuit de {trial_days} jours a commencé.",
"what_next": "Et maintenant ?",
"step_connect": "Connecter Letzshop :",
"step_connect_desc": "Ajoutez votre clé API pour commencer à synchroniser automatiquement les commandes.",
"step_invoicing": "Configurer la facturation :",
"step_invoicing_desc": "Configurez vos paramètres de facturation pour la conformité luxembourgeoise.",
"step_products": "Importer les produits :",
"step_products_desc": "Synchronisez votre catalogue de produits depuis Letzshop.",
"go_to_dashboard": "Aller au tableau de bord",
"login_dashboard": "Connexion au tableau de bord",
"need_help": "Besoin d'aide pour démarrer ?",
"contact_support": "Contactez notre équipe support"
},
"cta": {
"title": "Section Appel à l'action",
"main_title": "Titre",
"subtitle": "Sous-titre",
"buttons": "Boutons",
"add_button": "Ajouter un bouton"
"title": "Prêt à optimiser vos commandes ?",
"subtitle": "Rejoignez les vendeurs Letzshop qui font confiance à Wizamart pour leur gestion de commandes. Commencez votre essai gratuit de {trial_days} jours aujourd'hui.",
"button": "Essai gratuit"
},
"footer": {
"tagline": "OMS léger pour les vendeurs Letzshop. Gérez commandes, stocks et facturation.",
"quick_links": "Liens rapides",
"platform": "Plateforme",
"contact": "Contact",
"copyright": "© {year} Wizamart. Conçu pour le e-commerce luxembourgeois.",
"privacy": "Politique de confidentialité",
"terms": "Conditions d'utilisation",
"about": "À propos",
"faq": "FAQ",
"contact_us": "Nous contacter"
},
"modern": {
"badge_integration": "Intégration officielle",
"badge_connect": "Connexion en 2 minutes",
"hero_title_1": "Conçu pour le e-commerce luxembourgeois",
"hero_title_2": "Le back-office que Letzshop ne vous donne pas",
"hero_subtitle": "Synchronisez les commandes, gérez les stocks, générez des factures avec la TVA correcte et possédez vos données clients. Tout en un seul endroit.",
"cta_trial": "Essai gratuit de {trial_days} jours",
"cta_how": "Voir comment ça marche",
"hero_note": "Aucune carte de crédit requise. Configuration en 5 minutes. Annulez à tout moment.",
"pain_title": "Ça vous dit quelque chose ?",
"pain_subtitle": "Ce sont les frustrations quotidiennes des vendeurs Letzshop",
"pain_manual": "Saisie manuelle des commandes",
"pain_manual_desc": "Copier-coller les commandes de Letzshop vers des tableurs. Chaque. Jour.",
"pain_inventory": "Chaos des stocks",
"pain_inventory_desc": "Le stock dans Letzshop ne correspond pas à la réalité. Les surventes arrivent.",
"pain_vat": "Mauvaises factures TVA",
"pain_vat_desc": "Les clients UE ont besoin de la TVA correcte. Votre comptable se plaint.",
"pain_customers": "Clients perdus",
"pain_customers_desc": "Letzshop possède vos données clients. Vous ne pouvez pas les recibler ou fidéliser.",
"how_title": "Comment ça marche",
"how_subtitle": "Du chaos au contrôle en 4 étapes",
"how_step1": "Connecter Letzshop",
"how_step1_desc": "Entrez vos identifiants API Letzshop. Fait en 2 minutes, aucune compétence technique requise.",
"how_step2": "Les commandes arrivent",
"how_step2_desc": "Les commandes se synchronisent automatiquement. Confirmez et ajoutez le suivi directement depuis Wizamart.",
"how_step3": "Générer des factures",
"how_step3_desc": "Un clic pour créer des factures PDF conformes avec la TVA correcte pour tout pays UE.",
"how_step4": "Développez votre entreprise",
"how_step4_desc": "Exportez les clients pour le marketing. Suivez les stocks. Concentrez-vous sur la vente, pas les tableurs.",
"features_title": "Tout ce dont un vendeur Letzshop a besoin",
"features_subtitle": "Les outils opérationnels que Letzshop ne fournit pas",
"cta_final_title": "Prêt à prendre le contrôle de votre entreprise Letzshop ?",
"cta_final_subtitle": "Rejoignez les vendeurs luxembourgeois qui ont arrêté de lutter contre les tableurs et ont commencé à développer leur entreprise.",
"cta_final_note": "Aucune carte de crédit requise. Configuration en 5 minutes. Toutes les fonctionnalités Pro pendant l'essai."
}
},
"media": {
"title": "Bibliothèque de médias",
"upload": "Télécharger",
"upload_file": "Télécharger un fichier",
"delete": "Supprimer",
"empty": "Aucun fichier média",
"upload_first": "Téléchargez votre premier fichier"
},
"themes": {
"title": "Thèmes vendeurs",
"subtitle": "Gérez les personnalisations de thèmes des vendeurs"
},
"actions": {
"save": "Enregistrer",
"saving": "Enregistrement...",
"update": "Mettre à jour la page",
"create": "Créer la page",
"cancel": "Annuler",
"back_to_list": "Retour à la liste",
"preview": "Aperçu",
"revert_to_default": "Revenir à la valeur par défaut"
},
"messages": {
"created": "Page créée avec succès",
"updated": "Page mise à jour avec succès",
"deleted": "Page supprimée avec succès",
"reverted": "Retour à la page par défaut",
"error_loading": "Erreur lors du chargement de la page",
"error_saving": "Erreur lors de l'enregistrement de la page",
"confirm_delete": "Êtes-vous sûr de vouloir supprimer cette page ?"
},
"filters": {
"all_pages": "Toutes les pages",
"all_platforms": "Toutes les plateformes",
"search_placeholder": "Rechercher des pages..."
}
}