generator client { provider = "prisma-client-js" } datasource db { provider = "postgresql" url = env("DATABASE_URL") } model User { id String @id @default(cuid()) email String @unique createdAt DateTime @default(now()) updatedAt DateTime @updatedAt sessions Session[] draft RuleDraft? rules PublishedRule[] /// At most one pending verified email change (CR-103). emailChangeToken EmailChangeToken? } /// Pending email change: user must open verify link sent to `newEmail` (CR-103). /// Separate from `MagicLinkToken` so sign-in and email-change flows cannot be confused. model EmailChangeToken { id String @id @default(cuid()) userId String @unique user User @relation(fields: [userId], references: [id], onDelete: Cascade) newEmail String tokenHash String @unique expiresAt DateTime createdAt DateTime @default(now()) @@index([newEmail]) } model Session { id String @id @default(cuid()) userId String user User @relation(fields: [userId], references: [id], onDelete: Cascade) tokenHash String @unique expiresAt DateTime createdAt DateTime @default(now()) @@index([userId]) } model MagicLinkToken { id String @id @default(cuid()) email String tokenHash String @unique expiresAt DateTime nextPath String? createdAt DateTime @default(now()) @@index([email]) } model RuleDraft { id String @id @default(cuid()) userId String @unique user User @relation(fields: [userId], references: [id], onDelete: Cascade) payload Json updatedAt DateTime @updatedAt } model PublishedRule { id String @id @default(cuid()) userId String? user User? @relation(fields: [userId], references: [id], onDelete: SetNull) title String summary String? document Json createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@index([userId]) } model RuleTemplate { id String @id @default(cuid()) slug String @unique title String category String? description String? body Json sortOrder Int @default(0) featured Boolean @default(false) } /// Recommendation matrix (CR-88). /// JSON in `data/create/customRule/
.json` is canonical; this table is /// rebuilt from those files at `prisma db seed` time so the API can join. /// See `docs/guides/template-recommendation-matrix.md` §7. model MethodFacet { id String @id @default(cuid()) /// One of "communication" | "membership" | "decisionApproaches" | "conflictManagement". section String /// Matches the `id` of an entry in `messages/en/create/customRule/
.json#/methods`. slug String /// One of "size" | "orgType" | "scale" | "maturity". group String /// Canonical facet value id, e.g. "workersCoop", "earlyStage". value String /// `true` iff the JSON marks this method as matching the facet (`✓` cell). matches Boolean /// Optional per-cell weight; reserved for a future weighted-rank pass (v1 ignores). weight Float? @@unique([section, slug, group, value]) @@index([section]) @@index([group, value, matches]) }