Files
community-rule/prisma/schema.prisma
T
2026-04-29 19:24:50 -06:00

135 lines
4.1 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.
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/<section>.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/<section>.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])
}
/// Template-level recommendation matrix (Template Composition, cols GY). Canonical
/// JSON in `data/templates/templateFacet.json`; rebuilt at seed like
/// `MethodFacet`. One row per `(templateSlug, group, value)` where the matrix
/// marks a fit (✓). `GET /api/templates?facet.*` joins these rows to user facets.
/// See `docs/guides/template-recommendation-matrix.md` (parallel to `MethodFacet` §7).
model TemplateFacet {
id String @id @default(cuid())
/// `RuleTemplate.slug` (e.g. `consensus`, `do-ocracy`).
templateSlug String
/// `size` | `orgType` | `scale` | `maturity` — same as `MethodFacet.group`.
group String
/// Canonical facet value id, e.g. `workersCoop`, `local`.
value String
/// `true` iff the JSON marks a fit; seed only writes `true` rows.
matches Boolean
@@unique([templateSlug, group, value])
@@index([templateSlug])
@@index([group, value, matches])
}