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,49 +1,64 @@
{
"title": "Produktkatalog",
"description": "Produktkatalogverwaltung für Händler",
"products": {
"title": "Produkte",
"subtitle": "Verwalten Sie Ihren Produktkatalog",
"create": "Produkt erstellen",
"edit": "Produkt bearbeiten",
"delete": "Produkt löschen",
"empty": "Keine Produkte gefunden",
"empty_search": "Keine Produkte entsprechen Ihrer Suche"
},
"product": {
"name": "Produktname",
"description": "Beschreibung",
"sku": "Artikelnummer",
"product": "Produkt",
"add_product": "Produkt hinzufügen",
"edit_product": "Produkt bearbeiten",
"delete_product": "Produkt löschen",
"product_name": "Produktname",
"product_code": "Produktcode",
"sku": "SKU",
"price": "Preis",
"stock": "Bestand",
"status": "Status",
"active": "Aktiv",
"inactive": "Inaktiv"
},
"media": {
"title": "Produktmedien",
"upload": "Bild hochladen",
"delete": "Bild löschen",
"primary": "Als Hauptbild festlegen",
"error": "Medien-Upload fehlgeschlagen"
},
"validation": {
"name_required": "Produktname ist erforderlich",
"price_required": "Preis ist erforderlich",
"invalid_sku": "Ungültiges Artikelnummernformat",
"duplicate_sku": "Artikelnummer existiert bereits"
"sale_price": "Verkaufspreis",
"cost": "Kosten",
"stock": "Lagerbestand",
"in_stock": "Auf Lager",
"out_of_stock": "Nicht auf Lager",
"low_stock": "Geringer Bestand",
"availability": "Verfügbarkeit",
"available": "Verfügbar",
"unavailable": "Nicht verfügbar",
"brand": "Marke",
"category": "Kategorie",
"categories": "Kategorien",
"image": "Bild",
"images": "Bilder",
"main_image": "Hauptbild",
"gallery": "Galerie",
"weight": "Gewicht",
"dimensions": "Abmessungen",
"color": "Farbe",
"size": "Größe",
"material": "Material",
"condition": "Zustand",
"new": "Neu",
"used": "Gebraucht",
"refurbished": "Generalüberholt",
"no_products": "Keine Produkte gefunden",
"search_products": "Produkte suchen...",
"filter_by_category": "Nach Kategorie filtern",
"filter_by_status": "Nach Status filtern",
"sort_by": "Sortieren nach",
"sort_newest": "Neueste",
"sort_oldest": "Älteste",
"sort_price_low": "Preis: Niedrig bis Hoch",
"sort_price_high": "Preis: Hoch bis Niedrig",
"sort_name_az": "Name: A-Z",
"sort_name_za": "Name: Z-A"
},
"messages": {
"created": "Produkt erfolgreich erstellt",
"updated": "Produkt erfolgreich aktualisiert",
"deleted": "Produkt erfolgreich gelöscht",
"not_found": "Produkt nicht gefunden",
"cannot_delete": "Produkt kann nicht gelöscht werden",
"error_loading": "Fehler beim Laden der Produkte"
},
"filters": {
"all_products": "Alle Produkte",
"active_only": "Nur aktive",
"search_placeholder": "Produkte suchen..."
"product_deleted_successfully": "Product deleted successfully",
"please_fill_in_all_required_fields": "Please fill in all required fields",
"product_updated_successfully": "Product updated successfully",
"failed_to_load_media_library": "Failed to load media library",
"no_vendor_associated_with_this_product": "No vendor associated with this product",
"please_select_an_image_file": "Please select an image file",
"image_must_be_less_than_10mb": "Image must be less than 10MB",
"image_uploaded_successfully": "Image uploaded successfully",
"product_removed_from_vendor_catalog": "Product removed from vendor catalog.",
"please_select_a_vendor": "Please select a vendor",
"please_enter_a_product_title_english": "Please enter a product title (English)",
"product_created_successfully": "Product created successfully",
"please_select_a_vendor_first": "Please select a vendor first"
}
}

