Schémas de données — contenu minimal par service
Ce que chaque base doit contenir a minima pour que son service tienne ses agrégats et que la reprise ait une cible. Établi en croisant trois sources — la modélisation (schémas SVG des fiches de service), le code réel (changelogs Liquibase), l'infrastructure déployée (Database CR CloudNativePG en staging) — et intégrant le retour du chantier migration du 21/07/2026.
1. Où vit un schéma, et qui le crée
| Cible (staging, prod) | Une base PostgreSQL par service dans un cluster CNPG unique sigfga-pg : 19 Database CR déclarées en GitOps (gitops/envs/staging/databases.yaml), owner: sigfga, sync-wave 1. Le service se connecte à sa base : jdbc:…/claims, …/contributions. |
| Dev local | Une seule base sigfga avec un schéma par service (currentSchema=claims, …=medical_care) — commodité du docker-compose, pas la maille cible. Ne pas conclure d'un « un schéma par service » vu en local. |
| Création des tables | Liquibase, exclusivement (ADR-0002) : changesets en SQL formaté, changelog maître = pur index d'includes, jamais de changeset dedans. Aucun DDL cible écrit à la main par le chantier de reprise. |
| Interdits structurels | Aucune FK entre bases de services (rupture d'isolation des bounded contexts). Aucune vue ni foreign data wrapper inter-services. Les liens passent par événements Kafka ou appels REST. |
| Référence externe | Un identifiant d'un autre service se porte en colonne nue (claim_id uuid, insurer_id uuid) — sans contrainte, avec index. Sa cohérence est garantie par le flux d'événements, pas par la base. |
| Montants | XOF entiers (bigint) ou numeric — jamais float (défaut structurel de LOGPROD à corriger à la reprise). |
2. Socle technique obligatoire — présent dans tout schéma
Résumé ci-dessous ; formes SQL de référence, justification de chaque table et arbitrages ouverts sur la page du socle technique.
Ces tables ne sont pas du domaine : elles sont la condition pour qu'un service publie, consomme et rejoue sans doublon. La forme de référence est celle du code : outbox_events est déjà créée dans les bases de service.
| Table | Rôle | Obligatoire pour | État |
|---|---|---|---|
| outbox_events | Publication transactionnelle des événements (écrits dans la même transaction que l'agrégat, relayés ensuite vers Kafka). Colonnes de référence : id bigserial, event_id varchar(40) unique, event_type, subject, payload, occurred_at, published, published_at + index (published, id). | Tout service qui détient un état et publie (14 des 15) | EN CODE 14 services |
| processed_events | Idempotence de consommation : event_id PK + processed_at. Un événement rejoué par Kafka ne produit pas d'effet en double. | Tout service qui consomme | 1 service (svc-medical-care) |
| idempotency_keys | Idempotence des commandes REST : key PK, fingerprint, référence produite, created_at. Un POST rejoué renvoie la même ressource au lieu d'en créer une seconde. | Tout service à API de commande | 1 service (svc-claims) |
| known_<entité> | Projections locales alimentées par événements (copie en lecture seule d'une donnée d'un autre service, pour éviter un appel synchrone). Nommage explicite known_* : la table dit qu'elle n'est pas maître. Exemple en code : known_claims dans svc-medical-care. | Selon dépendances | 1 service |
| databasechangelog databasechangeloglock | Créées par Liquibase. Le pipeline de reprise lit databasechangelog pour vérifier la version de schéma attendue avant tout chargement, et s'arrête proprement en cas d'écart. | Toutes les bases | AUTOMATIQUE |
- inbox_events (dans 12 schémas modélisés : id, event_type, aggregate_id, payload, processed, processed_at) vs processed_events (en code : event_id, processed_at). Ce ne sont pas deux noms du même objet : le premier stocke la charge utile reçue, le second ne mémorise que l'identifiant traité. Recommandation : garder processed_events (dédup pure, volume constant) et ne matérialiser une vraie table d'entrée que là où un rejeu local du payload est requis.
- outbox_events modélisé avec aggregate_id / created_at vs code avec subject / occurred_at / event_id unique. Le code fait foi : c'est la forme réellement créée par Liquibase. Les SVG des fiches sont à réaligner.
- audit_logs apparaît dans 12 schémas et un service svc-audit-trail centralise la piste d'audit. Doublon à trancher : soit ces tables locales sont une trace technique assumée (et le disent), soit elles disparaissent au profit du journal central. Elles ne peuvent pas être toutes deux « la » piste d'audit exigée par les CDC.
3. Récapitulatif des 20 modules
« Tables métier » = noyau minimal hors socle technique. « Base » = base dédiée déclarée en GitOps. « Créé » = tables métier réellement présentes dans les changelogs Liquibase.
| Service | Base | Tables métier min. | Modélisé | Créé (code) | Reprise (statut révisé) |
|---|---|---|---|---|---|
| svc-reference-data | ✅ | 10 | À FAIRE | — | À CHARGER |
| svc-claims | ✅ | 6 | ✅ | PARTIEL | À CHARGER |
| svc-medical-care | ✅ | 10 | ✅ | PROJECTION | À CHARGER |
| svc-medical-billing | ✅ | 6 | ✅ | — | À CHARGER |
| svc-compensation | ✅ | 7 | ✅ | — | FINANCIER + INSTRUCTION |
| svc-compensation-engine | ✅ | 7 | À FAIRE | — | PARAMÉTRAGE |
| svc-contributions | ✅ | 12 | INCOMPLET | — | À CHARGER |
| svc-field-inspections | ✅ | 5 | ✅ | — | À CHARGER |
| svc-statistics | ✅ | 4 | ✅ | — | RECALCULÉ |
| svc-debt-recovery | ✅ | 6 | ✅ | — | SANS SOURCE |
| svc-payments | ✅ | 4 | ✅ | — | À TRANCHER |
| svc-documents | ✅ | 4 | ✅ | — | À CHARGER |
| svc-notifications | ✅ | 4 | ✅ | — | VIDE |
| svc-signatures | ✅ | 3 | À FAIRE | — | VIDE |
| svc-audit-trail | ✅ | 2 | ✅ | — | VIDE |
| asaci-edge | — | 0 | — | — | SANS BASE |
| psp-edge | — | 0 | — | — | SANS BASE |
| erp-edge | — | 0 | — | — | SANS BASE |
| mobile-bff | — | 0 | — | — | SANS BASE |
| portal-bff | — | 0 | — | — | SANS BASE |
4. Contenu minimal, schéma par schéma
Le détail de chaque base — MCD minimal, liste des tables du noyau et des compléments, sources legacy et transformations, points de vigilance — fait l'objet d'une sous-page par schéma. Elles sont générées depuis une spécification unique, de sorte que le diagramme et le tableau de tables ne peuvent pas diverger.
5. Base pivot de migration
La base sigfga_migration — staging brut, correspondance d'identifiants, rejets, réconciliation, inventaire GED — est séparée des bases de service et n'est jamais lue au runtime. Son contenu minimal et son MCD sont détaillés sur sa page dédiée.
6. Retour du chantier migration — intégration point par point
Retour du 21/07/2026 sur le tableau « reprise par service » : 8 lignes validées, 5 clarifications demandées, 1 statut contesté, 1 réserve transverse. Traitement de chacun.
| Point | Demande | Traitement |
|---|---|---|
| svc-field-inspections | Statut trop prudent — controle = 35 153 lignes documentées. Demande « À CHARGER ». | ACCEPTÉ Statut passé à À CHARGER ici et dans la page Reprise. Reformulé : ce qui reste au profiling est la qualité du rapprochement contrôle ↔ production, pas l'existence. Le service passe dans le chemin nominal du fan-out. |
| svc-contributions | Préciser le rôle des bordereaux Excel — risque de double comptage de l'assiette. | ACTÉ Rôle limitatif écrit noir sur blanc (§4) : attestation seule est chargée ; les Excel = justificatifs MinIO + référentiel compagnies + jeux de parité + rattrapage des seuls bordereaux jamais importés. Et conséquence non demandée mais nécessaire : les trois tables qui accueillent cette matière (statement_lines, statement_imports, statement_rejects) n'existaient pas dans le schéma modélisé — la source de vérité de l'assiette n'avait pas de cible. |
| svc-compensation | Sortir du binaire : les 61 dossiers et leurs montants sont en base ; c'est l'instruction qui manque. | ACCEPTÉ Statut scindé : volet financier À CHARGER (compensation_claims, damage_assessments), volet instruction selon décision n°2 (reprise GED seule vs ressaisie ciblée). |
| svc-medical-care svc-medical-billing | « À CHARGER » fondé, mais préciser les sous-périmètres non confirmés. | ACCEPTÉ Statut maintenu ; les sous-périmètres sont marqués table par table : prescriptions et feuilles de suivi (suivi : 2 lignes), détail de facturation (acte_frais : 5, acte_fournisseur : 2). |
| svc-documents | Acter la décision GED : « fichiers vers MinIO » vs page « Architecture technique » qui affiche encore SharePoint O365. | TRAITÉ Coexistence explicitée sur la page Architecture technique : MinIO = GED applicative (pièces de dossiers, ADR-0008), SharePoint O365 = bureautique/collaboratif cité par le CDC ERP. Deux briques, deux usages — la reprise ne vise que MinIO. |
| Réserve transverse | La colonne « Schéma runtime » est une intention, pas un état constaté. Le pipeline vérifie la version de schéma (ADR-0002) avant chargement. | LEVÉE Cette page distingue modélisé / provisionné / créé en code pour chaque module (§3) et matérialise le contrôle de version dans run_registry (§5). Constat : l'intention et l'état réel ne coïncident pas encore partout — les écarts subsistants sont listés en §7. |
7. Écarts et arbitrages ouverts
Classés par gravité. Les cinq premiers touchent la justesse des données ; les suivants la cohérence de la documentation.
| # | Écart | Conséquence si non traité | Décision attendue |
|---|---|---|---|
| a | Lignes d'attestation sans cible — statement_lines, statement_imports, statement_rejects absentes de svc-contributions | La source de vérité de l'assiette des 2 % (0,8–3 M lignes) n'a nulle part où atterrir. Le montant dû n'est ni recalculable ni auditable ligne à ligne. Bloquant pour le fan-out contributions. | Compléter le schéma avant le premier chargement. Valider la clé fonctionnelle de dédoublonnage. |
| b | Double comptage depense (1 087 lignes) — medical-billing ou payments ? | Le décaissé est compté deux fois, ou pas du tout. | Trancher au profiling : dette vs décaissement. |
| c | Deux tables de paiement — compensation.compensation_payments et payments.payment_orders | Deux vérités sur l'argent versé à une victime. | Retirer compensation_payments → projection ou identifiant nu. |
| d | Victime et dossier dupliqués — victims et claim_files maîtres dans svc-medical-care | Deux sources de vérité, et deux cibles de reprise pour les 293 victimes. | Appliquer le patron known_* déjà présent en code. |
| e | Frontière attestation ↔ RC Auto — statement_lines vs rc_auto_records | La même attestation chargée dans deux services. | Écrire la règle de partage (assiette vs flux statistique). |
| f | Un schéma modélisé pour un module sans état — portal-bff | Le schéma décrit user_profiles, user_sessions (avec refresh_token), notification_preferences… Or l'identité et les sessions appartiennent à Keycloak, et les préférences de notification à svc-notifications. Stocker un jeton de rafraîchissement dans un BFF est de surcroît un risque inutile. | Retirer ce schéma. Voir Edges et BFF. |
| g | Deux bases de paramétrage vides de source — SMIG, échelle du décret 2009-107, cas DJGS | svc-compensation-engine ne peut pas calculer, et son jeu de rejeu n'existe pas. | Obtenir les trois éléments du client (déjà en question consolidée). |
| h | audit_logs local × 12 + svc-audit-trail | Deux « pistes d'audit », aucune ne fait autorité pour les CDC. | Trancher : trace technique locale assumée, ou journal central seul. |
| i | inbox_events vs processed_events et forme de outbox_events | Les SVG des fiches décrivent un socle que le code ne construit pas. | Réaligner les SVG sur le code (le code fait foi). |
| j | Jetons push sans table — la décision les place dans svc-notifications, aucune table ne les porte | Le mobile ne peut pas être notifié, ou mobile-bff recrée une base pour ça. | Ajouter device_push_tokens. |
| k | Trois schémas non modélisés — svc-reference-data, svc-compensation-engine, svc-signatures | Dont svc-reference-data, qui est la première tranche de livraison et le pivot de tous les recodages de la reprise. | Modéliser en priorité reference-data (§4 en donne le contenu minimal). |
8. Ce qui reste à produire
- Les 3 schémas manquants (reference-data, compensation-engine, signatures) au même niveau de détail que les 13 existants — le contenu minimal ci-dessus en est la base.
- Les 3 tables manquantes de svc-contributions, avec stratégie de partitionnement et clé de dédoublonnage — préalable au chargement de LOGPROD.
- Le réalignement des 13 SVG sur le socle technique du code, et le retrait des tables hors périmètre (§7.c, §7.d, §7.f).
- Le DDL de la base pivot — livrable du chantier migration, pas de la modélisation, mais sa liste de tables est arrêtée (§5).
- Les décisions ouvertes : historique & rejeu d'événements, décision n°2 (instruction), frontière ERP/Odoo, sort du realm usagers Keycloak.