Architecture
Principes
- Monolithe modulaire Nuxt/Nitro : une base de code, front + API.
- Domaines isolés par module pour limiter le couplage.
- Contrats explicites entre modules via services et DTO.
- Capable d'évoluer vers une extraction en microservices si nécessaire.
Découpage des modules
Les modules métier se trouvent sous app/mypromo/server/modules/ :
| Module | Responsabilité |
|---|---|
auth | Comptes, sessions, rôles, KYB |
catalog | Magasins, espaces publicitaires, disponibilités |
campaigns | Paniers, campagnes, réservations |
billing | Ledger, facturation, rapprochement |
einvoicing | Transmission facture électronique, statuts provider, conformité |
notifications | E-mail transactionnel, in-app |
admin | Supervision, modération, paramètres |
kyb-core | Primitives KYB transverses (vérification SIREN/SIRET, cache Pappers) |
esign-core | Primitives signature électronique transverses (Yousign) |
shared | Primitives techniques transverses |
Couches internes d'un module
Chaque module est structuré en quatre couches :
domain— règles métier et invariantsapplication— use-cases et orchestrationinfrastructure— DB, API tierces, adaptateursapi— handlers HTTP (Nitro)
Chaque module expose une entrée publique app/mypromo/server/modules/<module>/index.ts.
Règle cross-module
Tout code extérieur à un module (handlers
app/mypromo/server/api/, pluginsapp/mypromo/server/plugins/, middleware) ne peut importer que depuisapp/mypromo/server/modules/<module>/index.ts. Il est interdit d'accéder directement aux couchesdomain,applicationouinfrastructured'un autre module.
Les primitives partagées utilisées par les plugins, middleware ou routes proviennent de app/mypromo/server/modules/shared/index.ts — jamais de sous-chemins internes.
Les notifications cross-module passent par app/mypromo/server/modules/notifications/index.ts ; les chemins internes email/* restent privés au module.
La règle est vérifiée en CI via app/mypromo/tests/unit/module-boundaries.spec.ts.
Contrats API standardisés
Toute route API retourne une enveloppe :
Succès :
{
"ok": true,
"data": { ... },
"meta": {
"requestId": "...",
"timestamp": "..."
}
}
Erreur :
{
"ok": false,
"error": {
"code": "...",
"message": "..."
},
"meta": {
"requestId": "...",
"timestamp": "..."
}
}
Les helpers d'enveloppe se trouvent dans app/mypromo/server/modules/shared/api. Les codes d'erreur stables sont définis par API_ERROR_CODES.
Tracing et logging
- Le middleware global
app/mypromo/server/middleware/request-id.tsinjecte l'en-têtex-request-idsur chaque requête. - Logs JSON structurés avec les champs
scope,level,message,requestId,timestamp. - Hook Nitro d'erreur centralisé pour les exceptions non capturées.
- Ne jamais logger de secrets (clés, mots de passe, tokens, credentials complets).
Arborescence de référence
app/mypromo/
server/
api/
config/
middleware/
modules/
auth/
catalog/
campaigns/
billing/
einvoicing/
notifications/
admin/
kyb-core/
esign-core/
shared/
plugins/
utils/
Règles d'évolution
- Un module ne lit pas directement les détails internes d'un autre module.
- Les utilitaires transverses restent agnostiques métier.
- Toute nouvelle feature doit expliciter son module propriétaire.