Skip to main content

Un code, quatre audiences

L’API est un unique code Fastify, déployé en containers indépendants, un par audience. L’audience est choisie au démarrage par APP_AUDIENCE. La table de routage est dans src/app/audiences.ts : préfixe, factory d’app, modules, et pour rs le flag realtime.
APP_AUDIENCE n’a aucune valeur par défaut. Absente ou inconnue, le process crashe au démarrage. C’est voulu : impossible de lancer la mauvaise audience par accident.
Pourquoi un seul code : une migration, une suite de tests, un pipeline. Les audiences ne diffèrent que par les routes montées — tout le partagé (DB, plugins, erreurs, pagination, i18n) n’existe qu’une fois.

Arborescence

Une nouvelle fonctionnalité vit dans audiences/<audience>/modules/<nom>/v1/ et s’enregistre comme plugin Fastify.

Base de données

Un seul Postgres, un seul schéma Prisma dans apps/api/database/ — workspace séparé pour que les migrations tournent sans démarrer le serveur.
Ne jamais éditer une migration déjà commitée. Voir Migrations pour la règle expand/contract, obligatoire.

Erreurs

Tout ce qui peut remonter à un client HTTP doit être un AppError (src/kit/errors/app-error.ts), jamais un Error brut : le handler Fastify global mappe AppError sur son statusCode / code, alors qu’un Error brut devient un 500 INTERNAL_SERVER_ERROR générique — le message réel est loggé mais perdu pour le client.

Santé

/health (liveness) et /health/ready (readiness). Le health gate des déploiements sonde /health/ready pour l’API et /health pour les fronts.

Tests

Les tests d’intégration utilisent inject() de Fastify contre une vraie base : le globalSetup dérive une base template migrée puis la clone une fois par worker. Les tests de routes s’appuient sur les fixtures rsFixture, boFixture, adFixture, prFixture.