Premiere commit - Omika
This commit is contained in:
@@ -0,0 +1,327 @@
|
||||
# Niveau 3 — Modèle métier canonique et contrats API
|
||||
|
||||
## Rôle des dossiers de `Omika.Core`
|
||||
|
||||
### `Domain/`
|
||||
|
||||
Le domaine contient les **entités métier canoniques**, indépendantes du stockage.
|
||||
|
||||
Elles correspondent aux concepts fonctionnels de l'application :
|
||||
|
||||
- Client, Adresse, Contact, Site ;
|
||||
- Societe, Collaborateur, Equipe, Utilisateur ;
|
||||
- Dossier, Intervention, ActionIntervention, CompteRendu, Checklist ;
|
||||
- RendezVous et ses éléments associés ;
|
||||
- Document et modèles de courrier/rapport ;
|
||||
- Role, Permission, DroitAcces ;
|
||||
- ParametreMetier, ParametreApplication, PreferenceUtilisateur.
|
||||
|
||||
Elles ne portent :
|
||||
|
||||
- aucun attribut HFSQL ;
|
||||
- aucun préfixe de rubrique physique (`CL_`, `IN_`, `PL_`, `RDV_`…) ;
|
||||
- aucun champ zombie.
|
||||
|
||||
Les **objets de valeur** (`ValueObjects/`) représentent des valeurs sans identité :
|
||||
|
||||
- `ReferenceValue` (valeur de référentiel configurable) ;
|
||||
- `DateTimeRange` (plage horaire validée) ;
|
||||
- `PostalAddress`, `ContactDetails` ;
|
||||
- `ExternalReference` (référence vers Batigest / base externe).
|
||||
|
||||
Les **exceptions** (`Exceptions/`) portent les erreurs de validation du domaine.
|
||||
|
||||
### `Contracts/`
|
||||
|
||||
Les contrats sont utilisés entre `Omika.Api` et `Omika.App`.
|
||||
|
||||
Ce sont des DTO purs :
|
||||
|
||||
- résumés de liste ;
|
||||
- détails ;
|
||||
- requêtes de création / modification / recherche ;
|
||||
- DTO communs (pagination, enveloppe d'erreur, référence, adresse, coordonnées).
|
||||
|
||||
**Distinction `AddressDto` / `AdresseDto` :**
|
||||
|
||||
- `AddressDto` (`Contracts/Common`) : adresse postale simple, sans identité
|
||||
(libellé, lignes, code postal, ville, pays). Réutilisée partout où une
|
||||
adresse postale brute est nécessaire.
|
||||
- `AdresseDto` (`Contracts/Clients`) : adresse d'une entité du domaine Clients,
|
||||
avec identifiant, type, indicateurs (« principale », « archivée ») et une
|
||||
adresse postale optionnelle (`AdressePostale`). Il ne s'agit pas d'un doublon
|
||||
de `AddressDto` : l'un est une valeur, l'autre un conteneur d'entité.
|
||||
|
||||
Ils ne contiennent :
|
||||
|
||||
- aucun attribut HFSQL ;
|
||||
- aucune propriété à préfixe physique ;
|
||||
- aucune dépendance vers `Omika.Data` ;
|
||||
- aucun champ zombie ;
|
||||
- aucun mot de passe ni objet de connexion ;
|
||||
- aucun graphe cyclique.
|
||||
|
||||
### `Compatibility/`
|
||||
|
||||
Les types de compatibilité conservent la **provenance** des données sans exposer
|
||||
la structure physique :
|
||||
|
||||
- `DatabaseSchemaVersion` (Unknown / Batik / Omika) ;
|
||||
- `DatabaseSource` (version + nom logique de base) ;
|
||||
- `LegacyEntityReference` (référence vers l'enregistrement d'origine) ;
|
||||
- `SchemaCapabilities` (capacités déclarées d'un schéma) ;
|
||||
- `CanonicalMappingResult<T>` (résultat d'un mapping physique → canonique).
|
||||
|
||||
### `Interfaces/`, `Abstractions/`, `Constants/`, `Runtime/`, `Mapping/`
|
||||
|
||||
- `Interfaces/` : services métier (voir ci-dessous).
|
||||
- `Abstractions/` : abstractions techniques existantes, non touchées.
|
||||
- `Constants/` : constantes existantes.
|
||||
- `Runtime/` : contexte d'exécution existant, non touché.
|
||||
- `Mapping/` : mappers purs entité métier → DTO.
|
||||
|
||||
## Différence entre une entité métier et un modèle physique
|
||||
|
||||
| Modèle physique (Omika.Data) | Entité métier (Omika.Core.Domain) |
|
||||
|---|---|
|
||||
| Correspond aux tables HFSQL (`Document.fic`, `Planning_RDV`…) | Correspond aux concepts fonctionnels (Document, RendezVous…) |
|
||||
| Porte des rubriques préfixées (`DC_Categorie`, `PL_PKID`…) | Porte des propriétés métier nommées sans préfixe |
|
||||
| Marque les rubriques zombie | Ne contient jamais de champ zombie |
|
||||
| Connaît les clés internes et la version physique | Connaît uniquement les identifiants canoniques et la provenance |
|
||||
|
||||
La chaîne attendue :
|
||||
|
||||
```
|
||||
Modèle physique Batik (Isis_BO) Modèle physique Omika
|
||||
| |
|
||||
+----------> Modèle métier canonique <-+
|
||||
|
|
||||
v
|
||||
Contrat API
|
||||
|
|
||||
v
|
||||
Application Avalonia
|
||||
```
|
||||
|
||||
Le mapping **physique → métier** reste dans `Omika.Data`.
|
||||
Le mapping **métier → DTO** est dans `Omika.Core/Mapping`.
|
||||
|
||||
## Différence entre une entité métier et un DTO
|
||||
|
||||
| Entité métier | DTO (contrat) |
|
||||
|---|---|
|
||||
| Évolue dans le temps (classe) | Immutable par convention (`record` avec propriétés `init`) |
|
||||
| Expose des collections contrôlées (`Add*`) | Expose des listes `IReadOnlyList<T>` en lecture seule |
|
||||
| Peut contenir des objets de valeur du domaine | Ne contient que des DTO ou types primitifs |
|
||||
| Vit dans `Domain/` | Vit dans `Contracts/` |
|
||||
| N'est jamais sérialisé tel quel | Est la frontière de l'API |
|
||||
|
||||
## Stratégie des identifiants
|
||||
|
||||
Les identifiants publics des contrats sont des **chaînes** afin de permettre
|
||||
temporairement :
|
||||
|
||||
- le GUID Omika ;
|
||||
- l'identifiant historique Batik (Isis_BO) ;
|
||||
- une clé métier.
|
||||
|
||||
Le domaine utilise `Guid Id` (identifiant canonique) plus
|
||||
`LegacyEntityReference? SourceReference` pour conserver la référence d'origine
|
||||
sans exposer la clé physique.
|
||||
|
||||
`LegacyEntityReference.PublicIdentifier` fournit une représentation publique
|
||||
stable (GUID → clé métier → identifiant numérique → GUID physique → ImportId).
|
||||
|
||||
Un helper de représentation publique des identifiants peut être ajouté plus tard
|
||||
si le besoin se fait sentir côté API/mobile.
|
||||
|
||||
## Stratégie des paramètres métier
|
||||
|
||||
Les paramètres métier (type de client, statut, type d'activité, priorité…) sont
|
||||
représentés par `ReferenceValue` :
|
||||
|
||||
- `Key` : clé métier stable (nouveau schéma Omika) ;
|
||||
- `LegacyId` : identifiant historique (ancien schéma Batik) ;
|
||||
- `Code` : code court éventuel ;
|
||||
- `Label` : libellé d'affichage.
|
||||
|
||||
Ils ne sont **pas** transformés automatiquement en `enum` : ils restent
|
||||
configurables. Le passage en enum n'est envisagé que si un paramètre devient
|
||||
vraiment stable et fermé.
|
||||
|
||||
## Stratégie des champs zombie
|
||||
|
||||
Les rubriques physiques obsolètes (anciens identifiants de civilité, de statut,
|
||||
clés internes…) sont marquées **zombie** dans les modèles physiques de
|
||||
`Omika.Data`.
|
||||
|
||||
Dans `Omika.Core` :
|
||||
|
||||
- elles n'apparaissent jamais comme propriétés publiques ;
|
||||
- le mapper de `Omika.Data` est responsable de convertir les valeurs en
|
||||
propriétés métier (`ReferenceValue`, libellés, etc.) ;
|
||||
- les tests d'architecture interdisent leur apparition dans les contrats.
|
||||
|
||||
## Stratégie de compatibilité Batik (Isis_BO) / Omika
|
||||
|
||||
- Le domaine est **unique** pour les deux bases.
|
||||
- La provenance est conservée via `LegacyEntityReference` / `DatabaseSource`.
|
||||
- `SchemaCapabilities` permet de savoir, sans connaître la structure physique,
|
||||
si une fonctionnalité est disponible dans la version source
|
||||
(clés métier, GUID, rôles, nouveau modèle de rendez-vous…).
|
||||
- `CanonicalMappingResult<T>` permet à un mapper physique → canonique de
|
||||
retourner la valeur plus les warnings, champs ignorés et erreurs non bloquantes.
|
||||
|
||||
## Cas particulier des rendez-vous
|
||||
|
||||
Un **agrégat métier unique** `RendezVous` reçoit les données des deux versions :
|
||||
|
||||
- ancien modèle : `Planning_RDV`, `Planning_RDV_Personne` ;
|
||||
- nouveau modèle : `RDV_Planning`, `RDV_Collaborateur`, `RDV_Contact`.
|
||||
|
||||
L'entité porte :
|
||||
|
||||
- une `DateTimeRange Periode` ;
|
||||
- des `AffectationCollaborateur` (responsable, période particulière, statut,
|
||||
temps validé) ;
|
||||
- des `ParticipantRendezVous` (contact, coordonnées, type, présence confirmée) ;
|
||||
- une `AnnulationRendezVous` éventuelle ;
|
||||
- des liens optionnels vers Client / Site / Dossier / Intervention.
|
||||
|
||||
Toute information absente dans une version est **nullable**.
|
||||
|
||||
Le contrat `RendezVousDetailsDto` est **identique** pour les deux versions et ne
|
||||
contient aucune notion de `Planning_RDV`, `RDV_Planning`, `PL_PKID`,
|
||||
`RDP_GUID` ou autre nom physique.
|
||||
|
||||
## Liste des fichiers créés
|
||||
|
||||
### `Omika.Core/Compatibility`
|
||||
|
||||
- `DatabaseSchemaVersion.cs`
|
||||
- `DatabaseSource.cs`
|
||||
- `LegacyEntityReference.cs`
|
||||
- `SchemaCapabilities.cs`
|
||||
- `CanonicalMappingResult.cs`
|
||||
|
||||
### `Omika.Core/Domain/Common`
|
||||
|
||||
- `EntityBase.cs`
|
||||
|
||||
### `Omika.Core/Domain/ValueObjects`
|
||||
|
||||
- `ReferenceValue.cs`
|
||||
- `DateTimeRange.cs`
|
||||
- `PostalAddress.cs`
|
||||
- `ContactDetails.cs`
|
||||
- `ExternalReference.cs`
|
||||
|
||||
### `Omika.Core/Domain/Exceptions`
|
||||
|
||||
- `DomainException.cs`
|
||||
- `DomainValidationException.cs`
|
||||
|
||||
### `Omika.Core/Domain/Entities`
|
||||
|
||||
- `Clients/Client.cs`, `Adresse.cs`, `Contact.cs`, `Site.cs`
|
||||
- `Organisation/Societe.cs`, `Collaborateur.cs`, `Equipe.cs`, `Utilisateur.cs`
|
||||
- `Interventions/Dossier.cs`, `Intervention.cs`, `ActionIntervention.cs`,
|
||||
`CompteRendu.cs`, `EtatIntervention.cs`, `Checklist.cs`, `ChecklistItem.cs`
|
||||
- `Planning/RendezVous.cs`, `AffectationCollaborateur.cs`,
|
||||
`ParticipantRendezVous.cs`, `AnnulationRendezVous.cs`, `SuiviTemps.cs`
|
||||
- `Documents/Document.cs`, `NoteDocument.cs`, `MessageInterne.cs`,
|
||||
`MessageExterne.cs`, `ModeleMail.cs`, `ModeleRapport.cs`
|
||||
- `Security/Role.cs`, `Permission.cs`, `DroitAcces.cs`
|
||||
- `Configuration/ParametreMetier.cs`, `ParametreApplication.cs`,
|
||||
`PreferenceUtilisateur.cs`
|
||||
|
||||
### `Omika.Core/Contracts/Common`
|
||||
|
||||
- `ApiErrorDto.cs`, `ApiResult.cs`, `PagedRequest.cs`, `PagedResult.cs`
|
||||
- `ReferenceValueDto.cs`, `AddressDto.cs`, `ContactDetailsDto.cs`
|
||||
|
||||
### `Omika.Core/Contracts/Clients`
|
||||
|
||||
- `ClientSummaryDto.cs`, `ClientDetailsDto.cs`
|
||||
- `CreateClientRequest.cs`, `UpdateClientRequest.cs`, `SearchClientsRequest.cs`
|
||||
- `AdresseDto.cs`, `ContactDto.cs`, `SiteDto.cs`
|
||||
|
||||
### `Omika.Core/Contracts/Organisation`
|
||||
|
||||
- `CollaborateurSummaryDto.cs`, `CollaborateurDetailsDto.cs`
|
||||
- `EquipeDto.cs`, `SocieteDto.cs`, `UtilisateurDto.cs`
|
||||
|
||||
### `Omika.Core/Contracts/Interventions`
|
||||
|
||||
- `DossierSummaryDto.cs`, `DossierDetailsDto.cs`
|
||||
- `InterventionSummaryDto.cs`, `InterventionDetailsDto.cs`
|
||||
- `CreateInterventionRequest.cs`, `UpdateInterventionRequest.cs`,
|
||||
`SearchInterventionsRequest.cs`
|
||||
- `ActionInterventionDto.cs`, `CompteRenduDto.cs`, `EtatInterventionDto.cs`
|
||||
|
||||
### `Omika.Core/Contracts/Planning`
|
||||
|
||||
- `RendezVousSummaryDto.cs`, `RendezVousDetailsDto.cs`
|
||||
- `CreateRendezVousRequest.cs`, `UpdateRendezVousRequest.cs`,
|
||||
`SearchRendezVousRequest.cs`
|
||||
- `AffectationCollaborateurDto.cs`, `ParticipantRendezVousDto.cs`,
|
||||
`AnnulationRendezVousDto.cs`, `SuiviTempsDto.cs`, `CreateSuiviTempsRequest.cs`
|
||||
|
||||
### `Omika.Core/Contracts/Documents`
|
||||
|
||||
- `DocumentSummaryDto.cs`, `DocumentDetailsDto.cs`, `CreateDocumentRequest.cs`
|
||||
- `ModeleMailDto.cs`, `ModeleRapportDto.cs`
|
||||
|
||||
### `Omika.Core/Contracts/Security`
|
||||
|
||||
- `LoginRequest.cs`, `CurrentUserDto.cs`, `RoleDto.cs`, `PermissionDto.cs`
|
||||
|
||||
### `Omika.Core/Contracts/Configuration`
|
||||
|
||||
- `ParametreMetierDto.cs`, `ApplicationConfigurationDto.cs`,
|
||||
`PreferenceUtilisateurDto.cs`
|
||||
|
||||
### `Omika.Core/Interfaces`
|
||||
|
||||
- `IClientService.cs`, `IInterventionService.cs`, `IRendezVousService.cs`,
|
||||
`IDocumentService.cs`, `IReferenceDataService.cs`, `ICurrentUserService.cs`
|
||||
|
||||
### `Omika.Core/Mapping`
|
||||
|
||||
- `ClientContractMapper.cs`, `InterventionContractMapper.cs`,
|
||||
`RendezVousContractMapper.cs`, `DocumentContractMapper.cs`
|
||||
|
||||
### `Omika.Tests`
|
||||
|
||||
- Architecture : `CoreMustNotReferenceDataTests`,
|
||||
`CoreMustNotReferenceAvaloniaTests`, `CoreMustNotReferenceAspNetCoreTests`,
|
||||
`PublicContractsMustNotContainHfSqlNamesTests`,
|
||||
`PublicContractsMustNotContainZombieFieldsTests`
|
||||
- Contrats : `PagedResultTests`, `ClientContractTests`,
|
||||
`InterventionContractTests`, `RendezVousContractTests`
|
||||
- Domaine : `DateTimeRangeTests`, `ClientDomainTests`,
|
||||
`InterventionDomainTests`, `RendezVousDomainTests`,
|
||||
`RendezVousCrossSchemaTests`
|
||||
- Compatibilité : `LegacyEntityReferenceTests`, `SchemaCapabilitiesTests`
|
||||
|
||||
## Décisions encore à valider
|
||||
|
||||
1. **Identifiants publics** : chaînes temporaires (GUID / legacy / clé métier).
|
||||
Un helper dédié ou un type valeur « PublicId » reste possible.
|
||||
2. **États et statuts** : conservés en `ReferenceValue`. À confirmer si certains
|
||||
deviendront des enums stables.
|
||||
3. **`DateTime` vs `DateTimeOffset`** : pas de gestion multi-fuseaux documentée
|
||||
pour l'instant ; `DateTime` est utilisé partout. À revoir si le mobile doit
|
||||
synchroniser sur plusieurs fuseaux.
|
||||
4. **Collections dans les entités** : `List<T>` privées avec méthodes `Add*`.
|
||||
À confirmer si des collections doivent devenir remplaçables (remplacement
|
||||
complet lors d'une mise à jour).
|
||||
5. **Contrat de recherche** : `SearchClientsRequest` hérite de `PagedRequest`
|
||||
avec des propriétés additionnelles. Les filtres seront consolidés lors de
|
||||
l'implémentation des services.
|
||||
6. **Sécurité** : `LoginRequest` accepte un mot de passe temporaire, mais aucun
|
||||
service d'authentification n'est implémenté à ce niveau. Le stockage des
|
||||
identifiants (hash, salt) sera décidé au niveau supérieur.
|
||||
7. **Fichiers physiques des documents** : les contrats exposent des identifiants
|
||||
logiques et des métadonnées ; la gestion du téléversement/téléchargement sera
|
||||
définie avec l'API.
|
||||
Reference in New Issue
Block a user