86 lines
6.3 KiB
Markdown
86 lines
6.3 KiB
Markdown
# Schéma de base de données — ARGOS (SQLite / EF Core 8)
|
|
|
|
Référence tenue à jour au fil de l'implémentation des entités `App.Core/Entities/**`.
|
|
Les types EF Core réels sont fixés dans `App.Infrastructure/Data/Configurations/*`.
|
|
|
|
## Équipe & authentification
|
|
|
|
**Users** — Id PK · Username (UNIQUE) · PasswordHash (Argon2id) · FullName · Email? · Role (enum) · IsActive · CreatedAtUtc · LastLoginAtUtc?
|
|
|
|
**TechnicianProfiles** (1:1 avec Users) — UserId PK/FK → Users · Skills? · PhoneNumber?
|
|
|
|
**QualificationTypes** — Id PK · Code (ex "B1","BR") · Label · Category (enum Electrique/Mecanique/Autre)
|
|
|
|
**TechnicianQualifications** — Id PK · TechnicianUserId FK → TechnicianProfiles · QualificationTypeId FK · ObtainedDate · ExpiryDate? · CertificateAttachmentId FK → Attachments?
|
|
Index (TechnicianUserId, ExpiryDate) pour l'alerte habilitations expirantes.
|
|
|
|
**TimeEntries** — Id PK · WorkOrderId FK → WorkOrders · TechnicianUserId FK → Users · StartedAtUtc · EndedAtUtc? · DurationMinutes · Source (enum Pc/AndroidSync) · Comment? · SyncDeviceId FK → SyncDevices?
|
|
|
|
## Machines
|
|
|
|
**Machines** — Id PK · Reference (UNIQUE) · Designation · Location? · Criticality (enum) · CommissioningDate? · PhotoAttachmentId FK → Attachments? · IsActive (soft delete) · CreatedAtUtc · UpdatedAtUtc
|
|
|
|
**MachineParts** — MachineId FK, PartId FK (PK composite) — nomenclature pièces/machine
|
|
|
|
**MachineCounterReadings** — Id PK · MachineId FK · CounterType (texte libre) · Value (REAL) · RecordedAtUtc · Source (enum Pc/AndroidSync)
|
|
Index (MachineId, CounterType, RecordedAtUtc DESC)
|
|
|
|
## Maintenance préventive
|
|
|
|
**MaintenancePlans** (gammes) — Id PK · MachineId FK · Name · Description? · FrequencyType (enum) · **StartDate** (ancre avant 1ère exécution) · CustomIntervalDays? · DayOfWeek? · DayOfMonth? · MonthlyRuleOccurrence? · MonthlyRuleWeekday? · CounterType? · CounterThreshold? · LeadTimeDays? · LeadTimePercentForCounter? · RequiredQualificationTypeId FK? · LastExecutionDateUtc? · LastExecutionCounterValue? · IsActive · CreatedAtUtc
|
|
|
|
**MaintenanceTasks** — Id PK · MaintenancePlanId FK · Order · Label · Description? · EstimatedDurationMinutes?
|
|
|
|
**Tools** — Id PK · Name (référentiel réutilisable)
|
|
**MaintenanceTaskTools** — MaintenanceTaskId FK, ToolId FK (PK composite)
|
|
**MaintenanceTaskParts** — MaintenanceTaskId FK, PartId FK (PK composite) · QuantityRequired
|
|
|
|
**WorkOrders** (OT) — Id PK · MachineId FK · MaintenancePlanId FK? (null = curatif) · Type (enum) · Status (enum) · Priority (enum) · ScheduledDate · DueDate? · CompletedAtUtc? · AssignedTechnicianUserId FK → Users? · **GeneratedForOccurrenceKey?** · Comment? · Source (enum) · CreatedAtUtc
|
|
**Index unique filtré** : `(MaintenancePlanId, GeneratedForOccurrenceKey) WHERE MaintenancePlanId IS NOT NULL` — anti-doublon de génération, voir `MaintenanceSchedulingEngine`.
|
|
|
|
**WorkOrderTaskResults** — Id PK · WorkOrderId FK · MaintenanceTaskId? (null = tâche ad-hoc curative) · IsCompleted · Comment? · PhotoAttachmentId FK → Attachments? · CompletedAtUtc? · CompletedByTechnicianUserId FK → Users?
|
|
|
|
**WorkOrderPartsUsed** — Id PK · WorkOrderId FK · PartId FK · QuantityUsed · StockMovementId FK → StockMovements?
|
|
|
|
## Magasin / stock
|
|
|
|
**Suppliers** — Id PK · Name · ContactName? · Phone? · Email? · Address?
|
|
|
|
**Parts** — Id PK · Reference (UNIQUE) · Designation · QuantityInStock (dénormalisé) · AlertThreshold · Location? · PrimarySupplierId FK? · UnitPrice · PhotoAttachmentId FK? · IsActive
|
|
|
|
**StockMovements** — Id PK · PartId FK · MovementType (enum In/Out) · Quantity · Reason? · WorkOrderId FK? · SupplierInvoiceId FK? · CreatedByUserId FK → Users · CreatedAtUtc
|
|
Index (PartId, CreatedAtUtc)
|
|
|
|
## Facturation
|
|
|
|
**SupplierInvoices** — Id PK · SupplierId FK? · InvoiceNumber? · InvoiceDate · Amount · AttachmentId FK → Attachments (NOT NULL) · LinkedWorkOrderId FK? · ImportedAtUtc
|
|
|
|
**Invoices** — Id PK · DocumentType (enum Invoice/Quote) · Number (UNIQUE) · ClientName · ClientAddress? · IssueDate · DueDate? · VatRate · Status (enum) · TotalHT · TotalTTC · PdfAttachmentId FK? · LinkedWorkOrderId FK? · CreatedByUserId FK → Users · CreatedAtUtc
|
|
|
|
**InvoiceLines** — Id PK · InvoiceId FK · Order · Designation · Quantity · UnitPrice · VatRateOverride?
|
|
|
|
## Sync réseau local (Android futur)
|
|
|
|
**SyncDevices** — Id PK · DeviceName · DeviceIdentifier (UNIQUE) · PairedAtUtc · PairingPinHash · LastSyncAtUtc? · IsActive
|
|
|
|
**SyncLogEntries** — Id PK · SyncDeviceId FK · Direction (enum Push/Pull) · EntityType · Status (enum) · ErrorMessage? · OccurredAtUtc
|
|
|
|
## Transverse
|
|
|
|
**Attachments** — Id PK · FileName · ContentType · StoredRelativePath (relatif à LocalFolder) · SizeBytes · EntityType (enum `AttachmentOwnerType`) · EntityId (int) · UploadedAtUtc · UploadedByUserId FK → Users?
|
|
⚠️ Clé polymorphe (EntityType+EntityId) : pas de FK SQLite possible, intégrité gérée par `IAttachmentRepository` (choix assumé, voir `docs/ARCHITECTURE.md`).
|
|
|
|
**AppSettings** — Key PK (texte) · Value (texte) — clé-valeur générique, typé côté `App.Core` via `ISettingsProvider`. Clés connues : `App.Core.Entities.Shared.AppSettingKeys`.
|
|
|
|
**LicenseActivationCache** — Id PK · CompanyName · MaxUsers · MaxMachines · IssuedDate — cache d'affichage uniquement, jamais utilisé pour la vérification (voir §Licence).
|
|
|
|
## Licence & essai — hors SQLite
|
|
|
|
- État d'essai (`InstallDateUtc`, `HardwareIdHash`, `LastRunTimestampUtc`) : fichier séparé chiffré DPAPI (`DataProtectionScope.LocalMachine`) dans `LocalFolder`, PAS en base — un reset de `app.db` ne doit jamais relancer un essai.
|
|
- Licence activée : fichier `.lic` JSON signé Ed25519, copié tel quel dans `LocalFolder`, revérifié (signature + hardware match) à chaque démarrage. Modèles : `App.Core.Services.Licensing.{LicenseFile, TrialState, LicenseCheckResult}`.
|
|
|
|
## Notes d'implémentation
|
|
|
|
- Mode SQLite **WAL** à activer dès la première migration (`PRAGMA journal_mode=WAL`) : App.UI (thread UI) et App.SyncServer (Kestrel local) écrivent potentiellement en même temps dans `app.db`.
|
|
- Toutes les dates métier "pures" (échéances, dates de naissance de document) utilisent `DateOnly` ; les horodatages système utilisent `DateTime` en UTC (`...AtUtc`).
|