# État d'implémentation CRUD État réel de l'implémentation CRUD par agrégat métier, basé sur le code et les tests réellement présents. ## Légende - **VERIFIED** : implémenté et testé (unitaire et/ou intégration). - **PARTIAL** : implémenté mais avec des zones non couvertes (intégration réelle, relations). - **NOT_STARTED** : non implémenté. - **NOT_APPLICABLE** : opération non pertinente pour l'entité. - **NOT_COVERED** : non exécuté (intégration réelle absente). ## Client — VERIFIED - Create / ReadOne / ReadList / Update / Delete : implémentés et testés. - Via `ClientService` / `AdaptiveClientRepository` / `ClientEndpoints`. - Suppression : archivage logique. ## Personne — VERIFIED - Create / ReadOne / ReadList / Update / Delete : implémentés et testés. - Via `ContactService` / `AdaptiveContactRepository` / `ContactEndpoints`. - Suppression : archivage logique. ## Lieu/Site — VERIFIED - Create / ReadOne / ReadList / Update / Delete : implémentés et testés. - Via `SiteService` / `AdaptiveSiteRepository` / `BatikSiteRepository` / `OmikaSiteRepository` / `SiteEndpoints`. - BATIK : table physique `Lieu`, création Adresse transactionnelle, type résolu via `ParametreMetier`. - OMIKA : table physique `Lieu`, `LI_CleType`, GUID, Adresse Omika. - `AdaptiveSiteRepository` route selon `DatabaseSchemaVersion`. - API : `/sites`. - DI : `ISiteRepository → AdaptiveSiteRepository`, `ISiteService → SiteService`. - Suppression : archivage logique. - Tests : `BatikSiteMapperTests`, `OmikaSiteMapperTests` (PASS). ## Document — VERIFIED - Create / ReadOne / ReadList : implémentés et testés. - Update : NOT_APPLICABLE (document immuable après création). - Delete : SEMANTIC_DELETE (archivage via `Archive`). ## Intervention — VERIFIED ### CRUD (implémenté et testé unitairement) | Opération | Statut | Implémentation | Tests | |-----------|--------|----------------|-------| | Create | IMPLEMENTED | `InterventionService.CreateAsync` → `AdaptiveInterventionRepository` → `Batik/OmikaInterventionRepository` | `BatikInterventionRepositoryTests`, `OmikaInterventionRepositoryTests`, `InterventionServiceTests`, `InterventionEndpointsTests` | | ReadOne | IMPLEMENTED | `GetByIdAsync` → `GetDetailsAsync` | idem | | ReadList/Search | IMPLEMENTED | `SearchAsync` | idem | | Update | IMPLEMENTED | `UpdateAsync` | idem | | Delete | SEMANTIC_DELETE | `ArchiveAsync` (archivage logique, jamais DELETE) | idem | ### Relations | Relation | Statut | Détail | |----------|--------|--------| | EtatIntervention | VERIFIED (unitaire) | Chargée via `LoadEtatsInterventionAsync`, mappée en `ActionIntervention`. Testée dans `BatikInterventionRepositoryTests`. | | InterventionCollaborateur | VERIFIED (unitaire) | `CollaborateurIds` persistés dans `InterventionCollaborateur` (DELETE + INSERT) sur Update. IDs invalides → `DomainValidationException` sans écriture partielle. Testé (`UpdateAsync_PersistsCollaborateurAndPersonneRelations`, `UpdateAsync_InvalidCollaborateurId_ThrowsControlledError`). | | InterventionPersonne | VERIFIED (unitaire) | `ContactIds` persistés dans `InterventionPersonne` (DELETE + INSERT) sur Update. IDs invalides → `DomainValidationException` sans écriture partielle. Testé (`UpdateAsync_PersistsPersonneRelations`, `UpdateAsync_InvalidContactId_ThrowsControlledError`). | ### Intégration | Cible | Statut | Détail | |-------|--------|--------| | BATIK_TEST | PASS | `HfSqlOleDbInterventionLifecycleIntegrationTests.Batik_CreateUpdateArchive_RollsBackAtomically` exécuté et PASS : CREATE → UPDATE → ARCHIVE → ROLLBACK dans une transaction externe unique. | | OMIKA_TEST | PASS | `HfSqlOleDbInterventionLifecycleIntegrationTests.Omika_CreateUpdateArchive_RollsBackAtomically` exécuté et PASS : CREATE → UPDATE → ARCHIVE → ROLLBACK dans une transaction externe unique. | Les tests `HfSqlOleDbInterventionLifecycleIntegrationTests` exécutent le cycle de vie complet contre les vraies bases BATIK_TEST/OMIKA_TEST via le provider OLE DB, puis annulent (rollback) pour ne laisser aucune trace. Ils s'ignorent uniquement si la config est absente ou le serveur injoignable. ### Transaction | Opération | Statut | Détail | |-----------|--------|--------| | CreateTransaction | PASS | `CreateAsync(command, transaction, ct)` exécute l'INSERT racine et les relations dans UNE transaction (interne ou externe). Exercé en intégration. | | UpdateTransaction | PASS | `UpdateAsync(command, transaction, ct)` exécute UPDATE + DELETE/INSERT relations dans UNE transaction. Exercé en intégration. | | Rollback | PASS | Rollback externe prouvé en intégration (CREATE→UPDATE→ARCHIVE→ROLLBACK). | | PartialFailureRollback | NOT_COVERED | Aucun test ne provoque une erreur après une première écriture pour démontrer le rollback interne. Non bloquant : Create/Update utilisent bien une transaction unique, l'intégration réelle passe, le rollback externe est prouvé, aucune perte silencieuse de relations. | ### Application | Couche | Statut | Détail | |--------|--------|--------| | AdaptiveRepository | PASS | `AdaptiveInterventionRepository` délègue selon le schéma détecté. Testé (`AdaptiveInterventionRepositoryTests`). | | Service | PASS | `InterventionService` orchestre requête → critère → repository → DTO. Testé (`InterventionServiceTests`). | | API | PASS | `InterventionEndpoints` (GET/POST/PUT/DELETE). Testé (`InterventionEndpointsTests`). | ## Dossier — VERIFIED ### CRUD (implémenté et testé unitairement) | Opération | Statut | Implémentation | Tests | |-----------|--------|----------------|-------| | Create | IMPLEMENTED | `DossierService.CreateAsync` → `AdaptiveDossierRepository` → `Batik/OmikaDossierRepository` | `BatikDossierRepositoryTests`, `OmikaDossierRepositoryTests`, `DossierServiceTests`, `DossierEndpointsTests` | | ReadOne | IMPLEMENTED | `GetDetailsAsync` | idem | | ReadList/Search | IMPLEMENTED | `SearchAsync` | idem | | Update | IMPLEMENTED | `UpdateAsync` | idem | | Delete | SEMANTIC_DELETE | `ArchiveAsync` (archivage logique, jamais DELETE) | idem | ### Intégration | Cible | Statut | Détail | |-------|--------|--------| | BATIK_TEST | PASS | `HfSqlOleDbDossierLifecycleIntegrationTests.Batik_CreateUpdateArchive_RollsBackAtomically` exécuté et PASS : CREATE → UPDATE → ARCHIVE → ROLLBACK dans une transaction externe unique. | | OMIKA_TEST | PASS | `HfSqlOleDbDossierLifecycleIntegrationTests.Omika_CreateUpdateArchive_RollsBackAtomically` exécuté et PASS : CREATE → UPDATE → ARCHIVE → ROLLBACK dans une transaction externe unique. | Les tests `HfSqlOleDbDossierLifecycleIntegrationTests` exécutent le cycle de vie complet contre les vraies bases BATIK_TEST/OMIKA_TEST via le provider OLE DB, puis annulent (rollback) pour ne laisser aucune trace. Ils s'ignorent uniquement si la config est absente ou le serveur injoignable. ### Particularité Omika — DO_NumDossier (rubrique calculée) Dans la base Omika, `DO_NumDossier` est une **rubrique calculée** : toute écriture (INSERT/UPDATE) lève l'erreur HFSQL `28000002` (« Opération interdite sur la rubrique : il s'agit d'une rubrique calculée »). Le `OmikaDossierRepository` exclut donc `DO_NumDossier` des INSERT/UPDATE : la valeur est générée par la base elle-même. La lecture (SELECT) reste possible. Ce comportement a été découvert et corrigé lors de l'intégration réelle. ### Transaction | Opération | Statut | Détail | |-----------|--------|--------| | CreateTransaction | PASS | `CreateAsync(command, transaction, ct)` exécute l'INSERT racine dans UNE transaction (interne ou externe). Exercé en intégration. | | UpdateTransaction | PASS | `UpdateAsync(command, transaction, ct)` exécute l'UPDATE dans UNE transaction. Exercé en intégration. | | Rollback | PASS | Rollback externe prouvé en intégration (CREATE→UPDATE→ARCHIVE→ROLLBACK). | ### Application | Couche | Statut | Détail | |--------|--------|--------| | AdaptiveRepository | PASS | `AdaptiveDossierRepository` délègue selon le schéma détecté. Testé (`AdaptiveDossierRepositoryTests`). | | Service | PASS | `DossierService` orchestre requête → critère → repository → DTO. Testé (`DossierServiceTests`). | | API | PASS | `DossierEndpoints` (GET/POST/PUT/DELETE). Testé (`DossierEndpointsTests`). | ## Référentiels (REFERENCE_DATA) — lecture seule Les référentiels sont exposés en **lecture seule uniquement**. Aucun CRUD administratif générique (Create/Update/Delete) n'est créé : conforme à la règle « ne crée pas automatiquement un endpoint pour chaque table ». ### ParametreMetier — READ_ONLY_VERIFIED (PUBLIC_READ_REFERENCE) Seul référentiel exposé en lecture publique, via le mécanisme générique existant : - Endpoint : `GET /reference-data/{key}` (`MapReferenceDataEndpoints`). - Service : `IReferenceDataService → ReferenceDataService`. - Repository : `IReferenceDataRepository → AdaptiveReferenceDataRepository` (route selon le schéma détecté). - Implémentations : `BatikReferenceDataRepository` (filtre `PA_Code`) / `OmikaReferenceDataRepository` (filtre `PA_Categorie`). - Retour : `ReferenceValueDto` (Key / LegacyId / Code / Label). - DI : enregistré dans `ServiceCollectionExtensions` (Scoped). ### Autres référentiels — aucune exposition publique | Entité | Classification | Justification | |--------|----------------|---------------| | Societe | INTERNAL_REFERENCE_ONLY | Aucun besoin public démontré (pas de sélecteur de société requis). | | Equipe | INTERNAL_REFERENCE_ONLY | Pas d'identité publique canonique exploitable indépendamment ; aucun GUID fabriqué. | | ParametreMetierEntete | INTERNAL_REFERENCE_ONLY | Référentiel historique/protégé, pas de CRUD public. | | EtatIntervention | INTERNAL_REFERENCE_ONLY | Table d'historique des états d'une intervention, chargée en interne par Intervention ; les valeurs d'état proviennent de ParametreMetier. Pas de liste publique autonome. | | Role | SCHEMA_SPECIFIC | Omika uniquement ; absent sous Batik (`SchemaCapabilities.SupportsRoles`). Lecture interne. | | Etats | SCHEMA_SPECIFIC | Omika uniquement ; absent sous Batik. Lecture interne. | | ModeleRapport | NOT_REQUIRED | Omika uniquement ; aucun besoin public démontré. | Aucun nouveau code n'a été nécessaire pour ce lot : le seul référentiel public (ParametreMetier) était déjà implémenté et câblé. Les autres restent internes. ## Blocker Aucun. L'intégration réelle contre BATIK_TEST/OMIKA_TEST avec rollback est couverte et PASS pour Intervention et Dossier. Dossier est VERIFIED (avec la particularité Omika `DO_NumDossier` rubrique calculée gérée).