Files
siop2/docs/03-architecture/modele-donnees.md
2026-07-15 21:26:27 +01:00

3.1 KiB
Raw Blame History

Modèle de données — SIOP V2

Rôle de ce document (playbook) : le modèle est introduit par release (on ne modélise pas ce qu'on ne construit pas). Chaque section explique les invariants et OÙ ils vivent (base / service). La v1 sert de référence éprouvée pour les entités à venir.

R0 — Identité & permissions

model Role {
  id          String       @id @default(uuid()) @db.Uuid
  name        String       @unique            // Administrateur, Dispatcher, Technicien,
  users       User[]                          // Technicien limité, Gestionnaire,
  permissions Permission[]                    // Demandeur, Vue seule
}

model Permission {           // matrice rôles × objets × droits — EN BASE, jamais dans le JWT
  id             String  @id @default(uuid()) @db.Uuid
  roleId         String  @db.Uuid
  role           Role    @relation(...)
  objectCategory String                       // enum applicatif : WORK_ORDERS, ASSETS, …
  canView        Boolean @default(false)
  canViewOther   Boolean @default(false)      // « voir autre » : au-delà de ses propres objets
  canCreate      Boolean @default(false)
  canEdit        Boolean @default(false)
  canDelete      Boolean @default(false)
  @@unique([roleId, objectCategory])
}

model User {
  id           String  @id @default(uuid()) @db.Uuid
  email        String  @unique
  displayName  String
  passwordHash String?                        // null tant que le compte n'est pas activé (R1)
  roleId       String  @db.Uuid
  role         Role    @relation(...)
  isActive     Boolean @default(true)
  isDemo       Boolean @default(false)        // seul un compte isDemo est empruntable (ADR-002)
  createdAt    DateTime @default(now())
  updatedAt    DateTime @updatedAt
}

Invariants R0 :

Invariant Où il vit
Un rôle par utilisateur ; la matrice décide de tout accès PermissionsGuard (relit la base, cache 60 s)
Le JWT ne porte jamais de droits (seulement l'identité + roleId) conception auth
demo-login refuse tout compte isDemo=false service auth (+ test e2e)
Matrice complète : chaque rôle a une ligne par catégorie d'objet seed idempotent (+ test)

À venir (référence v1 éprouvée, sera réintroduit release par release)

  • R1 : Location (hiérarchie + colonne PostGIS), Asset + organes (hiérarchie 2 niveaux, CHECK « un organe n'a pas d'emplacement propre »), Category, Team.
  • R2 : WorkOrder (machine à états stricte, priorité « personne bloquée »), Request (lien 1-1 vers OT), InterventionReport (bilan codé 6 champs → ReferenceValue), TaskTemplate/PreventivePlan/ChecklistItem (périodicité calendrier), Meter.
  • R3 : Part/StockMovement (stock dérivé des mouvements), PurchaseOrder, Partner, LaborTime (taux figé), Document.
  • R4 : WorkOrder.version (verrou optimiste de la synchro mobile).
  • R5 : tables d'embeddings pgvector (côté service IA).

Journal des migrations

# Migration Contenu
1 r0_identity Role, Permission, User (+ index & uniques ci-dessus)