View File

@@ -1,49 +1,64 @@
{
"title": "Catalogue produits",
"description": "Gestion du catalogue produits pour les vendeurs",
"products": {
"title": "Produits",
"subtitle": "Gérez votre catalogue de produits",
"create": "Créer un produit",
"edit": "Modifier le produit",
"delete": "Supprimer le produit",
"empty": "Aucun produit trouvé",
"empty_search": "Aucun produit ne correspond à votre recherche"
},
"product": {
"name": "Nom du produit",
"description": "Description",
"sku": "Référence",
"product": "Produit",
"add_product": "Ajouter un produit",
"edit_product": "Modifier le produit",
"delete_product": "Supprimer le produit",
"product_name": "Nom du produit",
"product_code": "Code produit",
"sku": "SKU",
"price": "Prix",
"sale_price": "Prix de vente",
"cost": "Coût",
"stock": "Stock",
"status": "Statut",
"active": "Actif",
"inactive": "Inactif"
},
"media": {
"title": "Médias du produit",
"upload": "Télécharger une image",
"delete": "Supprimer l'image",
"primary": "Définir comme image principale",
"error": "Échec du téléchargement"
},
"validation": {
"name_required": "Le nom du produit est requis",
"price_required": "Le prix est requis",
"invalid_sku": "Format de référence invalide",
"duplicate_sku": "La référence existe déjà"
"in_stock": "En stock",
"out_of_stock": "Rupture de stock",
"low_stock": "Stock faible",
"availability": "Disponibilité",
"available": "Disponible",
"unavailable": "Indisponible",
"brand": "Marque",
"category": "Catégorie",
"categories": "Catégories",
"image": "Image",
"images": "Images",
"main_image": "Image principale",
"gallery": "Galerie",
"weight": "Poids",
"dimensions": "Dimensions",
"color": "Couleur",
"size": "Taille",
"material": "Matériau",
"condition": "État",
"new": "Neuf",
"used": "Occasion",
"refurbished": "Reconditionné",
"no_products": "Aucun produit trouvé",
"search_products": "Rechercher des produits...",
"filter_by_category": "Filtrer par catégorie",
"filter_by_status": "Filtrer par statut",
"sort_by": "Trier par",
"sort_newest": "Plus récent",
"sort_oldest": "Plus ancien",
"sort_price_low": "Prix : croissant",
"sort_price_high": "Prix : décroissant",
"sort_name_az": "Nom : A-Z",
"sort_name_za": "Nom : Z-A"
},
"messages": {
"created": "Produit créé avec succès",
"updated": "Produit mis à jour avec succès",
"deleted": "Produit supprimé avec succès",
"not_found": "Produit non trouvé",
"cannot_delete": "Impossible de supprimer le produit",
"error_loading": "Erreur lors du chargement des produits"
},
"filters": {
"all_products": "Tous les produits",
"active_only": "Actifs uniquement",
"search_placeholder": "Rechercher des produits..."
"product_deleted_successfully": "Product deleted successfully",
"please_fill_in_all_required_fields": "Please fill in all required fields",
"product_updated_successfully": "Product updated successfully",
"failed_to_load_media_library": "Failed to load media library",
"no_vendor_associated_with_this_product": "No vendor associated with this product",
"please_select_an_image_file": "Please select an image file",
"image_must_be_less_than_10mb": "Image must be less than 10MB",
"image_uploaded_successfully": "Image uploaded successfully",
"product_removed_from_vendor_catalog": "Product removed from vendor catalog.",
"please_select_a_vendor": "Please select a vendor",
"please_enter_a_product_title_english": "Please enter a product title (English)",
"product_created_successfully": "Product created successfully",
"please_select_a_vendor_first": "Please select a vendor first"
}
}

View File

