ENG-001.1 — Rapport d'audit DMV Core
| Mission | ENG-001.1 — Audit DMV Core |
| Epic | EPIC-001 — Restructuration de DMV Core |
| Statut | Rapport produit |
| Périmètre | Observation et documentation uniquement |
| Code applicatif | Aucun changement |
Synthèse exécutive
DMV Core dispose déjà d'une structure modulaire nette dans api/app/Modules, avec 17 modules métier ou techniques identifiés. Cette structure est une base exploitable pour la migration cible, mais elle ne garantit pas encore les frontières de Bounded Contexts définies par l'ADR-014.
Les principaux écarts sont :
- ownership de données non respecté sur plusieurs tables métier ;
- dépendances directes entre modules via modèles internes, services internes ou accès
DB::table; - absence d'événements métier explicites ;
- responsabilités municipales fragmentées entre
MairieetTerritory; - couche
Admintrès couplée aux tables métier ; - effets transverses synchrones vers Rewards, Monetization, Actor et Publication.
Conclusion : la restructuration peut être engagée de manière incrémentale, sans réécriture globale, mais l'audit confirme que le backend n'est pas encore conforme à l'architecture cible.
Références analysées
| Source | Rôle |
|---|---|
dmv-docs/docs/decisions/ADR-014-dmv-core-bounded-contexts.md | Règles d'ownership, contrats, événements et dépendances autorisées |
dmv-docs/docs/06-architecture/28-dmv-core-bounded-context-map.md | Cartographie cible et constats d'architecture |
dmv-docs/docs/06-architecture/30-dmv-core-migration-roadmap.md | Roadmap de migration cible DMV Core |
api/app/Modules | Implémentation réelle de DMV Core |
api/app/Modules/*/Routes/api.php | Interfaces HTTP exposées |
api/app/Modules/*/Services/*.php | Logique applicative et dépendances |
api/app/Modules/*/Models/*.php | Ownership implicite des tables |
1. Cartographie des modules
| Module | État code | Responsabilité observée | API exposée | Données principales | Dépendances notables |
|---|---|---|---|---|---|
AI | 4 modèles, 7 services, 1 contrôleur | Quotas IA, prompts, cache, usages | Oui | ai_cache, ai_prompts, ai_usage_logs, ai_user_quotas | Lit Monetization pour quotas et boosts |
Actor | 15 modèles, 6 services, 5 contrôleurs | Identité organisationnelle, collaborateurs, modules, tags, XP local | Oui | acteurs, user_acteurs, acteur_collaborateurs, acteur_modules, documents, tags | Écrit Mairie et Monetization ; appelle Rewards |
Admin | 2 modèles, 12 services, 24 contrôleurs | Backoffice, supervision, imports, modération, interventions manuelles | Oui | import_runs, import_sources, accès multi-tables | Écrit directement Actor, Publication, Monetization, Community, Territory |
Analytics | 0 modèle, 1 service, 1 contrôleur | Agrégats et statistiques | Oui | Lecture multi-tables | Lit Monetization et autres tables |
AssoSuite | 5 modèles, 6 services, 4 contrôleurs | Membres, projets, cotisations d'association | Oui | assosuite_* | Lit Actor, utilise Settings |
Chat | 3 modèles, 1 service, 1 contrôleur | Rooms, messages, accusés de lecture | Oui | chat_rooms, chat_messages, chat_read_receipts | Faible couplage observé |
Community | 5 modèles, 2 services, 2 contrôleurs | Contributeurs, groupes, favoris | Oui | contributors, groupes, groupe_membres, contributor_favoris | Utilise modèles Actor pour tags ; logique d'autorisation locale |
Identity | 2 modèles, 2 services, 1 contrôleur | Profils utilisateurs et rôles globaux | Oui | profiles, users_roles | Faible couplage observé |
Import | 0 modèle, 1 service, 0 contrôleur | Connecteurs d'import et création de publications | Non | Utilise import_*, publications | Dépend d'Admin et écrit Publication |
Mairie | 2 modèles, 2 services, 4 contrôleurs | Alertes/services mairie et données municipales | Oui | mairie_alertes, mairie_services, commune_* | Écrit Territory ; appelle Publication et Actor |
Monetization | 7 modèles, 6 services, 3 contrôleurs | Plans, abonnements, boosts, Stripe | Oui | actor_subscriptions, subscription_plans, boosts, boost_catalog, subscription_logs | Écrit Actor et Publication ; appelle AssoSuite |
PlayLoop | 5 modèles, 2 services, 2 contrôleurs | Campagnes, devices, playlists, médias | Oui | playloop_* | Lit Publication |
Publication | 4 modèles, 2 services, 2 contrôleurs | Publications, modération, rapports | Oui | publications, publication_communes, publication_reports, type_publications | Lit Actor/Community ; appelle Actor XP et Rewards |
Ranking | 0 modèle, 1 service, 0 contrôleur | Classements calculés | Non | Lecture app_settings, publications | Lit Settings directement |
Rewards | 3 modèles, 2 services, 1 contrôleur | Règles, événements d'activité, récompenses | Oui | actor_activity_events, reward_rules, reward_grants | Écrit boosts Monetization |
Settings | 3 modèles, 2 services, 1 contrôleur | Paramètres applicatifs et onglets | Oui | app_settings, feature_tabs, feature_tab_overrides | Service lu par autres modules |
Territory | 9 modèles, 10 services, 1 contrôleur | Communes, géocodage, données territoriales et référentiels | Oui | communes, commune_elus, commune_collectes, commune_infos, commune_defibrillateurs | Écrit Actor et données municipales |
2. Bounded Contexts
| Context cible | État actuel | État cible | Priorité |
|---|---|---|---|
| Identity | Présent, globalement isolé | Session, profil, rôles bruts uniquement | P2 |
| Actor | Présent mais mélange organisation, XP local, abonnements initiaux et alertes mairie | Identité organisationnelle, rôles acteur, collaborateurs, claims | P0 |
| Territory | Présent mais écrit Actor et données municipales | Données strictement territoriales : commune, INSEE, géo, identité territoriale | P0 |
| Municipal Management | Fragmenté entre Mairie et Territory | Services municipaux, élus, collectes, alertes, infos pratiques | P0 |
| Community | Présent mais autorisation et tags dépendent partiellement d'autres contextes | Contributeurs, groupes, favoris, droits communautaires | P1 |
| Publication | Présent mais déclenche Rewards/XP synchrones et lit Community/Actor directement | Cycle éditorial, modération, publication, signalements | P0 |
| Monetization | Présent mais modifie Actor et Publication | Plans, abonnements, boosts, billing, transactions | P0 |
| Rewards | Présent mais crée des boosts Monetization directement | Règles, grants, calculs de récompense à partir d'événements | P0 |
| AssoSuite | Présent, plutôt isolé | Contexte applicatif ou app dédiée | P2 |
| PlayLoop | Présent, plutôt isolé | Contexte applicatif ou app dédiée | P2 |
| Authorization Platform Service | Partiellement présent via ActorAccessService, dupliqué dans Policies/Middleware | Service transverse unique d'autorisation | P1 |
| AI Platform Service | Présent mais lit Monetization directement | Service platform consommant des contrats/quota explicites | P1 |
| Settings Platform Service | Présent | Service de configuration consommé via contrat | P2 |
| Import Adapter | Présent mais dépend d'Admin et écrit Publication | Adapter d'import qui délègue aux contrats des contextes propriétaires | P1 |
| Admin Adapter | Présent mais contient des écritures métier directes | Adapter backoffice sans ownership métier | P0 |
| Analytics Platform Service | Présent en lecture | Read models / agrégats sans write métier | P2 |
| Ranking Platform Service | Présent sans API, lit tables directement | Calcul de classement isolé sur contrats/read models | P2 |
3. Ownership des données
| Table | Owner cible | Lectures externes observées | Écritures externes observées | Conforme |
|---|---|---|---|---|
profiles | Identity | Admin, Policies | Admin claims met à jour certains profils | Non |
users_roles | Identity | Identity/Admin | Non significatif observé | Oui |
acteurs | Actor | Mairie, Territory, Monetization, Admin, Rewards, Analytics, AssoSuite | Territory refresh, Monetization Stripe/badges, Admin actions | Non |
user_acteurs | Actor | Actor/Admin | Actor | Oui partiel |
acteur_collaborateurs | Actor | Actor | Actor | Oui |
acteur_modules | Actor | Actor | Actor | Oui |
acteur_permissions | Actor | Actor/Authorization | Actor | Oui |
acteur_roles | Actor | Actor/Authorization | Actor | Oui |
acteur_tags | Actor | Actor/Community | Actor | Partiel |
tags | Actor | Community | Actor | Partiel |
documents | Actor ou Files Platform Service | Actor | Actor | Partiel |
claims | Actor | Admin | Actor/Admin | Non |
acteur_xp_events | Actor ou Rewards | Actor/Publication | Publication via Actor service | Partiel |
communes | Territory | Mairie, Admin, Actor, Import | Mairie met à jour description/image ; Admin écrit communes | Non |
commune_elus | Municipal Management | Territory, Mairie | Territory refresh et Mairie | Non |
commune_collectes | Municipal Management | Territory, Mairie | Mairie | Partiel |
commune_infos | Municipal Management | Territory, Mairie | Territory refresh et Mairie | Non |
commune_sirene_snapshots | Territory | Territory | Territory | Oui |
commune_defibrillateurs | Territory | Territory | Territory | Oui |
defibrillateurs_catalogue | Territory | Territory | Territory | Oui |
mairie_alertes | Municipal Management | Actor/Mairie | Actor controller et Mairie | Non |
mairie_services | Municipal Management | Mairie | Mairie | Oui |
contributors | Community | Publication, Admin, Policies | Admin actor service modifie can_publish | Non |
contributor_favoris | Community | Community | Community | Oui |
groupes | Community | Community/Admin | Community/Admin | Partiel |
groupe_membres | Community | Community/Admin | Community/Admin | Partiel |
groupe_tags | Community | Community | Community | Oui |
publications | Publication | Import, Admin, Mairie, PlayLoop, Rewards, Ranking, Analytics | Import, Admin, Monetization boosts | Non |
publication_communes | Publication | Publication/Mairie | Publication | Partiel |
publication_reports | Publication | Publication/Admin | Publication/Admin | Partiel |
type_publications | Publication | Publication/Import/Admin | Publication/Admin | Partiel |
actor_subscriptions | Monetization | Actor, AI, Admin, Monetization | Actor auto-subscribe, Admin subscription actions | Non |
subscription_plans | Monetization | AI/Admin/Monetization | Monetization/Admin | Partiel |
subscription_logs | Monetization | Admin/Monetization | Admin/Monetization | Partiel |
boost_catalog | Monetization | Rewards/Admin/AI | Monetization/Admin | Partiel |
boosts | Monetization | Rewards/Admin/AI | Rewards and Admin create boosts | Non |
boost_purchases | Monetization | Monetization | Monetization | Oui |
push_usage | Monetization ou Notification | Analytics/Monetization | Monetization | Partiel |
reward_rules | Rewards | Rewards/Admin | Rewards/Admin | Partiel |
reward_grants | Rewards | Rewards | Rewards | Oui |
actor_activity_events | Rewards | Rewards | Rewards | Oui |
ai_cache | AI | AI | AI | Oui |
ai_prompts | AI | AI | AI | Oui |
ai_usage_logs | AI | AI | AI | Oui |
ai_user_quotas | AI | AI/Admin | AI | Partiel |
app_settings | Settings | Ranking/Settings | Settings/Admin | Partiel |
feature_tabs | Settings | Settings | Settings | Oui |
feature_tab_overrides | Settings | Settings | Settings | Oui |
import_sources | Import ou Admin Adapter | Import/Admin | Admin/Import | Partiel |
import_runs | Import ou Admin Adapter | Import/Admin | Import | Partiel |
assosuite_members | AssoSuite | AssoSuite | AssoSuite | Oui |
assosuite_projects | AssoSuite | AssoSuite | AssoSuite | Oui |
assosuite_cotisations | AssoSuite | AssoSuite/Monetization webhook | AssoSuite via Monetization webhook delegation | Partiel |
assosuite_cotisation_plans | AssoSuite | AssoSuite | AssoSuite | Oui |
assosuite_invitations | AssoSuite | AssoSuite | AssoSuite | Oui |
chat_rooms | Chat | Chat | Chat | Oui |
chat_messages | Chat | Chat | Chat | Oui |
chat_read_receipts | Chat | Chat | Chat | Oui |
playloop_campaigns | PlayLoop | PlayLoop | PlayLoop | Oui |
playloop_devices | PlayLoop | PlayLoop | PlayLoop | Oui |
playloop_media | PlayLoop | PlayLoop | PlayLoop | Oui |
playloop_playlists | PlayLoop | PlayLoop | PlayLoop | Oui |
playloop_playlist_items | PlayLoop | PlayLoop | PlayLoop | Oui |
4. Dépendances
| Dépendance | Classification | Justification |
|---|---|---|
| Actor → Mairie model | À supprimer | ActeurModulesController importe MairieAlerte et écrit mairie_alertes depuis Actor (api/app/Modules/Actor/Controllers/ActeurModulesController.php:11, api/app/Modules/Actor/Controllers/ActeurModulesController.php:236). |
| Actor → Monetization table | À supprimer | ActeurWriteService insère actor_subscriptions lors de l'auto-subscribe (api/app/Modules/Actor/Services/ActeurWriteService.php:386). |
| Actor → Rewards service | À remplacer par event | ActeurWriteService appelle RewardEngineService::recordEvent après mise à jour d'acteur (api/app/Modules/Actor/Services/ActeurWriteService.php:155). |
| Publication → Actor/Rewards services | À remplacer par event | PublicationWriteService appelle Actor XP et Rewards de manière synchrone (api/app/Modules/Publication/Services/PublicationWriteService.php:120, api/app/Modules/Publication/Services/PublicationWriteService.php:139). |
| Mairie → Territory tables | À supprimer | MairieWriteService met à jour communes et écrit commune_* (api/app/Modules/Mairie/Services/MairieWriteService.php:225, api/app/Modules/Mairie/Services/MairieWriteService.php:233). |
| Territory → Actor tables | À supprimer | CommuneMairieDataRefreshService met à jour acteurs depuis Territory (api/app/Modules/Territory/Services/CommuneMairieDataRefreshService.php:84, api/app/Modules/Territory/Services/CommuneMairieDataRefreshService.php:145). |
| Territory → données municipales | À déplacer | Territory écrit commune_elus et commune_infos, qui relèvent du futur Municipal Management (api/app/Modules/Territory/Services/CommuneMairieDataRefreshService.php:232, api/app/Modules/Territory/Services/CommuneMairieDataRefreshService.php:312). |
| Monetization → Actor/Publication tables | À supprimer ou contractualiser | Stripe Connect écrit acteurs.stripe_account_id; les boosts modifient acteurs.featured_until et publications.featured_until (api/app/Modules/Monetization/Services/MonetizationWriteService.php:62, api/app/Modules/Monetization/Services/BoostUsageService.php:210, api/app/Modules/Monetization/Services/BoostUsageService.php:234). |
| Rewards → Monetization tables | À supprimer | Rewards crée directement des lignes boosts (api/app/Modules/Rewards/Services/RewardEngineService.php:284). |
| Import → Admin models | À corriger | ImportRunnerService dépend de modèles Admin pour ImportRun et ImportSource (api/app/Modules/Import/Services/ImportRunnerService.php:7). |
| Import → Publication table | À remplacer par contrat Publication | ImportRunnerService lit, met à jour et crée des publications directement (api/app/Modules/Import/Services/ImportRunnerService.php:154, api/app/Modules/Import/Services/ImportRunnerService.php:172, api/app/Modules/Import/Services/ImportRunnerService.php:189). |
| Admin → tables métier | À supprimer progressivement | Admin modifie directement publications, actor_subscriptions, boosts, acteurs, contributors (api/app/Modules/Admin/Services/AdminPublicationService.php:241, api/app/Modules/Admin/Services/AdminSubscriptionWriteService.php:30, api/app/Modules/Admin/Services/AdminSubscriptionWriteService.php:84, api/app/Modules/Admin/Services/AdminActeurService.php:115, api/app/Modules/Admin/Services/AdminActeurService.php:204). |
| Ranking → Settings table | À contractualiser | Ranking lit app_settings directement au lieu de passer par SettingsReadService. |
| PlayLoop → Publication read service | Acceptable à court terme | Lecture orientée projection ; à formaliser comme contrat/read model. |
| Analytics → tables métier | Acceptable en lecture | Read-only observé ; doit rester agrégat sans write métier. |
5. Événements métier
| Élément | État actuel | Écart cible |
|---|---|---|
| Classes d'événements métier | Absentes dans api/app/Modules/*/Events | Aucun événement métier typé par contexte |
| Listeners métier | Absents dans api/app/Modules/*/Listeners | Aucun découplage producteur/consommateur |
| Rewards | RewardEngineService::recordEvent écrit actor_activity_events puis évalue immédiatement les règles | Journal applicatif synchrone, pas un événement inter-contextes |
| Actor XP | Publication et Actor appellent directement ActorXpService | Effet externe non découplé |
| Boosts récompense | Rewards crée directement des boosts | Devrait publier une intention ou appeler un contrat Monetization |
| Imports | Import écrit Publication directement | Devrait déléguer à un contrat Publication |
Événements manquants à introduire progressivement :
ActorCreatedActorUpdatedActorClaimSubmittedPublicationCreatedPublicationPublishedPublicationModeratedSubscriptionChangedBoostPurchasedBoostConsumedRewardGrantedMunicipalDataUpdated
6. API
| Module | État API | Cohérence |
|---|---|---|
| AI | API concentrée dans un contrôleur | Cohérente, dépendances quota à contractualiser |
| Actor | API riche et utile | Certaines routes gèrent des données Mairie et Monetization hors ownership |
| Admin | API très large | Fonctionne comme adapter mais contient des écritures métier directes |
| Analytics | API lecture | Cohérente si elle reste read-only |
| AssoSuite | API isolée | Cohérente, dépendances Actor/Settings à formaliser |
| Chat | API isolée | Cohérente |
| Community | API cohérente | Autorisation locale à rapprocher du Platform Service |
| Identity | API limitée | Cohérente |
| Import | Pas d'API module | Orchestration technique pilotée depuis Admin ; ownership ambigu |
| Mairie | API présente | Mélange données mairie, Publication et Territory |
| Monetization | API présente | Cohérente côté billing, mais effets sur Actor/Publication hors ownership |
| PlayLoop | API présente | Cohérente, lecture Publication à formaliser |
| Publication | API présente | Cohérente fonctionnellement, effets externes synchrones à découpler |
| Ranking | Pas d'API | Service interne acceptable, dépendance Settings directe à corriger |
| Rewards | API minimale | Cohérente partiellement, écriture Monetization à supprimer |
| Settings | API présente | Cohérente |
| Territory | API présente | Mélange territoire strict et rafraîchissement mairie/acteur |
7. Platform Services
| Service cible | État actuel | Cible | Priorité |
|---|---|---|---|
| Authorization | ActorAccessService, Policies et Middleware coexistent | Un service unique consommé par les contextes | P1 |
| Notification | Pas de service platform structuré observé dans DMV Core | Service dédié si notifications backend nécessaires | P2 |
| Search | Pas de service platform isolé observé | Contrat Search ou read model si recherche transverse | P2 |
| Storage | Documents gérés côté Actor ; pas de Files Platform Service explicite | Isoler fichiers/documents si usage transverse confirmé | P2 |
| Geocoding | Services dans Territory | Acceptable comme platform/adapter territorial | P2 |
| Files | Pas de service platform explicite | À extraire uniquement si plusieurs contextes écrivent/lisent des fichiers | P2 |
| Settings | Module dédié existant | À consommer via service plutôt que table directe | P2 |
| Analytics | Service lecture existant | Garder read-only et hors ownership métier | P2 |
| Ranking | Service existant | Isoler les inputs via contrats/read models | P2 |
| Import | Service existant mais couplé Admin/Publication | Adapter qui délègue aux contextes propriétaires | P1 |
8. Violations architecturales
| Élément | Gravité | Recommandation |
|---|---|---|
ActeurModulesController écrit mairie_alertes via modèle Mairie | P0 | Déplacer l'écriture derrière un contrat Municipal Management/Mairie. |
ActeurWriteService crée actor_subscriptions | P0 | Remplacer par contrat Monetization ensureFreeSubscription ou event ActorCreated. |
PublicationWriteService appelle Rewards et Actor XP | P0 | Publier des événements métier consommés par Rewards et Actor. |
MairieWriteService écrit communes et commune_* | P0 | Séparer données Territory strictes et Municipal Management. |
CommuneMairieDataRefreshService écrit acteurs | P0 | Remplacer par contrat Actor ou event de rapprochement mairie-acteur. |
MonetizationWriteService écrit acteurs.stripe_account_id | P0 | Déplacer la donnée Stripe owner vers Monetization ou exposer un contrat Actor explicite. |
BoostUsageService écrit acteurs.featured_until et publications.featured_until | P0 | Remplacer par contrats Actor/Publication ou effets consommés par événements. |
RewardEngineService crée des boosts | P0 | Rewards doit émettre une récompense ; Monetization matérialise le boost. |
ImportRunnerService écrit publications | P1 | Déléguer la création/mise à jour à PublicationWriteService ou à un contrat d'import Publication. |
AdminPublicationService modifie directement publications | P0 | Admin doit appeler les use cases Publication. |
AdminSubscriptionWriteService modifie directement Monetization | P1 | Admin doit appeler les use cases Monetization. |
AdminActeurService modifie acteurs et contributors | P1 | Admin doit appeler Actor/Community via contrats. |
CommunityPolicy lit contributors directement | P2 | Déplacer vers Authorization Platform Service ou CommunityReadService. |
PublicationPolicy inspecte la requête HTTP pour choisir les permissions | P1 | Éviter que la policy dépende de la forme de la requête ; déplacer en use case/authorization service. |
| Absence d'événements métier typés | P0 | Introduire une première famille d'événements sur Actor, Publication, Monetization, Rewards. |
9. Dette technique
| Dette | Localisation | Impact |
|---|---|---|
| TODO conversion boosts → crédits IA | api/app/Modules/AI/Services/AIQuotaService.php:148, api/app/Modules/AI/Services/AIQuotaService.php:160 | Règle de monétisation/IA incomplète. |
| Fallback legacy owner | api/app/Modules/Actor/DTOs/ActeurCollaborateurDTO.php:46, api/app/Modules/Actor/DTOs/ActeurCollaborateurDTO.php:56 | Compatibilité historique à isoler avant durcissement. |
| Rôle legacy profil | api/app/Modules/Identity/Models/Profile.php:26 | Ambiguïté entre Identity et Authorization. |
| Fallback legacy Mairie | api/app/Modules/Mairie/Middleware/EnsureCommuneManager.php:23 | Autorisation dispersée. |
| Imports legacy | api/app/Modules/Admin/Routes/api.php:175, api/app/Modules/Admin/Models/ImportRun.php:14 | Import rattaché à Admin au lieu d'un adapter dédié. |
| Controllers avec logique métier | api/app/Modules/Actor/Controllers/ActeurModulesController.php:225 | Controller non limité à l'adaptation HTTP. |
| Services Admin contenant règles métier | api/app/Modules/Admin/Services/AdminPublicationService.php:252 | Backoffice devient owner de règles métier. |
10. Plan de migration en Pull Requests
| PR | Objectif | Fichiers concernés | Dépendances | Critères d'acceptation | Risques | Priorité |
|---|---|---|---|---|---|---|
| PR-001 | Introduire les contrats inter-contextes minimaux | Nouveaux contrats dans modules propriétaires | Aucune | Aucun changement fonctionnel ; services existants compilent | Sur-abstraction si contrats trop larges | P0 |
| PR-002 | Découpler Actor → Monetization | ActeurWriteService, service Monetization | PR-001 | Création acteur conserve abonnement free sans écriture directe Actor vers actor_subscriptions | Régression onboarding acteur | P0 |
| PR-003 | Découpler Actor → Mairie | ActeurModulesController, Mairie/Municipal service | PR-001 | CRUD alertes mairie ne passe plus par modèle Mairie depuis Actor | Régression Workspace mairie | P0 |
| PR-004 | Découper données municipales hors Territory | CommuneMairieDataRefreshService, MairieWriteService | PR-001 | Territory n'écrit plus acteurs; responsabilités commune_* clarifiées | Migration délicate des imports INSEE/SIRENE | P0 |
| PR-005 | Introduire événements Publication/Actor | PublicationWriteService, ActeurWriteService, Rewards/Actor listeners | PR-001 | Publication et Actor ne déclenchent plus Rewards/XP en synchrone direct | Ordre d'exécution des effets secondaires | P0 |
| PR-006 | Découpler Rewards → Monetization | RewardEngineService, Monetization boost contract | PR-001, PR-005 | Rewards ne crée plus boosts directement | Compatibilité récompenses existantes | P0 |
| PR-007 | Découpler Boost effects | BoostUsageService, Actor/Publication contracts | PR-001 | Monetization n'écrit plus acteurs.featured_until ni publications.featured_until directement | Régression mise en avant | P0 |
| PR-008 | Transformer Admin en adapter | Services Admin publication/acteur/subscription/claim/commune | PR-001 à PR-007 | Admin appelle use cases propriétaires ; plus d'écriture métier directe critique | Gros volume, découper par domaine si nécessaire | P1 |
| PR-009 | Découpler Import de Publication/Admin | ImportRunnerService, modèles Import, service Publication | PR-001 | Import ne dépend plus de modèles Admin et délègue à Publication | Régression imports existants | P1 |
| PR-010 | Consolider Authorization Platform Service | Policies, Middleware, ActorAccessService | PR-001 | Règles d'accès centralisées ; policies réduites à l'adaptation | Risque de changement de droits | P1 |
| PR-011 | Formaliser read models transverses | Analytics, Ranking, PlayLoop, AI quotas | PR-001 | Lectures directes critiques remplacées par read services/contrats | Faible si read-only | P2 |
| PR-012 | Nettoyer dette legacy/TODO | AIQuota, DTO legacy, imports legacy | PR précédentes | TODO et fallbacks documentés ou supprimés | Faible | P2 |
Score de conformité
| Axe | Score | Argument |
|---|---|---|
| Architecture | 68 % | Modules présents et lisibles, mais frontières non garanties par contrats. |
| Bounded Contexts | 62 % | Plusieurs contextes cible existent, mais Municipal Management est fragmenté et Admin/Import/Ranking restent ambigus. |
| Ownership | 48 % | Nombreuses écritures cross-context sur acteurs, publications, actor_subscriptions, boosts, commune_*. |
| API | 72 % | Routes par module cohérentes, mais certaines API exposent des responsabilités mélangées. |
| Events | 25 % | Aucun événement métier typé ni listener inter-contexte ; effets synchrones dominants. |
| Platform Services | 45 % | Settings et certains services existent, mais Authorization, Import, Search/Files/Notification ne sont pas structurés comme services platform. |
| Global | 55 % | Base modulaire saine, mais conformité DDD/ADR encore insuffisante pour considérer la migration terminée. |
Conclusion
La restructuration de DMV Core ne nécessite pas de réécriture globale. Le bon chemin est une migration incrémentale par ownership : contrats minimaux, suppression des écritures cross-context, puis événements métier.
Les P0 ne bloquent pas l'exploitation actuelle, mais bloquent la conformité à l'architecture cible. ENG-001.1 est donc terminé comme audit : la suite doit être exécutée via les PR proposées, en commençant par Actor, Publication, Monetization, Rewards, Territory/Mairie et Admin.