Aller au contenu principal

Plan d'amélioration Backend (structure, modularité, performance)

Objectif : consolider la structure NestJS après la segmentation (API vs Worker), réduire les risques de cycles DI, accélérer le boot, et rendre l’architecture plus maintenable.

Ce plan est technique (backend). Pour les priorités produit, voir docs/PRIORITES.md.

Principes

  1. Deux runtimes, deux modules

    • API runtime : HTTP + controllers + schedulers “API-only”.
    • Worker runtime : BullMQ processors (pas de HTTP).
  2. Tokens DI = impl “leaf”

    • Un token *_TOKEN ne doit jamais pointer vers une façade qui dépend d’un service injectant ce token.
    • Utiliser un adapter lookup si besoin (ex: QuotesInvoicesLookupService).
  3. Runtime modules pour les dépendances optionnelles

    • QueueRuntimeModule, EventEmitterRuntimeModule, (à terme ScheduleRuntimeModule).
  4. Boot tests

    • Chaque runtime doit avoir un smoke test (API boot / Worker boot) pour attraper les cycles DI dès le CI.

Checklist d’implémentation (PRs)

Voir docs/BACKEND_STRUCTURE_IMPLEMENTATION_CHECKLIST.md.

Phase 0 — Quick wins (1–2 jours)

0.1 Stabiliser WorkerModule minimal

  • But : le worker charge uniquement ce qui est requis par les processors.
  • Actions
    • Auditer les imports “accidentels” tirés par les *ProcessorModule (ex: un module qui ramène toute une feature).
    • Garder EventEmitterRuntimeModule.register() dans WorkerModule (fournit EventEmitter2 même quand désactivé).
  • Critère de succès
    • RUN_MODE=worker boot sans erreur, et ne charge pas Search/Agent.

0.2 Nettoyer la config runtime (dev/prod)

  • But : rendre le comportement “API enqueues / Worker processes” explicite.
  • Actions
    • Documenter les env vars runtime (RUN_MODE, QUEUE_*, SCHEDULE_ENABLED, EVENT_EMITTER_ENABLED) dans docs/BACKEND.md et docs/QUEUE_SYSTEM.md (fait).
    • Ajouter les clés manquantes dans .env.example (placeholders uniquement).
  • Critère de succès
    • Stack dev + prod fonctionnent avec 2 services (api, worker).

Phase 1 — Refacto structure (3–5 jours)

1.1 Extraire ApiModule (root thin)

  • But : AppModule devient un “wrapper” minimal, lisible, stable.
  • Actions
    • Créer ApiModule (controllers + modules métier HTTP).
    • AppModule importe ApiModule et les modules runtime (event-emitter, schedule) au bon endroit.
  • Critère de succès
    • AppModule contient uniquement du wiring, pas de logique de segmentation.

1.2 Séparer Queue “client” vs “worker”

  • But : empêcher l’API de charger les processors, et clarifier l’usage.
  • Actions
    • QueueClientModule : queues + QueueService (enqueue/status) sans processors.
    • QueueWorkerModule : QueueClientModule + *ProcessorModule.
    • API importe QueueClientModule, worker importe QueueWorkerModule.
  • Critère de succès
    • QUEUE_WORKERS_ENABLED=false sur l’API => aucun processor instancié.

Phase 2 — Durcissement anti-cycles + conventions (3–7 jours)

2.1 Standardiser “core module + adapter + token”

  • But : prévenir les cycles DI à l’échelle du projet.
  • Actions
    • Pattern documenté + checklist PR : “token bound to leaf/adapter”.
    • Appliquer progressivement aux modules à haut risque (emails, search, agent, calendar, quotes/invoices).
  • Critère de succès
    • Plus de “hang” sur NestFactory.create() suite à une refacto de modules.

2.2 Runtime modules uniformes

  • But : éviter les if (process.env...) dispersés.
  • Actions
    • Ajouter ScheduleRuntimeModule (similaire à EventEmitterRuntimeModule).
    • Définir la règle : forRoot() appelé une seule fois (dans le runtime module).
  • Critère de succès
    • Aucune feature module n’appelle ScheduleModule.forRoot().

Phase 3 — Tests & observabilité boot (2–4 jours)

3.1 Smoke tests “boot”

  • But : détecter immédiatement cycles DI / providers bloquants.
  • Actions
    • Test API boot : créer app (sans listen) ou createTestingModule(AppModule) et init.
    • Test Worker boot : createApplicationContext(WorkerModule) et close().
  • Critère de succès
    • CI échoue si un cycle DI est introduit.

3.2 Mesure de boot

  • But : suivre les gains.
  • Actions
    • Logger un timestamp “created” (déjà partiellement fait), + mesure par runtime.
    • Optionnel: exposer un endpoint healthz API + log worker “ready”.
  • Critère de succès
    • Boot API/worker mesurés et comparables entre versions.

Nettoyage documentation (source de vérité)

  • Règle
    • docs/PRIORITES.md = source de vérité “quoi faire”.
    • Ce document = “comment refactor” (plan technique).