17 KiB
Analyse DDD Stratégique — Plateforme ESS
Analyse du code source URIAE (bundles Symfony sous src/Uriae/) selon les patterns stratégiques du Domain-Driven Design, dans le contexte de l’Économie Sociale et Solidaire (ESS) et des travailleurs en insertion / SIAE.
1. Langage Partagé
Constat
- Le code mélange anglais (
Employee,User,HiringStatus,Town) et français (Contrat,ParcoursInsertion,Structure,Accompagnement,SituationSortie), avec des artefacts hybrides (TypeEmployeedont le docblock cite encoreTypeSalarie). - Des termes alignés insertion / SIAE apparaissent clairement :
ParcoursInsertion,SiaeType,TypeContratAsp,FicheContratAsp,CodeRome,SiteTravail,AnnexeFinanciere,Financement, catégories de sortie (TypeSituationSortieavec notions type durable/transition côté référentiel). - Le cœur personne–emploi est nommé Employee alors que les commentaires et l’UI parlent d’employé / salarié ;
TypeEmployeedistingue Candidat, En insertion, Permanent — vocabulaire partiellement adapté aux parcours IAE mais pas à toute la diversité ESS. - Structure + FormeJuridique + SiaeType reflètent une structure porteuse (multi-sites, annexes, typologie SIAE) plutôt qu’une modélisation fine « association / SCIC / mutuelle » au niveau métier juridique.
- Suivi côté métier insertion est riche (
Action,Accompagnement,Evaluation,FormationInterne,Potentiel,Problematique,Habilitation) ; le bundle Asp réutilise le mot Suivi pour des échanges de fichiers ASP — homonymie avec le contexte « suivi salarié ».
Problèmes détectés
- Écart vocabulaire ESS élargi : peu de traces explicites dans le code des statuts bénévole, coopérateur, adhérent-salarié, ESAT, volontariat, ni des agréments type ESUS/CAE comme concepts de domaine nommés ; l’implémentation semble centrée SIAE / contrat / ASP plutôt que sur tout le spectre ESS décrit dans un cadrage large.
- Employee comme terme unique aplati salariés en insertion, permanents et candidats, sans langage ubiquitaire distinct pour « personne accompagnée » vs « salarié classique » si c’est une distinction métier pour les utilisateurs.
- Union en code = fédération / instance nationale de la plateforme, pas « syndicat » ni « union type ESS » au sens juridique — risque de faux amis avec les acteurs métier.
- SituationSortie vit dans le namespace Union alors qu’elle modélise un segment de parcours de sortie lié au salarié — le langage des packages ne suit pas le langage du parcours insertion.
- Duplication sémantique Suivi (Asp vs Suivi) et TypeEmployee / salarié dans les libellés affichés (
getName()qui préfixe « Salarié(e) ») masque les cas limites ESS.
Recommandations
- Tenir un atelier glossaire avec le métier en partant des écrans et des entités existantes, puis tracer : terme UI ↔ nom de classe ↔ table SQL.
- Introduire des alias métier dans la doc produit et, à terme, des value objects / read models nommés comme le métier (ex. TravailleurAccompagne, RéférentielSortieInsertion) sans tout renommer d’un coup si le coût est trop élevé.
- Renommer ou préfixer dans le langage technique ce qui prête à confusion (
AspSuivivsSuiviSalarié,FederationouInstancePlateformevsUnionsi pertinent).
Glossaire ESS proposé
| Terme métier ESS | Terme trouvé dans le code | Statut |
|---|---|---|
| Travailleur / personne accompagnée (générique) | Employee, commentaires « employé » |
Présent mais générique RH |
| Salarié en insertion (IAE / parcours) | TypeEmployee::EN_INSERTION, ParcoursInsertion |
Présent, cœur du modèle |
| Salarié permanent | TypeEmployee::PERMANANT, PERMANANT_SORTI |
Présent |
| Candidat / postulant | TypeEmployee::CANDIDAT, état Postulant |
Présent |
| Structure ESS (association, SCOP, etc.) | Structure, FormeJuridique |
Structure oui ; typologie juridique ESS limitée aux données référentielles |
| SIAE / dispositif insertion | SiaeType, mesures ASP, fixtures EI/ACI/AI/ETTI |
Fortement présent |
| Contrat de travail / conventionnement | Contrat, Conventionnement (réf. union) |
Présent (contrat + catalogue partenaire/conventionnement) |
| Financement / annexe | Financement, AnnexeFinanciere, ChiffreCle |
Présent côté structure |
| Sortie d’insertion / typologie | SituationSortie, TypeSituationSortie |
Présent ; emplacement bundle incohérent |
| Accompagnement socio-professionnel | Accompagnement, Action, taxonomies TypeAction |
Présent |
| Évaluation / compétences | Evaluation, Savoir, grilles |
Présent |
| Conditions sociales (RSA, AAH, RQTH…) | HiringStatus |
Présent sous nom anglais |
| Conformité ASP / déclarations | FicheContratAsp, fichiers mensuels/annuels |
Présent (intégration forte) |
| Bénévole / coopérateur / mutuelle salarié | (peu ou pas de modèle dédié repéré) | Absent ou non modélisé explicitement |
| Agrément ESUS, dispositif CAE, etc. | (non saillant dans l’échantillon de code analysé) | À valider côté données ; risque sous-langage |
| Convention collective métier (Éclat, Nexem…) | (non saillant) | Hors modèle explicite dans l’exploration |
2. Contextes Bornés
Constat
Les bundles Employee, Suivi, Structure, Union, Asp, plus Bilan / Home / Import / Export / User / Helper, matérialisent un découpage technique Symfony qui recoupe en partie des frontières métier.
Problèmes détectés
- Union concentre à la fois des référentiels fédérateurs et des données de parcours (
SituationSortie) et des écrans d’admin sur des entités Suivi et Employee — fusion artificielle de plusieurs problématiques. - Employee embarque des collections Suivi (relations Doctrine vers
Accompagnement,Evaluation, etc.) — couplage bidirectionnel qui empêche de voir Suivi comme contexte autonome. - ASP lit/écrit le contexte contrat/personne au-delà d’une simple intégration — frontière Conformité déclarative vs Vie du contrat peu lisible dans le code.
- Bilan / Home agrègent plusieurs contextes sans couche de lecture dédiée explicite (risque de modèle transactionnel utilisé comme vue transverse).
Recommandations
- Valider par le métier un découpage par capacités : Parcours & contrat, Suivi & évaluation, Structure & gouvernance, Référentiels fédération, Télédéclaration / ASP, Reporting.
- Déplacer progressivement les CRUD vers le bundle propriétaire du concept (cf. phases F/G du playbook dans
deep-dive-context-map.md). - Introduire des ports (interfaces applicatives) aux frontières bundle avant tout big-bang de renommage.
Découpage proposé
- Contexte « Travailleur & emploi » — lifecycle, contrats, parcours insertion, états, documents administratifs.
- Contexte « Suivi & développement des compétences » — actions, formations, évaluations, problématiques, habilitations, potentiel.
- Contexte « Structure & exploitation » — profil structure, sites, secteurs, alertes, agenda, compétences structure, chiffres / annexes.
- Contexte « Référentiels fédération » — union/plateforme, partenaires, catalogues publiés, types de sortie comme langage publié.
- Contexte « Déclarations & interopérabilité ASP » — fiches, statuts, fichiers, erreurs, éligibilité.
- Contexte « Lecture / pilotage » — bilan, tableaux de bord, exports.
- Contexte « Accès & sécurité » — utilisateurs, rôles (plutôt générique).
3. Noyau Partagé
Constat
Des concepts transverses existent déjà : identifiants entiers Doctrine, Structure comme tenant, Town / territoire, Code ROME, typologies SIAE, TypeSituationSortie avec codes ASP, liens Contrat ↔ FicheContratAsp.
Problèmes détectés
- Le graphe Doctrine partagé (Employee ↔ Suivi ↔ Structure ↔ Union) fait office de shared kernel implicite trop large : toute évolution entraîne des effets en cascade.
- Des règles spécifiques ASP ou à une convention risquent d’être mélangées à des invariants génériques (période de contrat, identité) si elles restent dans les mêmes entités/services.
- Duplications possibles entre formatage, validations transverses et référentiels édités depuis plusieurs bundles (chemins Union vs Structure signalés dans la doc interne).
Recommandations
- Définir un Shared Kernel minimal et versionné : surtout identifiants stables, codes référentiels publiés, et valeurs communes (ex. période calendaire, identité légère en lecture).
- Isoler les politiques (éligibilité ASP, règles d’évaluation) dans des services de contexte, pas dans des entités « fourre-tout ».
- Documenter ce qui est contrat publié (ex. codes de sortie consommés par ASP et reporting) vs détail interne.
Candidats au Shared Kernel
| Candidat | Justification métier ESS |
|---|---|
Identifiants stables (EmployeeId, StructureId, ContractId…) |
Traçabilité multi-contextes, audits, financeurs, déclarations |
| Référentiel de typologie de sortie (codes + libellés publiés) | Alignement ASP, statistiques et parcours |
Référentiel territorial (Town, département, région) |
Adresses structures, personnes, partenaires |
| Typologie SIAE / mesure (lecture) | Conditionne écrans, règles ASP et indicateurs |
| Code ROME (référence ou service de validation partagé) | Contrat et déclarations cohérents |
| Période / intervalle de dates métier (value object) | Contrats, sorties, durées d’aide, durées d’accompagnement |
À exclure du noyau partagé (exemples) : règles d’éligibilité ASP détaillées, workflow de validation d’évaluation, règles de grille spécifiques à une fédération, logique fusion de structures.
4. Carte de Contextes
Constat
Les dépendances réelles passent surtout par Doctrine, contrôleurs et services Symfony ; la direction « métier » (qui impose le langage à l’autre) n’est pas toujours explicite dans le code, mais on peut la déduire.
Problèmes détectés
- Couplage fort Employee ↔ Suivi masque une relation client–fournisseur ou ACL souhaitable.
- ASP en aval de Employee/Structure mais avec mutations possibles côté intégration — relation conformiste / ACL peu respectée en pratique.
- Union en amont pour certains référentiels mais en aval opérationnel pour d’autres données — rôle flou.
Recommandations
- Rendre explicites les relations de contexte (Open Host Service, Published Language, ACL, Anti-Corruption Layer) dans la doc et dans les points d’extension du code.
- Prioriser la dépendance unidirectionnelle : Référentiels et Structure → Contrat/Parcours ; Suivi → identité Travailleur en lecture ; ASP → snapshots ou événements.
Context Map
+------------------+
| Référentiels |
| Fédération |
| (Union BC) |
+--------+---------+
| Published Language (codes sortie, catalogues)
+--------------+--------------+
| |
v v
+----------------+ +------------------+
| Structure & | | Suivi & |
| Exploitation | | Compétences |
| (tenant) | | (actions, |
+--------+-------+ | évaluations) |
| +--------+---------+
| scopes / refs |
v |
+----------------+ |
| Travailleur & |<--------------------+
| Emploi | (Employee upstream
| (contrat, | for identity; Suivi
| parcours) | should be downstream)
+--------+-------+
|
| contract snapshots / eligibility inputs
v
+----------------+
| ASP & |
| Déclarations |
+--------+-------+
|
v
+----------------+
| Lecture / |
| Bilan / Export |
+----------------+
Légende relationnelle (intention cible):
Fédération --[Published Language]--> Travailleur / ASP / Suivi
Structure --[Supplier]--> Travailleur, Suivi, ASP
Travailleur --[Supplier]--> Suivi (ACL côté Suivi recommandé)
ASP --[Downstream Conformist + ACL]--> Travailleur (pas de mutation directe idéale)
Bilan --[Separate Read Model]--> tous
5. 🎯 Distillation du Domaine
Constat
La valeur différenciante probable de la plateforme pour l’ESS cible (d’après le code et les deep dives) réside dans le couplage métier insertion + SIAE + suivi + structure, plutôt que dans l’auth ou les imports génériques.
Problèmes détectés
- Une part importante de la complexité semble portée par l’intégration ASP et les invariants contrat/sortie — c’est cohérent avec le cœur métier, mais le mélange avec la persistance et les autres bundles peut disperser cette richesse.
- Les référentiels et l’admin trans-bundle peuvent absorber de l’effort maintenance sans être la différenciation produit.
- User / infrastructure web : nécessaires mais ne doivent pas dominer l’architecture si le produit vend du parcours ESS.
Recommandations
- Investir explicitement (tests, modules, documentation métier) sur : ParcoursInsertion, Contrat + sortie, règles ASP, HiringStatus, Suivi d’insertion — là où se jouent conformité et qualité d’accompagnement.
- Réduire le coût sur le générique (auth standard, utilitaires) via bibliothèques ou modules minces.
- Mesurer où se concentrent les bugs et évolutions réglementaires ; aligner la structure des équipes et des bounded contexts sur ces zones.
Classification des domaines
| Contexte | Catégorie | Justification |
|---|---|---|
| Travailleur, contrat, parcours insertion, sortie | Core Domain | Cœur de la promesse « accompagner le parcours » + états métier |
| Règles & cycles ASP (déclarations, éligibilité) | Core Domain (ou Core fortement lié) | Spécificité réglementaire et opérationnelle IAE/SIAE |
| Suivi (actions, évaluations, formations, problématiques) | Supporting Domain | Très important pour l’usage terrain mais peut être structuré comme soutien au parcours |
| Structure (profil, sites, alertes, chiffres, annexes) | Supporting Domain | Indispensable, mais beaucoup de structures pourraient être partagées avec d’autres outils administratifs |
| Référentiels fédération | Supporting Domain (avec Published Language) | Stabilité et gouvernance ; valeur par la cohérence plus que par l’algorithme |
| Bilan, Home, exports agrégés | Supporting Domain (voire Generic si simple) | Lecture / reporting ; souvent candidat read model |
| Import / Export techniques | Generic Subdomain | Pipelines ETL classiques |
| User, auth, helpers transverses | Generic Domain | Standard industrie |
🏁 Synthèse Globale
Score de maturité DDD
| Dimension | Score (1-5) | Commentaire |
|---|---|---|
| Ubiquitous Language | 2 | Richesse métier insertion/SIAE visible, mais mélange FR/EN, homonymies, et écarts avec vocabulaire ESS élargi |
| Bounded Contexts | 2 | Bundles = indices utiles ; frontières réelles brouillées (Union, graphe Employee–Suivi) |
| Context Map explicite | 3 | Bonne base dans deep-dive-context-map.md ; pas encore reflétée par des séams techniques partout |
| Shared Kernel discipline | 2 | Noyau implicite trop large via ORM ; candidats légitimes identifiables |
| Distillation (priorisation Core) | 2 | Le Core est dans le code mais noyé dans la technique ; risque de sous-investissement sur read models et ACL |
⚡ 3 actions prioritaires
- Trancher et documenter le glossaire ESS (travailleur, insertion, structure, sortie, déclaration) et corriger les faux amis (
Union, double sens deSuivi).- Clarifier la propriété de
SituationSortieet des écrans référentiels (déplacer vers Employee/Suivi ou APIs dédiées) pour aligner bundles et contextes métier.- Isoler ASP et Suivi derrière des ports + anti-corruption (IDs stables, snapshots, événements), pour réduire le noyau partagé implicite et sécuriser les évolutions réglementaires.