Données & reprise · Edges et BFF

Edges et BFF — sans base de données

Cinq modules sur vingt ne portent aucune donnée : les deux BFF et les trois edges. Ils ne déclarent ni base, ni datasource, ni migration Liquibase. Cette page explique pourquoi, où vit l'état à la place, et à quelles conditions cette règle pourrait un jour être rouverte.

5modules sans état
15bases, une par service métier
0base pour les edges et BFF

1. Le principe : pas d'état, pas de base

Un BFF agrège et oriente : il compose des écrans à partir de plusieurs services, sans rien détenir en propre. Un edge (couche anti-corruption) traduit un format externe en modèle interne et inversement. Ni l'un ni l'autre n'est propriétaire d'une donnée métier — et un module qui n'est propriétaire d'aucune donnée n'a pas de base.

Les deux besoins qui pourraient sembler justifier une base sont déjà couverts ailleurs dans l'architecture :

Besoin apparentPourquoi il ne justifie pas de base
Dédup des flux entrantsTraitée en aval : les consommateurs sont idempotents (processed_events, déduplication par identifiant d'événement). L'edge n'a pas à la porter.
Fiabilité des envois sortantsKafka est déjà la file durable : l'edge consomme, appelle l'API externe, et en cas d'échec l'offset n'est pas commité (retry) ou le message part en DLQ. Une table de rejeu locale ferait doublon avec le broker.
Le raisonnement décisif porte sur l'outbox. Le patron outbox existe pour rendre atomique « changement d'état local + publication d'événement » : on écrit l'événement dans la même transaction que la donnée, et un relais publie ensuite. Sans état local, il n'y a rien à rendre atomique — la publication directe, combinée à l'at-least-once de Kafka et à des consommateurs idempotents, suffit et se raisonne plus simplement. C'est pourquoi ces cinq modules publient directement et ne déclarent pas d'outbox_events.

2. Où vit l'état, à la place

La question utile n'est pas « ce module a-t-il une base ? » mais « qui est propriétaire de cet état ? ». Pour chacun des cinq, la réponse est ailleurs :

ModulePropriétaire réel de l'état
portal-bffAucun état propre : agrégation d'écrans et orchestration. Sessions, profils et authentification appartiennent à Keycloak.
mobile-bffSynchronisation hors-ligne par curseur : le delta se calcule à la demande depuis les services du domaine. Les jetons push appartiennent à svc-notifications.
asaci-edgeLe fichier reçu va dans MinIO, l'événement dans Kafka ; la validation et la mise en quarantaine appartiennent au service métier destinataire. Le « mapping de format » est de la configuration, pas des données.
psp-edgeL'état des paiements — instructions, exécution, rapprochement — appartient à svc-payments ; la corrélation passe par un identifiant porté dans le message.
erp-edgeKafka sert de file durable pour les écritures vers Odoo ; le « mapping des tiers » relève du référentiel.

3. Ce que cela implique concrètement

ConfigurationAucun bloc quarkus.datasource ni quarkus.liquibase dans application.yml, aucune variable DB_URL ni secret de base dans les values de déploiement.
DépendancesNi quarkus-jdbc-postgresql ni quarkus-liquibase dans le build.gradle.kts du module.
DéploiementAucune Database CR CloudNativePG. Le cluster sigfga-pg porte quinze bases, une par service métier — pas dix-neuf.
BénéficeDémarrage plus rapide (pas de migration au boot), aucune connexion JDBC inutile, aucun jeu de credentials à gérer, à faire tourner ni à sauvegarder.
Un point de contrôle simple. Si un de ces cinq modules se met à déclarer un datasource, c'est le signe qu'un état métier est en train d'y migrer par accident. La question à poser alors n'est pas « quelle base lui donner » mais « à quel service appartient cette donnée ».

4. Le préalable côté notifications

La règle « mobile-bff sans base » repose sur une condition : les jetons push des appareils doivent être détenus par un service. L'architecture les place dans svc-notifications, mais la table device_push_tokens reste à créer. Tant qu'elle n'existe pas, le seul état que le BFF mobile pourrait légitimement vouloir persister n'a pas de propriétaire désigné.

5. Les deux cas qui pourraient rouvrir la règle

Elle n'est pas un dogme. Deux situations justifieraient une base pour un edge — aucune n'est constituée aujourd'hui :

ModuleCondition de réouverture
asaci-edgeSi le format réel de l'ASACI — encore inconnu — impose une véritable machine à états côté connecteur (quarantaine d'un fichier mal formé, cycle d'accusés de réception), et que MinIO plus Kafka ne suffisent plus à la porter.
psp-edgeUne table d'idempotence stricte des instructions de paiement, pour garantir qu'un rejeu Kafka ne déclenche jamais un second virement. Elle serait purement technique — aucune donnée métier, jamais cible de reprise.

Dans les deux cas, la base serait introduite pour ce module seul et délibérément, avec la justification écrite ici. C'est la différence entre une décision d'architecture et une configuration par défaut.