# Architecture — Modular Monolith DDD ## Principe fondamental Le **backend est la source de verite unique**. Il dicte : - Quels modules sont actifs (`config/modules.php`) - L'organisation de la sidebar (`config/sidebar.php`, decouplee des modules) Le frontend scanne `modules/*/` comme layers Nuxt et consomme l'API pour la navigation. Il ne decide rien. ## Endpoints API cles - `GET /api/version` (public) — version de l'app - `GET /api/modules` (public) — IDs des modules actifs - `GET /api/sidebar` (public) — sections filtrees par modules actifs + `disabledRoutes` (items dont le module owner est inactif) - `GET /api/me` (auth) — user courant ## Arborescence minimale (detail complet : @README.md) ``` src/ Shared/ # Noyau technique partage (Domain/, Application/Bus/, Infrastructure/ApiPlatform/) Module/ Core/ # Module obligatoire (auth, users) CoreModule.php # ID, LABEL, REQUIRED, permissions() Domain/ Application/ Infrastructure/ Commercial/ # Exemple d'autre module frontend/ app/ # Shell (layouts, middlewares) shared/ # Code inter-modules (composables, stores, utils) modules/ # Layers Nuxt auto-detectes core/ commercial/ ``` ## Declaration d'un module Chaque module expose un `*Module.php` avec : - `ID` (snake_case, ex: `commercial`, `gestion_rh`) - `LABEL` - `REQUIRED` (bool) - Methode statique `permissions()` retournant les RBAC du module ## Activer / desactiver un module Editer uniquement `config/modules.php` (commenter la ligne). Cascade automatique : 1. `/api/modules` ne retourne plus l'ID 2. `/api/sidebar` filtre les items `module: ''` et supprime les sections vides 3. Middleware front `modules.global.ts` redirige toute navigation vers une route desactivee 4. Le code reste dans le bundle (layer auto-detecte) → reactivation instantanee sans rebuild ## Reorganiser la sidebar Editer uniquement `config/sidebar.php`. Le code des modules n'est pas touche — seule la place des items change. Chaque item reference son module owner via la cle `module`. ## Communication inter-modules **Interdit** : import direct d'une classe d'un autre module. **Autorise** : - Via `Shared/Domain/Contract/` (interfaces : `UserResolverInterface`, `TenantAwareInterface`...) - Via domain events (`Shared/Domain/Event/DomainEventInterface`) ## Migrations - **Par defaut** : `src/Module//Infrastructure/Doctrine/Migrations/` (namespace modulaire) - **Exception** : les migrations d'initialisation critiques (setup user, RBAC, seed de base) vivent au namespace racine `DoctrineMigrations` dans `migrations/`. - Raison : avec plusieurs `migrations_paths`, Doctrine Migrations 3.x trie par FQCN alphabetique et non par version timestamp → ordre incorrect entre namespaces sur base vide. - A supprimer quand un `MigrationsComparator` custom ou un upgrade Doctrine resoudra le tri.