mirror of
https://github.com/siop-spelev/siop2.git
synced 2026-08-08 12:41:54 +00:00
- image api : multi-stage (pnpm deploy --legacy --prod), client Prisma régénéré dans l'arborescence déployée, binaryTargets explicites (debian/arm64 openssl-3), entrypoint migrate deploy → seed optionnel (SEED_ON_START, compilé dist/seed) → API ; non-root, healthcheck /health - image web : nginx alpine, statique Vite, proxy /api résolu À LA REQUÊTE (resolver Docker + variable — nginx démarre sans l'API), fallback SPA, cache immuable /assets, healthcheck IPv4 (127.0.0.1) - infra/docker-compose.dokploy.yml : 5 services préfixés siop2-, secrets exigés, seul siop2-web rejoint dokploy-network (API jamais exposée) - runbook docs/06-production/runbook-dokploy.md : topologie, profils d'environnement, checklist première prod, rollback, répétition locale - répétition locale validée de bout en bout : migrate+seed au boot, parcours demo-login → /users/me à travers nginx conteneurisé, conteneurs healthy ; le double verrou ADR-002 (DEMO_MODE sans I_KNOW en production) a refusé de démarrer — observé en situation réelle - prisma passe en dépendance de production (migrations au boot) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
51 lines
1.8 KiB
Plaintext
51 lines
1.8 KiB
Plaintext
// 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"
|
||
// Cibles explicites : poste de dev (native) + conteneur node:24-slim
|
||
// (OpenSSL 3) en x64 (serveur partenaire) et arm64 (répétition locale).
|
||
binaryTargets = ["native", "debian-openssl-3.0.x", "linux-arm64-openssl-3.0.x"]
|
||
}
|
||
|
||
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])
|
||
}
|