Files
Gmao-app-win11/docs/ARCHITECTURE.md
2026-09-10 16:43:09 +02:00

3.6 KiB

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.