Cartographie des Bounded Contexts réels de DMV Core
Statut
Document d'étude — v1.0 — rédigé le 2026-07-22. Ce n'est pas une ADR. Il applique les
principes d'ADR-014 au code existant, dans le but de préparer une future ADR de
cartographie, pas de la remplacer. Aucun code n'a été modifié pour produire ce document.
Convention de lecture : chaque affirmation est marquée [Constat] (observé directement dans le code, avec citation), [Interprétation] (lecture DDD d'un constat, discutable), ou [Recommandation] (proposition d'action, non engageante).
1. Méthodologie
L'inventaire s'appuie sur trois lectures indépendantes du dépôt api/ : deux investigations
ciblées (Identity/Authorization/Actor/Community/Territory d'une part, Publication/Mairie/
Monetization/notifications d'autre part), chacune avec instruction de ne rapporter que des
faits vérifiables avec citation fichier:ligne, et un inventaire complémentaire couvrant les
modules restants (AI, Admin, Analytics, AssoSuite, Chat, Import, PlayLoop, Ranking, Rewards,
Settings). L'analyse DDD (classification, ownership, recommandations) a été produite après
coup, à partir de ces constats — jamais l'inverse, pour éviter de plaquer un modèle théorique
sur le dépôt.
Chaque module a été examiné selon quatre angles : ses propres modèles et tables, ses
contrôleurs/services, ses imports croisés vers d'autres modules (use App\Modules\...), et
ses écritures directes via DB::table() (qui n'apparaissent pas dans un grep d'imports
Eloquent et ont nécessité une recherche séparée).
2. Inventaire de l'existant
[Constat] Dix-sept modules existent sous api/app/Modules/ : AI, Actor, Admin,
Analytics, AssoSuite, Chat, Community, Identity, Import, Mairie, Monetization, PlayLoop,
Publication, Ranking, Rewards, Settings, Territory. C'est plus que ce que documentait le
dernier état des lieux (00-governance/01-project-overview.md, 2026-05-08) — AI, Import,
Ranking et Rewards sont apparus depuis.
Nombre de routes déclarées par module (indicateur de volume, pas de qualité) :
| Module | Routes | Module | Routes |
|---|---|---|---|
| Admin | 135 | AssoSuite | 24 |
| Actor | 40 | PlayLoop | 20 |
| Mairie | 29 | Community | 16 |
| Monetization | 13 | Publication | 12 |
| AI | 12 | Settings | 8 |
| Territory | 8 | Chat | 6 |
| Analytics | 5 | Identity | 5 |
| Rewards | 2 |
Import et Ranking n'exposent aucune route HTTP propre (confirmé par l'absence de
Routes/api.php dans ces deux modules) — ce sont des capacités invoquées par du code
serveur (connecteurs d'import, job planifié), pas des points d'entrée API.
3. Analyse par module
Pour chaque module : responsabilités observées, données possédées, et couplages trouvés. Les cinq modules explicitement signalés (Identity, Actor, Community, Mairie, Monetization) sont traités en détail ; les autres reçoivent un traitement plus court, proportionné aux constats trouvés.
Identity
[Constat] Modèles Profile (profiles), UserRole (users_roles). Service
AuthController + SupabaseTokenService pour l'échange de jeton (déjà documenté par les
travaux précédents). ProfileService::resolveManagedCommunes()
(app/Modules/Identity/Services/ProfileService.php:111-164) exécute une jointure directe
users_roles → communes → acteurs (lecture seule) et retourne des données de Territory et
d'Actor (slug/logo de l'acteur mairie) directement depuis Identity. IdentityServiceProvider
délègue la Gate own-actor à Actor\Services\ActorAccessService::isOwner()
(Providers/IdentityServiceProvider.php:75-77) — Identity ne décide pas lui-même de
l'ownership d'un acteur, il relaie vers Actor.
[Interprétation] Identity reste globalement bien circonscrit à la session et à l'identité
brute. resolveManagedCommunes est la seule fuite trouvée, et elle est en lecture seule —
c'est un modèle de lecture composé hébergé au mauvais endroit plutôt qu'une violation
d'écriture.
Actor
[Constat] Modèle central Acteur (table acteurs), plus ActeurCollaborateur,
ActeurTag, ActeurXpEvent, Document, ActeurAlerte (jamais utilisé ailleurs dans le
code, voir §6), et surtout ActorAccessService
(app/Modules/Actor/Services/ActorAccessService.php), le moteur RBAC central : résout rôle,
permissions et modules pour une paire (acteur, utilisateur), avec court-circuit
is_platform_admin. Réutilisé tel quel par les deux middleware de Mairie
(EnsureMairieAccess.php:60-70, EnsureCommuneManager.php:97-107).
[Constat] Deux écritures croisées trouvées : ActeurModulesController.php:249-284 crée,
met à jour et désactive directement des lignes MairieAlerte (table du module Mairie) ;
ActeurWriteService.php:122-147 appelle ActorXpService::award() et
RewardEngineService::recordEvent() comme effet synchrone de la création d'une publication —
en réalité ce dernier point concerne surtout Publication (voir plus bas), mais Actor possède
également son propre appel direct à RewardEngineService (ActeurWriteService.php:158,163).
[Interprétation] Actor est correctement propriétaire de ses propres données (acteur, collaborateurs, tags, XP). Le problème n'est pas une mauvaise propriété de données, c'est un rayon d'action trop large côté écriture (Mairie, Rewards) et un rôle d'autorité d'autorisation partiellement centralisé — partiellement seulement, puisque Community, AssoSuite et Monetization ne le réutilisent pas (voir §6).
Community
[Constat] Modèles Contributor, ContributorFavori, Groupe, GroupeMembre,
GroupeTag. Tous les imports croisés trouvés (Identity\Models\Profile,
Actor\Models\Acteur, Actor\Models\Tag) sont des lectures — relations Eloquent ou
validations (Tag::whereIn, CommunityWriteService.php:348). Aucune écriture croisée
trouvée. CommunityPolicy implémente sa propre logique d'autorisation
(Policies/CommunityPolicy.php:24,64-73), indépendante d'ActorAccessService.
[Interprétation] Community est le module le plus proprement isolé des cinq examinés en détail. Sa seule faiblesse est de participer à la fragmentation de l'autorisation (§6), pas une violation d'ownership de données.
Mairie
[Constat, le plus significatif de cette cartographie] Le module regroupe des responsabilités de nature très différente :
- Alertes (
mairie_alertes) et Services municipaux (mairie_services) : entièrement autonomes dans le module, créés/modifiés uniquement parMairieWriteService.php:34-79et101-147, gérés via les tables propres du module. Génériques dans leur mécanique — un acteur de type mairie a des alertes et des services — juste restreints parkind === 'mairie'dans les deux middleware. - Publications mairie : délègue entièrement à
Publication\Services\PublicationWriteServiceetPublicationReadService(MairieWriteService.php:12-14,157-212), en forçantscope='mairie'— un bon exemple d'usage de contrat plutôt que de duplication. - Champ
description/image_urlde la commune : écrit directement dans la tablecommunes(propriété de Territory) viaDB::table('communes')->update()(MairieWriteService.php:225). - Élus, collectes, infos pratiques (
commune_elus,commune_collectes,commune_infos) : CRUD complet implémenté dansMairieWriteService.php:233-351viaDB::table()brut, sans passer par les modèles EloquentTerritory\Models\CommuneElu/CommuneCollecte/ CommuneInfoqui existent pourtant pour ces mêmes tables. Les lectures, elles, utilisent bien ces modèles Territory (MairieReadService.php:13-16,100-124). Territory possède, de son côté, un troisième chemin d'écriture indépendant sur ces mêmes tables : le rafraîchissement automatique SIRENE (Territory/Services/CommuneMairieDataRefreshService.php:218,232,246,260,314,321,323).
Trois chemins de code distincts, dans deux modules différents, écrivent aujourd'hui dans les mêmes trois tables.
[Interprétation] « Mairie » n'est pas aujourd'hui un Bounded Context cohérent — c'est un assemblage de deux natures de responsabilité bien distinctes : (a) des capacités acteur-génériques restreintes à un type d'acteur (Alertes, Services, Publications), qui relèvent conceptuellement d'Actor ; (b) de la gestion administrative d'une commune (Élus, Collectes, Infos, champs de la commune elle-même), qui relève conceptuellement de Territory, mais dont le code d'écriture vit aujourd'hui dans Mairie plutôt que dans Territory. C'est précisément le cas que la mission demandait de ne pas trancher par réflexe — voir §5 pour le développement complet.
Monetization
[Constat] Modèles propres (ActorSubscription, Boost, BoostCatalog,
BoostPurchase, PushUsage, SubscriptionLog, SubscriptionPlan) tous correctement
scopés. Mais plusieurs écritures directes dans la table acteurs (propriété d'Actor) :
featured_until (BoostUsageService.php:207-212), stripe_account_id
(MonetizationWriteService.php:62-63,362-366), badge_verifie/badge_label
(MonetizationWriteService.php:392-412, docblock indiquant qu'il s'agit de la ré-implémentation
d'un trigger Supabase existant). L'autorisation d'accès à un acteur est réimplémentée
indépendamment (ensureOwner() dans trois contrôleurs, requête directe sur user_acteurs)
plutôt que de réutiliser ActorAccessService.
[Interprétation] Monetization connaît trop peu Actor pour ses propres besoins (aucune lecture des permissions existantes) et le connaît trop pour ce qui devrait rester du ressort d'Actor (badge, mise en avant) — les deux symptômes viennent du même défaut : aucun contrat publié entre les deux modules, seulement des accès directs dans les deux sens.
Publication
[Constat] Modèles propres et cohérents (Publication, PublicationCommune,
PublicationReport, TypePublication). Aucune logique de notification ou d'email trouvée.
En revanche, PublicationWriteService.php:122-147 appelle directement
ActorXpService::award() et RewardEngineService::recordEvent() à trois reprises comme
conséquence synchrone de la création d'une publication.
[Interprétation] C'est la violation la plus nette et la plus directement comparable à
l'exemple donné par ADR-014 lui-même (« Publications ne doit pas contenir de logique de
notifications ») — ici appliqué à l'XP et aux récompenses plutôt qu'aux notifications, mais
de nature strictement identique : Publication décide d'une conséquence externe à sa propre
responsabilité.
Territory
[Constat] Modèles Commune, CommuneCollecte, CommuneElu, CommuneInfo,
CommuneDefibrillateur(Sync), CommuneSireneSnapshot, DefibrillateurCatalogue(Sync).
La colonne communes.mairie_actor_id (0000_00_00_000005_create_communes_table.php:32,
re-confirmée 000073_add_mairie_actor_id_to_communes.php:28) n'a aucune contrainte de clé
étrangère en base — un UUID indexé nullable, sans garantie référentielle. Fait plus
significatif : CommuneMairieDataRefreshService.php:148,158 écrit directement dans la table
acteurs (kind, categorie_id, numero_siret) via DB::table('acteurs')->update() — une
écriture croisée dans le sens inverse de celle observée côté Mairie (Territory → Actor cette
fois).
[Interprétation] Territory n'est pas seulement consulté par Mairie, il écrit lui-même dans Actor. Le couplage Actor ↔ Territory ↔ Mairie est bidirectionnel et déjà profond, confirmant que ces trois modules ne peuvent pas être analysés indépendamment (voir §5).
AI
[Constat] Prompts, providers, cache, quotas, logs d'usage — aucune donnée métier propre, aucun couplage à un autre module trouvé dans l'inventaire (non vérifié aussi exhaustivement que les cinq modules prioritaires).
[Interprétation] Ne ressemble pas à un Bounded Context métier — c'est une capacité
technique transverse, cohérente avec le vocabulaire déjà établi (Knowledge Engine /
Experience Engine, 08-frontend/architecture DMV synthese.md §7.4) plutôt qu'un domaine au
sens de cette cartographie.
Admin
[Constat] 24 contrôleurs/services, 135 routes, 17 imports croisés recensés par l'agent d'investigation vers Actor, Territory, Identity, Monetization, Publication — la totalité des modules métier examinés. Sert exclusivement le Backoffice.
[Interprétation] Ressemble à un adaptateur au sens d'ADR-014 §12 (traduction vers un
consommateur externe, agrégation en lecture) plutôt qu'à un Bounded Context — mais ceci n'a
pas été vérifié aussi rigoureusement que les cinq modules prioritaires : je n'ai pas
contrôlé si ses services d'écriture (AdminActeurService, AdminClaimService, etc.)
dupliquent des règles métier plutôt que de déléguer aux modules propriétaires. Point à
vérifier avant toute conclusion définitive.
Analytics
[Constat] Docblock explicite : « Aucune écriture, aucun recalcul dans PHP »
(AnalyticsService.php:18) — s'appuie sur des fonctions PostgreSQL (DB::select('SELECT * FROM get_stats_acteur(...)')). Lit Monetization\Models\PushUsage.
[Interprétation] Un modèle de lecture composé au sens propre du terme — exactement le même schéma que Search dans l'étude précédente sur DMV Core.
AssoSuite, PlayLoop
[Constat] AssoSuite possède ses propres modèles (AssoMember, AssoProject,
AssoCotisation...) et son propre middleware d'autorisation
(EnsureAssoAccess.php:24-31, vérifie directement AssoMember sans passer par
ActorAccessService). PlayLoop possède également ses propres modèles et son propre
mécanisme d'authentification par appareil (DeviceTokenMiddleware).
[Interprétation] Les deux sont déjà des Bounded Contexts correctement isolés — cohérent
avec ADR-000, qui prévoit qu'ils deviennent des applications à part entière. Leur seul
défaut commun est de réimplémenter leur propre logique d'autorisation plutôt que de
converger vers un mécanisme partagé (§6).
Chat, Settings, Ranking, Rewards, Import
[Constat] Chat ne référence que Identity\Models\Profile — aucun couplage à Actor ou
Community trouvé. Settings ne présente aucun import croisé côté écriture. Ranking lit
app_settings (table de Settings) via DB::table() brut plutôt que via le service
SettingsReadService (RankingService.php:53). Rewards est invoqué directement et
synchronement par Actor et Publication (voir plus haut) plutôt que de réagir à des
événements. Import contient des connecteurs (BessanFrConnector...) qui font clairement
office de couche anti-corruption pour des données externes, sans exposer de route HTTP
propre.
[Interprétation] Chat est un candidat à trancher entre Bounded Context autonome (« Messaging ») ou Platform Service générique — la question reste ouverte (§8). Ranking ressemble à un composant interne de l'Experience Engine plutôt qu'à un Bounded Context de plein droit. Import est un adaptateur, pas un Bounded Context.
4. Bounded Contexts proposés
| Regroupement | Classification proposée | Confiance |
|---|---|---|
| Identity | Bounded Context, périmètre déjà correct (hors resolveManagedCommunes) | Élevé |
| Actor | Bounded Context, ownership de données correct, rayon d'écriture à corriger | Élevé |
| Community | Bounded Context, déjà propre | Élevé |
| Publication | Bounded Context, ownership correct, une violation ponctuelle à corriger | Élevé |
| Monetization | Bounded Context, ownership correct, écritures croisées à corriger | Élevé |
| AssoSuite | Bounded Context déjà isolé, candidat à extraction future (cohérent ADR-000) | Élevé |
| PlayLoop | Bounded Context déjà isolé, candidat à extraction future (cohérent ADR-000) | Élevé (non vérifié aussi exhaustivement) |
| Rewards | Bounded Context valide, mais mal invoqué (synchrone plutôt qu'événementiel) | Élevé |
| Territory | Bounded Context, mais périmètre exact à redéfinir avec Mairie (§5) | Moyen |
| Mairie | Pas un Bounded Context cohérent en l'état — à scinder (§5) | Moyen |
| Authorization | N'existe pas encore comme Bounded Context/capacité propre — actuellement fragmenté dans Actor, Community, AssoSuite, Monetization | Faible (nécessite une décision, pas une simple observation) |
| Claims | Ownership ambigu aujourd'hui (soumission dans Actor, traitement dans Admin) — candidat à devenir son propre petit contexte | Faible |
| AI, Analytics, Settings | Platform Services / capacités transverses, pas des Bounded Contexts métier | Élevé |
| Import | Adaptateur (anti-corruption layer), pas un Bounded Context | Moyen |
| Ranking | Probable composant interne de l'Experience Engine, pas un Bounded Context autonome | Faible (peu vérifié) |
| Chat | Bounded Context autonome ou Platform Service générique — non tranché | Faible |
| Admin | Adaptateur pour le Backoffice, pas un Bounded Context — écritures non auditées | Moyen |
5. Ownership et contrats — le cas Actor / Mairie / Territory en détail
[Interprétation, développée] La preuve du code converge vers trois masses distinctes, actuellement mélangées dans le seul module Mairie :
Ce qui appartient à Actor : Alertes, Services municipaux, et le fait qu'une publication
soit scope='mairie'. Rien de spécifique à la gestion d'une commune ici — c'est un acteur,
de type mairie, qui utilise des capacités déjà génériques (alertes, services, publications)
avec une restriction de type. [Recommandation] Ces trois capacités devraient être
exposées comme des extensions du contrat d'Actor (ou rester dans un sous-module Mairie qui
ne fait qu'orchestrer des appels à Actor et Publication), jamais comme un domaine métier
séparé.
Ce qui appartient à Territory : Élus, Collectes, Infos pratiques, et les champs propres de la commune (description, image). Ce sont des données sur la commune en tant qu'entité administrative — leur pertinence ne dépend pas de l'existence d'un acteur mairie. Aujourd'hui leur écriture vit dans Mairie via SQL brut, en cour-circuitant les modèles Eloquent que Territory possède déjà pour ces mêmes tables. [Recommandation] Cette écriture devrait migrer vers Territory (ou un contexte de gestion municipale distinct, voir ci-dessous), exposée comme un contrat que Mairie (ou la future application MairieSuite) invoque, plutôt que par accès direct aux tables.
Ce qui pourrait relever d'un contexte "Municipal Management" distinct : la question
n'est pas définitivement tranchée par le code. Territory, tel qu'il existe aujourd'hui,
mélange deux préoccupations différentes — des données de référence publique (communes,
défibrillateurs, SIRENE) alimentées par des connecteurs automatisés, et une gestion
administrative pilotée par un utilisateur autorisé (municipal_manager, vérifié par
EnsureCommuneManager). [Interprétation, confiance faible] Un contexte « Municipal
Management », séparé de Territory (référence publique) et distinct d'Actor (identité de
l'acteur mairie), est défendable par analogie avec Publication (éditorial) séparé d'Actor
(identité) — mais rien dans le code n'impose ce choix plutôt que de simplement transférer
Élus/Collectes/Infos à Territory tel quel. C'est une décision produit, pas une déduction du
code (voir §8).
Ce qui relève d'une future application cliente (MairieSuite) : rien dans DMV Core
lui-même — ADR-000 a déjà tranché que MairieSuite sera une application, pas un
prolongement de Workspace. Le périmètre exact de ce qu'elle consommera dépend directement de
l'issue de la question précédente.
Ce qui devrait sortir de DMV Core : rien d'identifié dans le module Mairie qui ne corresponde à aucune des trois catégories ci-dessus — pas de constat allant dans ce sens.
6. Violations ou ambiguïtés observées
| Situation | Fichier(s) | Classification |
|---|---|---|
| Publication décide d'attribuer XP et récompenses | PublicationWriteService.php:122-147 | Violation directe d'ADR-014 (principe 2/4) |
Actor écrit directement dans MairieAlerte | ActeurModulesController.php:249-284 | Violation directe — capacité mal placée, à repositionner dans Mairie |
| Actor invoque directement Rewards | ActeurWriteService.php:158,163 | Violation directe (même nature que Publication) |
Territory écrit directement dans acteurs (SQL brut) | CommuneMairieDataRefreshService.php:148,158 | Violation directe — écriture croisée, contourne le modèle Acteur |
Mairie écrit dans communes, commune_elus, commune_collectes, commune_infos en SQL brut, en parallèle des modèles Eloquent Territory | MairieWriteService.php:225,233-351 | Violation directe + ambiguïté de fond (§5) — deux chemins d'écriture concurrents sur les mêmes tables |
Monetization écrit featured_until, stripe_account_id, badge_verifie/label dans acteurs | BoostUsageService.php:207-212, MonetizationWriteService.php:62-63,362-366,392-412 | Violation directe |
Quatre implémentations indépendantes d'autorisation acteur-scopée (ActorAccessService, CommunityPolicy, EnsureAssoAccess, ensureOwner() de Monetization) | Actor, Community, AssoSuite, Monetization | Ambiguïté architecturale — pas une violation d'ADR-014 au sens strict (aucune n'écrit dans les données d'un autre), mais une absence de contrat partagé qui les expose à diverger silencieusement |
resolveManagedCommunes compose des données Territory/Actor à l'intérieur d'Identity | ProfileService.php:111-164 | Dette mineure — lecture seule, à faire évoluer vers un modèle de lecture composé explicite plutôt qu'un correctif |
acteur_alertes : aucun point d'appel trouvé dans tout le code PHP | ActeurAlerte.php (modèle seul) | Ni une violation ni une dette — probablement une fonctionnalité inachevée ou orpheline, à vérifier avec l'équipe produit |
Ownership de claims non clarifié (soumission dans Actor, traitement dans Admin, aucun modèle Claim dédié) | ActeurWriteService.php (soumission), AdminClaimController/Service (traitement) | Ambiguïté nécessitant une décision produit |
RankingService lit app_settings en SQL brut plutôt que via le service de Settings | RankingService.php:53 | Dette mineure, lecture seule, faible risque |
Aucune situation classée « acceptable temporairement » au sens strict — chaque écriture croisée trouvée touche une donnée qui a un propriétaire clair ailleurs dans le code (Actor, Territory), ce qui en fait des violations directes plutôt que des zones grises.
7. Carte cible
Carte proposée à l'issue de l'analyse — les frontières en confiance faible ou moyenne sont signalées comme telles, pas présentées comme acquises.
Identity [confiance : élevé]
│
├── possède : session, profil, rôles bruts
└── publie : UserAuthenticated, RoleAssigned
Authorization (capacité à extraire) [confiance : faible — décision requise]
│
├── possède : le mécanisme générique de résolution rôle/permission
└── consommé par : Actor, Community, AssoSuite, Monetization (aujourd'hui dupliqué
indépendamment par chacun)
Actor [confiance : élevé]
│
├── possède : identité organisationnelle, collaborateurs, tags, XP, badges
├── consomme : Authorization (lecture), Territory (lecture, commune de rattachement)
└── publie : ActorCreated, ActorUpdated, ActorBadgeEligible (fait, pas décision — voir
Monetization ci-dessous)
Territory [confiance : moyen]
│
├── possède : communes (données de référence publique), élus, collectes, infos
│ pratiques — périmètre à confirmer avec Municipal Management (§5, §8)
└── publie : CommuneUpdated
Municipal Management (candidat, non tranché) [confiance : faible — décision requise]
│
└── gestion administrative d'une commune par un utilisateur autorisé — peut rester
fusionné avec Territory selon l'arbitrage produit du §5
Community [confiance : élevé]
│
├── possède : contributeurs, groupes, favoris
└── consomme : Identity, Actor (lecture seule)
Publication [confiance : élevé]
│
├── possède : cycle de vie éditorial, modération, reports
├── référence : acteur_id
└── publie : PublicationPublished, PublicationModerated (au lieu d'appeler XP/Rewards
directement)
Monetization [confiance : élevé]
│
├── possède : plans, abonnements, boosts, facturation Stripe
├── référence : acteur_id
└── publie : BoostPurchased, SubscriptionChanged, StripeAccountUpdated (au lieu d'écrire
directement dans acteurs)
Rewards [confiance : élevé]
│
├── possède : règles de récompense, octrois, XP
└── consomme (événements, pas appel direct) : PublicationPublished, BoostPurchased
AssoSuite, PlayLoop [confiance : élevé]
│
└── déjà isolés — candidats naturels à devenir des applications (ADR-000)
Claims (candidat, non tranché) [confiance : faible — décision requise]
│
└── workflow de revendication d'une fiche acteur — aujourd'hui dispersé entre Actor et
Admin
AI, Analytics, Settings, Import [confiance : élevé]
│
└── Platform Services / adaptateurs, pas des Bounded Contexts métier
Admin [confiance : moyen]
│
└── adaptateur du Backoffice — écritures propres non encore auditées
8. Points restant à arbitrer
Cinq décisions ne peuvent pas être prises par la seule lecture du code — elles engagent le produit, pas seulement l'architecture :
- Le périmètre Territory / Municipal Management. Élus, Collectes, Infos doivent-ils rejoindre Territory tel quel, ou justifient-ils un contexte de gestion municipale distinct ? Détermine directement le périmètre de la future application MairieSuite.
- L'extraction d'un contexte Authorization. Les quatre implémentations actuelles
doivent-elles converger vers une seule capacité partagée, et si oui, portée par quel
module — un nouveau contexte dédié, ou une promotion d'
ActorAccessServiceau rang de Platform Service généralisé ? - Le statut de Claims. Contexte à part entière avec son propre cycle de vie (soumission → revue → décision), ou sous-domaine d'Actor traité par Admin comme aujourd'hui ?
- Le statut de Chat. Bounded Context métier (« Messaging »formant) ou Platform Service générique de messagerie réutilisable par plusieurs contextes ?
acteur_alertes. Fonctionnalité abandonnée à retirer, ou fonctionnalité prévue mais jamais reliée à un point d'entrée — à vérifier avec l'équipe produit avant toute décision de conservation ou de suppression.
9. Recommandations pour l'étape suivante
[Recommandation] Ne pas traiter cette cartographie comme suffisante pour lancer une migration — c'est un état des lieux, pas un plan. Trois actions suggérées avant toute ADR de migration :
- Trancher les cinq points du §8 avec l'équipe produit — ce sont des décisions, pas des approfondissements techniques supplémentaires à mener seul.
- Auditer les services d'écriture d'Admin (non fait ici, signalé comme lacune au §3) avant de le classer définitivement comme adaptateur pur.
- Prioriser les corrections des violations du §6 par risque plutôt que par ordre
d'apparition — les écritures croisées touchant
acteurs(Territory, Monetization) etcommune_elus/collectes/infos(Mairie) sont les plus profondément ancrées et les plus coûteuses à corriger plus tard ; les appels directs à Rewards/XP (Actor, Publication) sont plus superficiels et plus rapides à convertir en événements.
Aucun plan de migration détaillé n'est proposé ici, conformément au périmètre de cette mission.
Liens associés
docs/decisions/ADR-000-dmv-core-modular-applications.mddocs/decisions/ADR-011-wall-engine-context-engine.mddocs/decisions/ADR-012-architecture-foundation-frozen.mddocs/decisions/ADR-013-workspace-as-application.mddocs/decisions/ADR-014-dmv-core-bounded-contexts.mddocs/06-architecture/26-platform-architecture.mddocs/06-architecture/27-architecture-governance.md