@@ -1,49 +1,64 @@
{
"title": "Produktkatalog",
"description": "Produktkatalogverwaltung fir Händler",
"products": {
"title": "Produkter",
"subtitle": "Verwalte Äre Produktkatalog",
"create": "Produkt erstellen",
"edit": "Produkt beaarbechten",
"delete": "Produkt läschen",
"empty": "Keng Produkter fonnt",
"empty_search": "Keng Produkter entspriechen Ärer Sich"
},
"product": {
"name": "Produktnumm",
"description": "Beschreiwung",
"sku": "Artikelnummer",
"product": "Produkt",
"add_product": "Produkt derbäisetzen",
"edit_product": "Produkt änneren",
"delete_product": "Produkt läschen",
"product_name": "Produktnumm",
"product_code": "Produktcode",
"sku": "SKU",
"price": "Präis",
"stock": "Bestand",
"status": "Status",
"active": "Aktiv",
"inactive": "Inaktiv"
},
"media": {
"title": "Produktmedien",
"upload": "Bild eroplueden",
"delete": "Bild läschen",
"primary": "Als Haaptbild setzen",
"error": "Medien-Upload feelgeschloen"
},
"validation": {
"name_required": "Produktnumm ass erfuerderlech",
"price_required": "Präis ass erfuerderlech",
"invalid_sku": "Ongëlteg Artikelnummerformat",
"duplicate_sku": "Artikelnummer existéiert schonn"
"sale_price": "Verkafspräis",
"cost": "Käschten",
"stock": "Lager",
"in_stock": "Op Lager",
"out_of_stock": "Net op Lager",
"low_stock": "Niddregen Stock",
"availability": "Disponibilitéit",
"available": "Disponibel",
"unavailable": "Net disponibel",
"brand": "Mark",
"category": "Kategorie",
"categories": "Kategorien",
"image": "Bild",
"images": "Biller",
"main_image": "Haaptbild",
"gallery": "Galerie",
"weight": "Gewiicht",
"dimensions": "Dimensiounen",
"color": "Faarf",
"size": "Gréisst",
"material": "Material",
"condition": "Zoustand",
"new": "Nei",
"used": "Gebraucht",
"refurbished": "Iwwerholl",
"no_products": "Keng Produkter fonnt",
"search_products": "Produkter sichen...",
"filter_by_category": "No Kategorie filteren",
"filter_by_status": "No Status filteren",
"sort_by": "Sortéieren no",
"sort_newest": "Neisten",
"sort_oldest": "Eelsten",
"sort_price_low": "Präis: Niddreg op Héich",
"sort_price_high": "Präis: Héich op Niddreg",
"sort_name_az": "Numm: A-Z",
"sort_name_za": "Numm: Z-A"
},
"messages": {
"created": "Produkt erfollegräich erstallt",
"updated": "Produkt erfollegräich aktualiséiert",
"deleted": "Produkt erfollegräich geläscht",
"not_found": "Produkt net fonnt",
"cannot_delete": "Produkt kann net geläscht ginn",
"error_loading": "Feeler beim Lueden vun de Produkter"
},
"filters": {
"all_products": "All Produkter",
"active_only": "Nëmmen aktiv",
"search_placeholder": "Produkter sichen..."
"product_deleted_successfully": "Product deleted successfully",
"please_fill_in_all_required_fields": "Please fill in all required fields",
"product_updated_successfully": "Product updated successfully",
"failed_to_load_media_library": "Failed to load media library",
"no_vendor_associated_with_this_product": "No vendor associated with this product",
"please_select_an_image_file": "Please select an image file",
"image_must_be_less_than_10mb": "Image must be less than 10MB",
"image_uploaded_successfully": "Image uploaded successfully",
"product_removed_from_vendor_catalog": "Product removed from vendor catalog.",
"please_select_a_vendor": "Please select a vendor",
"please_enter_a_product_title_english": "Please enter a product title (English)",
"product_created_successfully": "Product created successfully",
"please_select_a_vendor_first": "Please select a vendor first"
}
}