Files
siop2/apps/api/prisma/schema.prisma
pr-daaif 8adb561b63 feat(r0.10): apps/api — auth fermée par défaut, matrice en base, démo-login ADR-002, seed
- packages/shared : rôles/catégories, schémas Zod, contrat d'API ;
  pnpm contract → docs/openapi.json committée (règle d'or ADR-001)
- apps/api : NestJS 11 + Prisma 6, migration r0_identity (Role/Permission/User) ;
  guard JWT global + @Public() ; PermissionsGuard (@RequirePermission,
  matrice relue en base, cache 60 s) ; FileStorage (seul import MinIO) ; /health
- démo-login ADR-002 : module conditionnel DEMO_MODE (404 sinon, testé e2e),
  double verrou production, refus des comptes isDemo=false
- seed idempotent : 7 rôles, matrice complète (70 lignes), 7 comptes démo
- 19 tests Jest (unit + e2e) ; smoke test sur build de prod

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 21:55:04 +01:00

48 lines
1.6 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Modèle R0 — identité & permissions (docs/03-architecture/modele-donnees.md).
// La matrice rôles × objets × droits vit EN BASE ; le JWT ne porte jamais de droits.
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model Role {
id String @id @default(uuid()) @db.Uuid
name String @unique // 7 rôles seedés — voir @siop/shared ROLE_NAMES
users User[]
permissions Permission[]
}
model Permission {
id String @id @default(uuid()) @db.Uuid
roleId String @db.Uuid
role Role @relation(fields: [roleId], references: [id], onDelete: Cascade)
objectCategory String // enum applicatif — voir @siop/shared OBJECT_CATEGORIES
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(fields: [roleId], references: [id])
isActive Boolean @default(true)
isDemo Boolean @default(false) // seul un compte isDemo est empruntable (ADR-002)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([roleId])
}