first commit

This commit is contained in:
2026-09-10 16:43:09 +02:00
commit 79cf35f690
144 changed files with 8822 additions and 0 deletions

34
docs/ARCHITECTURE.md Normal file
View File

@@ -0,0 +1,34 @@
# Architecture — ARGOS (GMAO)
> Nom de marque : **ARGOS**. "GMAO" reste utilisé comme terme générique (Gestion de Maintenance
> Assistée par Ordinateur) dans le code/les noms de dossiers existants — pas de renommage du repo.
## Projets
- **App.Core** (`net8.0`, zéro dépendance EF/WinUI/ASP.NET) : entités du domaine, interfaces de repository, services métier purs (licence, planification préventive, KPI), DTOs de synchronisation. Dépend uniquement de `BouncyCastle.Cryptography` (Ed25519, .NET n'a pas de support natif).
- **App.Infrastructure** : EF Core (SQLite), implémentations des repositories, WMI (hardware id), DPAPI (état d'essai), QuestPDF, stockage des pièces jointes.
- **App.UI** : WinUI 3, MVVM (CommunityToolkit.Mvvm), packaging MSIX.
- **App.SyncServer** : API HTTP locale (ASP.NET Core Minimal API) + découverte mDNS pour la future app Android.
- **LicenseGenerator** : console séparée, reste sur le poste de développement, jamais packagée dans le client.
- **tests/App.Core.Tests** : xUnit, couvre licence / calcul d'échéances / KPI (logique pure, sans I/O).
## Décisions structurantes
- **Rôles utilisateurs** : enum `UserRole` sur `User`, pas de table `Roles` séparée (3 rôles fixes en V1).
- **Pièces jointes** : table unique `Attachment` avec clé polymorphe (`EntityType` + `EntityId`), pas de FK SQLite dessus — intégrité gérée par `IAttachmentRepository`.
- **Paramètres globaux** : table clé-valeur `AppSetting`, typée côté `App.Core` via `ISettingsProvider`.
- **Licence & essai** : stockés **hors SQLite** (fichier `.lic` signé + état DPAPI séparé) pour qu'un reset de la base ne réinitialise jamais l'essai. `LicenseActivationCache` en base n'est qu'un cache d'affichage, jamais une source d'autorité.
- **Repositories** : interface générique `IRepository<TEntity, TKey>` (CRUD minimal) + interfaces spécifiques par entité pour les requêtes métier (recherche, filtres, dédoublonnage d'occurrence).
- **Unité de travail** : `IUnitOfWork.SaveChangesAsync()` — les repositories modifient le graphe en mémoire, la persistance est commitée explicitement par le service appelant (`MaintenanceSchedulingEngine`, `WorkOrderCompletionService`, etc.).
- **Ed25519** : `BouncyCastle.Cryptography` (managé pur), pas NSec/libsodium (dépendance native incompatible avec la contrainte "pas de DLL native à embarquer dans le MSIX").
- **Moteur de planification préventive** : ne calcule jamais qu'UNE seule prochaine occurrence par gamme (`FrequencyCalculator.ComputeNextDueDate`), à partir de la dernière exécution réelle. La génération d'OT est dédupliquée par un index unique `(MaintenancePlanId, GeneratedForOccurrenceKey)` côté base, pas par une logique applicative fragile.
## Points ouverts / à trancher au fil de l'implémentation
- **Hébergement d'App.SyncServer** : en cours d'exécution intégrée au process App.UI (un `WebApplication`/Kestrel démarré en tâche de fond dans l'app WinUI, partageant le même `DbContext`) plutôt qu'un `.exe` séparé à lancer/superviser — à confirmer à l'étape 3i.
- **Clé publique Ed25519** : `Ed25519PublicKeyProvider` contient des fragments placeholder (zéros) qui lèvent une exception explicite tant que la vraie paire de clés n'a pas été générée par `LicenseGenerator`.
## Environnement de build
- SDK .NET 8 + Visual Studio 2022 Community (workloads `.NET Desktop Development` + `Windows application development`) installés via winget sur ce poste.
- Aucune build/test n'a encore été exécutée au moment de la rédaction de ce document — à faire dès l'installation terminée, avant d'ajouter du code supplémentaire.