# 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 (`TypeEmployee` dont le docblock cite encore `TypeSalarie`). - Des termes **alignés insertion / SIAE** apparaissent clairement : `ParcoursInsertion`, `SiaeType`, `TypeContratAsp`, `FicheContratAsp`, `CodeRome`, `SiteTravail`, `AnnexeFinanciere`, `Financement`, catégories de **sortie** (`TypeSituationSortie` avec 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é** ; `TypeEmployee` distingue **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 (`AspSuivi` vs `SuiviSalarié`, `Federation` ou `InstancePlateforme` vs `Union` si 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é 1. **Contexte « Travailleur & emploi »** — lifecycle, contrats, parcours insertion, états, documents administratifs. 2. **Contexte « Suivi & développement des compétences »** — actions, formations, évaluations, problématiques, habilitations, potentiel. 3. **Contexte « Structure & exploitation »** — profil structure, sites, secteurs, alertes, agenda, compétences structure, chiffres / annexes. 4. **Contexte « Référentiels fédération »** — union/plateforme, partenaires, catalogues publiés, **types de sortie** comme langage publié. 5. **Contexte « Déclarations & interopérabilité ASP »** — fiches, statuts, fichiers, erreurs, éligibilité. 6. **Contexte « Lecture / pilotage »** — bilan, tableaux de bord, exports. 7. **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 > 1. **Trancher et documenter** le glossaire **ESS** (travailleur, insertion, structure, sortie, déclaration) et **corriger** les **faux amis** (`Union`, double sens de `Suivi`). > 2. **Clarifier la propriété** de **`SituationSortie`** et des **écrans référentiels** (déplacer vers Employee/Suivi ou APIs dédiées) pour **aligner bundles et contextes métier**. > 3. **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**.