Audit des consommateurs de l'API des alertes mairie
| Mission | Audit des consommateurs de l'API des alertes mairie |
| Rattaché à | ENG-001.5 — Extraction de Municipal Management §8.1, §13.A |
| Type | Audit uniquement — aucune implémentation, aucune décision d'architecture |
| Dépôts inspectés | dmv-workspace, dmv-public, dmv-backoffice, api (dépôt dmv_api) |
| Statut | Audit produit |
1. Objectif
Déterminer avec certitude laquelle des deux API de gestion des alertes mairie — l'API Actor
(/api/v1/acteurs/{acteurId}/alertes) ou l'API Mairie
(/api/v1/mairie/...alertes...) — est réellement utilisée en production aujourd'hui, par quels
consommateurs, pour quels usages (lecture, écriture), afin de permettre une décision ultérieure
(non prise ici) sur l'API canonique à conserver.
Ce document ne tranche rien. Il répond exclusivement à la question factuelle : qui appelle quoi, aujourd'hui, dans le code réel.
2. Cartographie API Actor
| Module backend | Actor |
| Contrôleur | Actor/Controllers/ActeurModulesController.php |
| Modèle utilisé | Mairie\Models\MairieAlerte (import direct, hors module — c'est la violation V-Actor-Mairie déjà documentée par ENG-001-5-municipal-management.md §8.1) |
| Service dédié | Aucun — logique inline dans le contrôleur |
Routes (Actor/Routes/api.php)
| Méthode | Route | Action | Middleware |
|---|---|---|---|
| GET | /acteurs/{acteurId}/alertes | indexAlertes() | identify.app (public, aucune auth) |
| POST | /acteurs/{acteurId}/alertes | storeAlerte() | identify.app + auth:sanctum |
| PATCH | /acteurs/{acteurId}/alertes/{alerteId} | updateAlerte() | identify.app + auth:sanctum |
| PATCH | /acteurs/{acteurId}/alertes/{alerteId}/desactiver | desactiverAlerte() | identify.app + auth:sanctum |
Aucune route de suppression physique — seule la désactivation logique existe (is_active=false).
Autorisation
- Écriture :
$this->authorize('update', $acteur)→ActeurPolicy::update()→ActorAccessService::hasPermission($user, $acteurId, 'manage_actor')(Actor/Policies/ActeurPolicy.php:25-28) — permission générique de gestion de l'acteur. - Restriction de type :
findMairieActeurOrFail()(ActeurModulesController.php:19-28) vérifiekind === 'mairie', 403 sinon. - Ne vérifie ni la permission
manage_alertes, ni l'activation du modulealertespour l'acteur.
Validation (storeAlerte, ActeurModulesController.php:241-247)
'titre' => ['required', 'string', 'max:255'],
'contenu' => ['nullable', 'string'],
'niveau' => ['required', 'string', 'in:info,warning,danger'],
'is_active' => ['sometimes', 'boolean'],
'expires_at' => ['nullable', 'date'],
Réponse
Retourne le modèle Eloquent MairieAlerte sérialisé brut (pas de DTO) : tous les attributs de
colonne, y compris created_at et updated_at (timestamps Eloquent standard).
3. Cartographie API Mairie
| Module backend | Mairie |
| Contrôleur | Mairie/Controllers/MairieAlerteController.php |
| Service | Mairie/Services/MairieWriteService.php (écriture), MairieReadService.php (lecture) |
| DTO | Mairie/DTOs/MairieAlerteDTO.php |
Routes (Mairie/Routes/api.php)
| Méthode | Route | Action | Middleware |
|---|---|---|---|
| GET | /mairie/communes/{communeId}/alertes | index() | identify.app (public, aucune auth) |
| POST | /mairie/acteurs/{acteurId}/alertes | store() | identify.app + auth:sanctum + mairie.access |
| PATCH | /mairie/alertes/{alerteId} | update() | idem |
| DELETE | /mairie/alertes/{alerteId}/desactiver | desactiver() | idem |
Contrairement à l'API Actor, la lecture publique se fait par commune, pas par acteur.
Autorisation (mairie.access → EnsureMairieAccess)
- Vérifie
acteur.kind === 'mairie'(EnsureMairieAccess.php:53-56). ActorAccessService::canAccess()(ownership/collaborateur).- Permission spécifique
manage_alertes(EnsureMairieAccess::resolveRequiredCapability(), route/alertes→['manage_alertes', 'alertes']). - Module
alertesactivé pour l'acteur (hasModule($acteurId, 'alertes')).
Validation (CreateAlerteRequest.php, UpdateAlerteRequest.php)
Création :
'titre' => ['required', 'string', 'max:255'],
'contenu' => ['required', 'string'], // requis, contrairement à Actor
'niveau' => ['required', 'in:info,warning,danger'],
'expires_at' => ['nullable', 'date', 'after:now'], // doit être future, contrainte absente côté Actor
is_active n'est pas dans les règles de création — même envoyé, il est ignoré (filtré par
FormRequest::validated()), puis MairieWriteService::createAlerte() force is_active = true
inconditionnellement (MairieWriteService.php:47).
Mise à jour :
'titre' => ['sometimes', 'string', 'max:255'],
'contenu' => ['sometimes', 'string'],
'niveau' => ['sometimes', 'in:info,warning,danger'],
'expires_at' => ['nullable', 'date'],
'is_active' => ['sometimes', 'boolean'],
Réponse
MairieAlerteDTO::toArray() : id, commune_id, acteur_id, titre, contenu, niveau, is_active, expires_at, created_at — ensemble fixe, dates ISO8601, pas de updated_at.
4. Consommateurs frontend
Recherche exhaustive dans les trois dépôts (grep récursif sur les patterns d'URL des deux API,
sur *.ts/*.tsx/*.js/*.jsx, répertoires node_modules, out, .next, dist, build exclus ;
recherche complémentaire sur fichiers de test et de mock).
dmv-workspace
| Fichier:ligne | Fonction | Route appelée | Écran | Usage |
|---|---|---|---|---|
services/acteur/acteur-modules.service.ts:123-127 | getActeurAlertes() | GET /acteurs/{acteurId}/alertes | Page « Alertes » de l'espace mairie | Lecture, actif |
services/acteur/acteur-modules.service.ts:130-139 | createActeurAlerte() | POST /acteurs/{acteurId}/alertes | idem | Création, actif |
services/acteur/acteur-modules.service.ts:141-151 | updateActeurAlerte() | PATCH /acteurs/{acteurId}/alertes/{alerteId} | idem | Modification, actif |
services/acteur/acteur-modules.service.ts:153-158 | desactiverActeurAlerte() | PATCH /acteurs/{acteurId}/alertes/{alerteId}/desactiver | idem | Désactivation, actif |
app/(workspace)/acteur/[slug]/alertes/page.tsx | Page complète (formulaire, liste, dialogues) | consomme les 4 fonctions ci-dessus | Écran de gestion des alertes | Actif, seul écran de gestion trouvé |
Aucun import ni appel vers /mairie/acteurs/.../alertes, /mairie/alertes/..., ou
/mairie/communes/.../alertes trouvé dans dmv-workspace, malgré la présence d'un dossier
services/mairie/ dédié à d'autres ressources (voir §4 note ci-dessous). Recherche confirmée par
deux passes indépendantes (recherche par motif de route, puis recherche du terme alerte dans
tout l'arbre app/).
Note — autres ressources Mairie utilisées par Workspace, hors périmètre alertes mais
pertinentes pour §10 : services/mairie/commune.ts, elus.ts, collectes.ts, infos.ts
existent et sont bien consommés (app/(workspace)/acteur/[slug]/{commune,elus,collectes}/page.tsx)
pour GET/PATCH /mairie/communes/{communeId} et le CRUD élus/collectes/infos. Aucun
services/mairie/services.ts n'existe, et aucun appel à /mairie/services/... ou
/mairie/communes/{id}/services... n'a été trouvé nulle part dans les trois dépôts — la gestion
des mairie_services (services municipaux) semble sans consommateur frontend actif dans le
périmètre audité.
dmv-public
| Fichier:ligne | Route appelée | Écran | Usage |
|---|---|---|---|
app/[commune]/acteur/[slug]/ActorsClient.tsx:283 | GET /acteurs/{actor.id}/alertes (via apiGetPublic) | Fiche publique d'un acteur mairie, section alertes actives | Lecture, actif |
app/components/wall/hooks/useWallUserSignals.ts:87 | GET /acteurs/{acteur.id}/alertes | Signaux utilisateur du Mur (Wall) | Lecture, actif |
app/components/wall/hooks/useWallUserSignals.ts:133 | GET /acteurs/{id}/alertes | idem, variante (liste de mairies suivies) | Lecture, actif |
app/components/mon-espace/MonEspaceTodaySummary.tsx:228 affiche un libellé « Alertes mairie »
mais consomme les données produites par useWallUserSignals.ts (ci-dessus), pas d'appel HTTP
propre.
Aucun appel vers /mairie/communes/{communeId}/alertes (l'endpoint public Mairie, pourtant
public et donc a priori le plus naturel pour un site public) n'a été trouvé dans dmv-public.
Sur la même page (ActorsClient.tsx), les données commune (élus, collectes, infos) sont lues via
GET /communes/{communeId}/elus|collectes|infos — l'API Territory publique, ni Actor ni
Mairie — confirmant que la fiche publique d'un acteur mairie compose déjà des lectures issues de
plusieurs Bounded Contexts.
dmv-backoffice
Aucun consommateur trouvé. Les trois occurrences du terme « alerte » dans ce dépôt
(src/components/Layout.jsx:107, src/pages/CriticiteConfig.jsx,
src/pages/PublicationScoringConfig.jsx:154) concernent la configuration du score de
criticité des publications (un mécanisme de modération de contenu, type_publications de type
« alerte »), un concept homonyme mais fonctionnellement sans rapport avec mairie_alertes.
Confirmé par lecture du contenu de chaque fichier.
Tests et mocks
Une seule occurrence du terme « alerte » dans les suites de tests des trois dépôts :
dmv-public/lib/feedEngine/__tests__/pipeline.test.ts — teste le classement d'une publication de
type_publications.nom === 'alerte' dans le moteur de flux (Wall), sans rapport avec
mairie_alertes non plus. Aucun test frontend, dans aucun des trois dépôts, n'exerce l'une ou
l'autre des deux API d'alertes mairie.
5. Consommateurs backend
ExpireAlertesJob (Mairie/Jobs/ExpireAlertes.php) : n'appelle aucune des deux API HTTP. Il invoque directementMairieWriteService::expireAlertes()en mémoire (job horaire), qui exécute une mise à jour de masse sur le modèle EloquentMairieAlerte— indépendant du chemin HTTP utilisé pour créer les alertes, donc indépendant du résultat de cet audit.- Commandes Artisan : aucune commande ne référence
mairie_alertesouMairieAlerte(vérifié — seulesRefreshMairieSireneCommandetResolveMairiesCommandexistent dansConsole/Commands, aucune des deux ne touche aux alertes). - Listeners : aucun listener trouvé dans le dépôt référençant
MairieAlerteoumairie_alertes(api/app/Modules/*/Listeners— répertoires absents ou vides pour ce sujet, cohérent avec le constat déjà établi parENG-001-1-dmv-core-audit-report.md: aucune classe d'événement métier n'existe encore dans le projet). - Import : confirmé lors de la rédaction d'
ENG-001-5-municipal-management.md§6.5 — aucune table municipale, y comprismairie_alertes, n'est touchée par le moduleImport. Revérifié ici, inchangé. - Admin : aucune route ni aucun contrôleur Admin ne gère
mairie_alertes(vérifié par lecture deAdmin/Routes/api.php— zéro occurrence du terme « alerte »). Le backoffice n'offre aucune gestion des alertes mairie, ni via l'une ni via l'autre API.
Conclusion. Les deux API HTTP sont exclusivement consommées par les frontends. Aucun usage interne au backend ne dépend de l'une ou l'autre route — un remplacement ou une suppression de route n'affecterait que des clients HTTP externes (les trois frontends audités, et tout client non audité, voir §11).
6. Comparaison fonctionnelle
| Aspect | API Actor | API Mairie | Impact |
|---|---|---|---|
| Lecture publique | Par acteur (/acteurs/{id}/alertes) | Par commune (/mairie/communes/{id}/alertes) | Clé de recherche différente — une migration de lecture nécessiterait de reprojeter la requête |
| Permission d'écriture | manage_actor (générique) | manage_alertes (spécifique) | Un collaborateur avec un rôle restreint pourrait avoir des droits différents selon l'API utilisée |
Vérification du module alertes | Absente | Présente (hasModule) | L'API Actor permet de créer une alerte même si le module « alertes » est désactivé pour l'acteur — l'API Mairie l'interdit. Différence de comportement fonctionnel réelle, pas seulement cosmétique. |
contenu à la création | Optionnel (nullable) | Obligatoire (required) | Un payload valide pour Actor serait rejeté (422) par Mairie |
expires_at à la création | Aucune contrainte | Doit être future (after:now) | Idem — une date passée est acceptée par Actor, rejetée par Mairie |
is_active à la création | Respecté si fourni par le client | Toujours forcé à true, valeur cliente ignorée | Une alerte créée « inactive » est possible via Actor, impossible via Mairie |
| Suppression physique | Absente (aucune des deux) | Absente (aucune des deux) | Identique — pas de différence |
| Forme de la réponse | Modèle Eloquent brut (tous les attributs, dont updated_at) | DTO figé (MairieAlerteDTO, sans updated_at) | Un client qui dépendrait de champs non exposés par le DTO (ex. updated_at) casserait en migrant vers Mairie |
Résolution de commune_id à la création | Lecture de l'attribut Eloquent déjà chargé ($acteur->commune_id) | Requête dédiée (getCommuneIdForActeur()) | Résultat identique en pratique, chemin de code différent |
Ce qui empêcherait un remplacement immédiat, sans changement de comportement observable :
- La vérification du module
alertes(présente côté Mairie, absente côté Actor) — basculer tous les clients vers Mairie sans adaptation changerait le comportement pour tout acteur ayant ce module désactivé (blocage nouveau) ; basculer vers Actor de façon définitive maintiendrait un contournement de ce contrôle qui existe déjà aujourd'hui côté Actor. - La contrainte
contenuobligatoire etexpires_atfuture à la création côté Mairie — un payload aujourd'hui accepté par Actor (contenu vide, date passée) serait rejeté si le trafic basculait vers Mairie sans adapter le frontend. - La forme de la réponse (DTO vs modèle brut) — tout code frontend qui lirait un champ absent du DTO Mairie (aucun trouvé dans le code actuel, mais non garanti pour des consommateurs non audités, voir §11) casserait silencieusement.
- La clé de lecture publique (par acteur vs par commune) — la migration de la lecture publique nécessiterait une adaptation du frontend, pas seulement un changement d'URL.
7. Compatibilité
Cas constaté : Cas D, avec asymétrie marquée. Les deux API sont utilisées simultanément, mais pas pour les mêmes ressources :
mairie_alertes: uniquement l'API Actor est utilisée par les trois frontends audités, en lecture (dmv-public, deux écrans) et en écriture (dmv-workspace, un écran complet). L'API Mairie (MairieAlerteController) n'a aucun consommateur trouvé dans les trois dépôts.commune_elus/commune_collectes/commune_infos/communes(commune) : l'API Mairie est utilisée pardmv-workspaceen écriture ; la lecture publique passe par l'API Territory, ni Actor ni Mairie.mairie_services: aucune des deux API pertinentes (il n'existe qu'une API Mairie pour cette ressource) n'a de consommateur trouvé dans les trois dépôts.
Ce n'est donc ni le Cas A, ni le Cas B, ni le Cas C tels que formulés par la mission : c'est un Cas D où, pour la ressource alertes spécifiquement, l'API qui semble « legacy » au vu de sa localisation dans le code (Actor, hors du module Mairie qui porte le nom de la fonctionnalité) est en réalité celle qui est réellement utilisée, et l'API qui semble « canonique » de par son emplacement (module Mairie) est celle qui n'a aucun consommateur actif trouvé.
Impacts et risques par hypothèse de suite :
- Si l'API Mairie (
MairieAlerteController) était supprimée aujourd'hui : aucun impact détecté sur les trois frontends audités. Risque résiduel : tout consommateur non audité (voir §11). - Si l'API Actor (
ActeurModulesController, endpoints alertes) était supprimée aujourd'hui : rupture immédiate de l'écran de gestion des alertes dansdmv-workspace(4 fonctions) et de l'affichage des alertes actives dansdmv-public(3 emplacements). Impact majeur, à éviter sans migration préalable du frontend. - Migration nécessaire dans les deux sens : quelle que soit l'API retenue comme canonique, au moins un consommateur frontend actif devra être adapté — sauf si l'API Actor est retenue telle quelle (aucune adaptation frontend nécessaire, uniquement un changement d'implémentation côté backend, voir Option B §8).
8. Options
Présentées sans décision, conformément à la mission.
Option A — Conserver l'API Mairie comme canonique
- Avantages. Cohérent avec l'ownership cible (
RFC-001: alertes municipales appartiennent à Municipal Management, dont Mairie est l'ancêtre direct) ; autorisation plus fine déjà en place (manage_alertes, vérification du module) ; réponse déjà sous forme de DTO stable. - Inconvénients. Nécessite d'adapter trois écrans actifs (un dans
dmv-workspace, deux dansdmv-public) vers la nouvelle clé de lecture (par commune plutôt que par acteur pour la lecture publique) et vers des règles de validation plus strictes (contenurequis,expires_atfuture) — un changement fonctionnel non trivial, potentiellement perceptible par les utilisateurs actuels de Workspace (formulaire différent) si le frontend n'est pas adapté en amont. - Risques. Migration frontend à coordonner sur deux dépôts avant toute suppression de l'API Actor ; fenêtre de coexistence obligatoire.
- Dette technique. Aucune nouvelle dette — résorbe la duplication.
- Impact Municipal Management. Aligné nativement — Mairie devient directement le socle du
futur module, cohérent avec
RFC-001. - Impact frontend. Élevé — trois écrans à adapter avant toute suppression côté backend.
Option B — Conserver l'API Actor comme canonique
- Avantages. Aucune adaptation frontend nécessaire — c'est déjà l'API réellement utilisée
partout. Migration purement backend : réimplémenter
ActeurModulesControllerpour déléguer à un futur service Municipal Management au lieu d'accéder directement au modèle, sans changer les routes ni les contrats de payload/réponse déjà consommés. - Inconvénients. Contredit la logique de nommage et l'intuition d'ownership (une route
/acteurs/...gérée par un contexte qui n'est pas censé posséder cette donnée) ; nécessite de corriger consciemment les deux lacunes fonctionnelles identifiées (permissionmanage_alertesabsente, vérification de module absente) pour ne pas figer un comportement moins strict que prévu comme comportement définitif. - Risques. Si les deux lacunes de contrôle d'accès ne sont pas corrigées au passage, elles deviennent une dette permanente plutôt qu'un accident de trajectoire.
- Dette technique. Nécessite de documenter formellement pourquoi l'API publique porte un nom
(
/acteurs/...) qui ne reflète pas son Bounded Context propriétaire réel (Municipal Management) — écart nom/ownership à assumer explicitement plutôt qu'à corriger. - Impact Municipal Management. Le futur module devrait exposer ses contrats via des routes
historiquement logées dans Actor — inhabituel mais pas bloquant (
ADR-014§12 : les routes sont des adaptateurs, pas l'implémentation elle-même). - Impact frontend. Nul à court terme.
Option C — Façade de compatibilité temporaire
- Avantages. Permet de basculer l'implémentation backend (vers Municipal Management à terme) sans attendre la coordination des trois dépôts frontend ; les deux routes actuelles restent disponibles, l'une (Mairie) authentique, l'autre (Actor) en façade de compatibilité qui délègue au même service sous-jacent.
- Inconvénients. Maintient deux surfaces API pour la même ressource plus longtemps ; un garde-fou architectural (comme celui introduit par ENG-001.4 pour Territory → Actor) devient plus difficile à écrire puisque la façade elle-même doit légitimement appeler le service interne.
- Risques. Si la façade n'est jamais retirée faute de suivi, la duplication redevient permanente — nécessite un engagement explicite de dépréciation avec échéance.
- Dette technique. Dette explicitement temporaire et documentée, la moins mauvaise des trois formes de dette si un calendrier de retrait est fixé et respecté.
- Impact Municipal Management. Neutre — le module peut être créé et devenir propriétaire exclusif de la donnée sans attendre la clarification de la façade externe.
- Impact frontend. Nul à court terme ; nécessite malgré tout, à terme, la même migration que l'Option A pour permettre le retrait de la façade.
9. Recommandation
Cette section formule une recommandation argumentée, conformément à la mission — elle ne constitue pas une décision actée.
Les faits constatés (§4-§7) pointent vers l'Option B comme la moins risquée à court terme :
l'API Actor est déjà, de facto, l'unique API réellement utilisée pour mairie_alertes par les
trois frontends audités ; l'API Mairie n'a aucun consommateur actif détecté. Choisir l'Option A
imposerait une migration frontend sur trois écrans avant de pouvoir supprimer quoi que ce soit
côté backend, pour un gain d'alignement architectural qui peut être obtenu autrement (faire
pointer les routes /acteurs/.../alertes vers un service Municipal Management interne, sans
changer les routes elles-mêmes — cohérent avec ADR-014 §12, « DMV Core n'est pas l'API »).
L'Option C n'apporte pas d'avantage suffisant ici puisque l'API « à déprécier » (Mairie) n'a déjà
aucun trafic à faire coexister.
Cette recommandation ne dispense pas de trancher explicitement les deux lacunes fonctionnelles
identifiées en §6 (permission manage_alertes, vérification du module alertes) — quelle que
soit l'option retenue, ces deux points doivent être une décision consciente, pas un oubli
hérité.
Recommandation : Option B, sous réserve de vérification qu'aucun consommateur non audité n'utilise l'API Mairie (§11).
10. Impact sur les futures PR
Réévaluation du découpage Municipal-A à Municipal-F proposé par
ENG-001-5-municipal-management.md §12, à la lumière de cet audit. Aucun document de roadmap
n'est modifié ici — recommandation uniquement.
- Le découpage en six PR reste globalement pertinent. Aucune PR ne doit être supprimée.
- PR Municipal-B (« résolution de la duplication Actor/Mairie ») devrait être précisée, pas déplacée : son option recommandée n'était pas encore connue au moment de sa rédaction (elle demandait explicitement une vérification frontend avant arbitrage, §13.A de la spec principale) — cet audit fournit cette vérification. Le risque documenté dans la spec (« rupture d'un client existant... à vérifier côté frontend avant implémentation ») est désormais levé dans un sens précis : c'est l'API Mairie qui peut être retirée sans impact frontend détecté, pas l'inverse.
- PR Municipal-C (« déplacement d'Alertes et Services municipaux ») doit intégrer une
clarification : les alertes ont un consommateur actif à préserver (API Actor) tandis que les
services municipaux (
mairie_services) n'en ont aucun dans le périmètre audité — ces deux ressources, actuellement regroupées dans la même PR, ont des profils de risque différents. Ne pas fusionner ni scinder sans arbitrage explicite, mais signaler l'asymétrie à l'architecte. - Aucune nouvelle PR n'apparaît nécessaire du fait de cet audit — les corrections des deux lacunes fonctionnelles (§6) peuvent être absorbées par PR Municipal-B, qui touche déjà ce périmètre.
11. Décisions restant ouvertes
Cet audit ne tranche rien. Les points suivants restent à arbitrer par l'architecte :
- Choix entre Option A, B et C (§8) — recommandation formulée (§9), décision non prise.
- Correction des deux lacunes fonctionnelles de l'API Actor (permission
manage_alertesabsente, vérification du modulealertesabsente) — à corriger quelle que soit l'option retenue, mais le mécanisme exact (ajout des contrôles manquants dansActeurModulesController, ou délégation complète à un futur service partagé qui les porterait nativement) n'est pas arbitré ici. - Consommateurs non audités. Cet audit couvre exclusivement
dmv-workspace,dmv-public,dmv-backofficeet le backendapi, conformément au périmètre de la mission. Il ne couvre pas : une éventuelle application mobile Capacitor,dmv_backoffice(l'autre backoffice, à accès Supabase direct, distinct dedmv-backoffice, non mentionné par la mission), ni tout consommateur externe (partenaire, script, intégration tierce). L'affirmation « aucun consommateur actif de l'API Mairie » est valable dans le périmètre audité uniquement — à confirmer avant toute suppression de route. - Calendrier et modalités d'une éventuelle façade de compatibilité (Option C), si elle devait finalement être retenue malgré la recommandation en sens contraire.
- Précision du découpage Municipal-C (§10) : scinder Alertes et Services municipaux en deux PR distinctes, ou les garder groupées avec un risque documenté comme asymétrique — non tranché ici.
Références
- ENG-001.5 — Extraction de Municipal Management §8.1, §13.A, §13.B
- ENG-001-1 — Rapport d'audit DMV Core §4, §8, §10 (PR-003)
- ADR-014 — DMV Core : Bounded Contexts et Monolithe Modulaire