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.
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 apparent | Pourquoi il ne justifie pas de base |
|---|---|
| Dédup des flux entrants | Traité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 sortants | Kafka 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. |
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 :
| Module | Propriétaire réel de l'état |
|---|---|
| portal-bff | Aucun état propre : agrégation d'écrans et orchestration. Sessions, profils et authentification appartiennent à Keycloak. |
| mobile-bff | Synchronisation hors-ligne par curseur : le delta se calcule à la demande depuis les services du domaine. Les jetons push appartiennent à svc-notifications. |
| asaci-edge | Le 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-edge | L'état des paiements — instructions, exécution, rapprochement — appartient à svc-payments ; la corrélation passe par un identifiant porté dans le message. |
| erp-edge | Kafka 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
| Configuration | Aucun bloc quarkus.datasource ni quarkus.liquibase dans application.yml, aucune variable DB_URL ni secret de base dans les values de déploiement. |
| Dépendances | Ni quarkus-jdbc-postgresql ni quarkus-liquibase dans le build.gradle.kts du module. |
| Déploiement | Aucune Database CR CloudNativePG. Le cluster sigfga-pg porte quinze bases, une par service métier — pas dix-neuf. |
| Bénéfice | Démarrage plus rapide (pas de migration au boot), aucune connexion JDBC inutile, aucun jeu de credentials à gérer, à faire tourner ni à sauvegarder. |
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 :
| Module | Condition de réouverture |
|---|---|
| asaci-edge | Si 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-edge | Une 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.