ENG-001.5J3 — Réconciliation Territory/SIRENE des informations municipales — Rapport d'implémentation
| Mission | ENG-001.5J3 — Migration de la réconciliation Territory/SIRENE des informations municipales |
| Rattaché à | ENG-001.5J — Migration des infos pratiques vers Municipal Management ; ENG-001.5J1 — Rapport d'implémentation ; ENG-001.5J2 — Rapport d'implémentation |
| Dépôt | dmv_api |
| Branche | feature/eng-001-5j3-municipal-infos-reconciliation |
| Statut | Implémenté localement — aucun commit applicatif |
1. Divergence initiale
MunicipalManagementWriterne portait encore aucune capacité publique de réconciliation descommune_infos.CommuneMairieDataRefreshServicecontenait encore :- le matching par
commune_id + section + label; - la décision création / mise à jour ;
- les valeurs par défaut
icon_color = blueetordre = 0; - le calcul de
infos_updated; - une méthode privée
upsertInfo()dédiée àcommune_infos.
- le matching par
- Le contrat public Municipal Management ne permettait pas encore à Territory de déléguer ce cas d’usage sans fuite SIRENE.
2. Arbitrage validé
- L’extension du contrat
MunicipalManagementWriterest validée avec :
public function reconcileInfos(
string $communeId,
MunicipalInfoReconciliationDTO $data,
): MunicipalInfoReconciliationResultDTO;
- Municipal Management devient l’unique owner métier de la réconciliation
commune_infos. - Territory reste limité à :
- la lecture de la source externe ;
- l’extraction des champs utiles ;
- la construction de DTO neutres ;
- l’appel du contrat ;
- la réinjection du résultat dans
MairieDataRefreshResult.
3. Signature finale du contrat
MunicipalManagementWriter::reconcileInfos(
string $communeId,
MunicipalInfoReconciliationDTO $data,
): MunicipalInfoReconciliationResultDTO
4. DTO créés
MunicipalInfoCandidateDTO
Champs exacts :
sectionlabelvaleur
MunicipalInfoReconciliationDTO
Contenu exact :
candidates: liste typée deMunicipalInfoCandidateDTO
MunicipalInfoReconciliationResultDTO
Contenu exact :
infosUpdated: liste de chaînes
Compatibilité exposée :
[
'infos_updated' => [...],
]
5. Sémantique exacte de infosUpdated
- la valeur est calculée dans Municipal Management ;
- chaque candidat traité ajoute sa
sectionà la liste si elle n’y est pas déjà ; - la liste est donc dédupliquée ;
- une section est considérée comme impactée dès lors qu’un candidat de cette section est présent dans le payload, même si la
valeurfinale est identique à l’état déjà stocké ; - ce comportement reproduit le flux historique observé dans Territory, qui ajoutait la section dès la présence du champ source, sans distinguer création, modification effective ou identité stricte de valeur.
Conséquence d’idempotence :
- deux appels successifs avec les mêmes candidats conservent le même état final ;
- ils retournent encore
['identite']si des candidatsidentitesont présents.
6. Logique retirée de Territory
CommuneMairieDataRefreshService ne contient plus :
- aucune écriture directe vers
commune_infos; - aucune méthode
upsertInfo(); - aucun matching par
commune_id + section + label; - aucune valeur par défaut métier de création ;
- aucun calcul local de
infos_updated.
Territory conserve uniquement :
- la construction de candidats neutres (
section,label,valeur) ; - l’appel à
MunicipalManagementWriter::reconcileInfos(); - la réinjection du résultat dans
MairieDataRefreshResult.
7. Logique ajoutée à Municipal Management
MunicipalManagementWriteService::reconcileInfos() porte désormais :
- la vérification d’existence de la commune ;
- la recherche de l’information existante par
commune_id + section + label; - la décision création / mise à jour ;
- la mise à jour limitée à
valeurpour les lignes existantes ; - la création avec valeurs historiques :
icon_color = blueordre = 0created_at = now()
- la déduplication de
infosUpdated.
8. Comportement historique préservé
- matching inchangé par
commune_id + section + label; - mise à jour inchangée limitée à
valeur; - création inchangée avec
icon_color = blueetordre = 0; - aucune suppression ;
- aucune désactivation ;
- aucune réactivation ;
- aucun autre champ modifié sur une ligne existante ;
- format de
MairieDataRefreshResultinchangé ; - routes inchangées ;
- aucun frontend modifié.
9. Idempotence
Preuve couverte par les tests :
- premier appel : création des trois infos historiques
identite; - second appel identique :
- aucun doublon ;
- même état final en base ;
- même liste
infos_updated = ['identite'].
10. Tests et garde-fous
Tests ajoutés ou adaptés :
- création des trois informations historiques avec défauts ;
- mise à jour d’une information existante en ne modifiant que
valeur; - matching exact et isolation entre communes ;
- idempotence sans doublon ;
- déduplication de
infos_updated; - compatibilité exacte avec
MairieDataRefreshResult; - délégation effective Territory → contrat public ;
- garde-fou sur l’absence d’écriture directe Territory →
commune_infos; - garde-fou sur l’absence de
upsertInfo()dans Territory ; - garde-fou sur l’unicité d’implémentation métier ;
- garde-fou sur la neutralité des DTO et l’absence de terme
Sirenedans les contrats/DTO Municipal Management ; - garde-fou sur l’absence de route modifiée.
11. Validations
Validations à exécuter pour clôture locale :
php -lsur les fichiers PHP touchés ;php artisan route:list;php artisan test;vendor/bin/pint --test;git diff --check;npm run buildcôté documentation ;git diff --checkcôté documentation.
12. Dettes restantes
- aucune dette supplémentaire introduite dans ce périmètre ;
- les lectures publiques Territory restent inchangées par décision de périmètre ;
- les autres sous-domaines municipaux ne sont pas touchés ;
- aucune évolution sur
commune_info_sectionsn’est nécessaire dans J3.