Architecture

Monolithe modulaire Nuxt/Nitro — principes, découpage des modules, couches internes, contrats API, règle cross-module.

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/ :

ModuleResponsabilité
authComptes, sessions, rôles, KYB
catalogMagasins, espaces publicitaires, disponibilités
campaignsPaniers, campagnes, réservations
billingLedger, facturation, rapprochement
einvoicingTransmission facture électronique, statuts provider, conformité
notificationsE-mail transactionnel, in-app
adminSupervision, modération, paramètres
kyb-corePrimitives KYB transverses (vérification SIREN/SIRET, cache Pappers)
esign-corePrimitives signature électronique transverses (Yousign)
sharedPrimitives techniques transverses

Couches internes d'un module

Chaque module est structuré en quatre couches :

  • domain — règles métier et invariants
  • application — use-cases et orchestration
  • infrastructure — DB, API tierces, adaptateurs
  • api — 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/, plugins app/mypromo/server/plugins/, middleware) ne peut importer que depuis app/mypromo/server/modules/<module>/index.ts. Il est interdit d'accéder directement aux couches domain, application ou infrastructure d'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.ts injecte l'en-tête x-request-id sur 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.