Aller au contenu principal

ENG-001.5I — Migration des Élus municipaux vers Municipal Management — Rapport d'implémentation

MissionENG-001.5I — Migration des Élus vers Municipal Management
Rattaché àENG-001.5 — Extraction de Municipal Management ; Recalibrage de roadmap ; ENG-001.5H ; ADR-014
Dépôtdmv_api
Branchefeature/eng-001-5i-municipal-elus
StatutImplémenté

1. Arbitrage appliqué

  • Le contrat public MunicipalManagementWriter est étendu avec reconcileElus(string $communeId, MunicipalElusReconciliationDTO $data): MunicipalElusReconciliationResultDTO.
  • Le contrat et les DTO restent purement métier : aucune dépendance à SIRENE, Territory, Eloquent, HTTP ou payload externe brut.
  • Territory conserve uniquement la lecture SIRENE, la normalisation, la construction du DTO métier, l’appel au contrat et l’exploitation des compteurs.
  • Municipal Management devient l’unique propriétaire du matching, de la création, de la mise à jour, de la réactivation, de la désactivation et des compteurs métiers.

2. Contrat final

Lecture

MunicipalManagementReader::getElus(string $communeId): Collection

Écriture

MunicipalManagementWriter::createElu(string $communeId, array $data): MunicipalEluDTO
MunicipalManagementWriter::updateElu(string $communeId, string $eluId, array $data): MunicipalEluDTO
MunicipalManagementWriter::deleteElu(string $communeId, string $eluId): void
MunicipalManagementWriter::reconcileElus(
string $communeId,
MunicipalElusReconciliationDTO $data,
): MunicipalElusReconciliationResultDTO

DTOs ajoutés

  • MunicipalEluCandidateDTO : nom, role, isMayor
  • MunicipalElusReconciliationDTO : list<MunicipalEluCandidateDTO> $candidates
  • MunicipalElusReconciliationResultDTO : added, updated, disabled

3. Logique déplacée

  • MunicipalManagementReadService::getElus() lit désormais commune_elus et mappe vers MunicipalEluDTO.
  • MunicipalManagementWriteService::createElu()/updateElu()/deleteElu() implémentent désormais réellement les écritures élus.
  • MunicipalManagementWriteService::reconcileElus() porte désormais l’algorithme historique de matching par nom normalisé.
  • MairieCommuneController délègue désormais lecture et CRUD élus à MunicipalManagementReader / MunicipalManagementWriter.
  • AdminCommuneInfoController délègue désormais fullCommune() et le CRUD élus à Municipal Management.
  • CommuneMairieDataRefreshService ne conserve plus que la transformation du payload externe en DTO métier, puis l’appel à reconcileElus().

4. Comportement conservé

  • Routes Mairie inchangées.
  • Routes Admin inchangées.
  • URL, payloads, validations et codes HTTP inchangés.
  • Ordre des élus conservé.
  • Sémantique disabled_at conservée.
  • Aucun frontend modifié.

5. Idempotence

  • Deux appels successifs à reconcileElus() avec la même liste ne créent aucun doublon.
  • Le second appel ne produit aucune mise à jour inutile.
  • L’état final reste stable.
  • Les compteurs retournent added=0, updated=0, disabled=0 au second passage.

6. Unicité d’implémentation

  • Il ne reste plus d’accès direct à commune_elus dans MairieCommuneController, AdminCommuneInfoController et CommuneMairieDataRefreshService.
  • MairieReadService et MairieWriteService ne portent plus de logique métier élus propre ; ils délèguent au contrat Municipal Management.
  • L’unique implémentation métier élus est désormais MunicipalManagementReadService / MunicipalManagementWriteService.

7. Tests ajoutés

  • Réconciliation : création, mise à jour, réactivation, désactivation, idempotence, isolation inter-communes, compteurs.
  • Façade Mairie : lecture, création, modification inter-communes, suppression idempotente.
  • Façade Admin : lecture /full, mise à jour et suppression.
  • Territory : transformation du payload externe en DTO métier et appel au contrat.
  • Garde-fous : absence de logique métier élus hors Municipal Management ; absence de références Sirene dans le contrat/DTOs.

8. Hors périmètre respecté

  • Aucun changement sur alertes, services, collectes, infos pratiques, commune_info_sections, relation commune ↔ mairie, autres données SIRENE, migrations SQL, endpoints ou événements.
  • Aucun changement hors périmètre n'est inclus dans cette mission.