rnotes-online/prisma/schema.prisma

176 lines
4.7 KiB
Plaintext

generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
// ─── Auth ────────────────────────────────────────────────
model User {
id String @id @default(cuid())
did String? @unique
username String? @unique
name String?
email String? @unique
emailVerified DateTime?
image String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
memberships SpaceMember[]
notebooks Notebook[]
comments Comment[]
suggestions Suggestion[]
reactions Reaction[]
}
// ─── Multi-tenant Spaces ─────────────────────────────────
enum SpaceRole {
ADMIN
MODERATOR
MEMBER
VIEWER
}
model Space {
id String @id @default(cuid())
slug String @unique
name String
description String @default("")
icon String @default("")
visibility String @default("public_read")
ownerDid String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
members SpaceMember[]
notebooks Notebook[]
}
model SpaceMember {
id String @id @default(cuid())
userId String
spaceId String
role SpaceRole @default(MEMBER)
joinedAt DateTime @default(now())
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
space Space @relation(fields: [spaceId], references: [id], onDelete: Cascade)
@@unique([userId, spaceId])
}
// ─── Notebooks & Notes ───────────────────────────────────
model Notebook {
id String @id @default(cuid())
spaceId String
title String
description String @default("")
icon String @default("📓")
createdBy String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
space Space @relation(fields: [spaceId], references: [id], onDelete: Cascade)
creator User @relation(fields: [createdBy], references: [id])
notes Note[]
@@index([spaceId])
}
model Note {
id String @id @default(cuid())
notebookId String
title String @default("Untitled")
yjsDocId String @unique @default(cuid())
sortOrder Int @default(0)
createdBy String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
notebook Notebook @relation(fields: [notebookId], references: [id], onDelete: Cascade)
comments Comment[]
suggestions Suggestion[]
@@index([notebookId])
}
// ─── Suggestions (Track Changes) ─────────────────────────
enum SuggestionStatus {
PENDING
ACCEPTED
REJECTED
}
enum SuggestionType {
INSERT
DELETE
FORMAT
REPLACE
}
model Suggestion {
id String @id @default(cuid())
noteId String
authorId String
type SuggestionType
status SuggestionStatus @default(PENDING)
fromPos Int
toPos Int
content String?
oldContent String?
attrs Json?
resolvedBy String?
resolvedAt DateTime?
createdAt DateTime @default(now())
note Note @relation(fields: [noteId], references: [id], onDelete: Cascade)
author User @relation(fields: [authorId], references: [id])
@@index([noteId, status])
}
// ─── Comments & Threads ──────────────────────────────────
model Comment {
id String @id @default(cuid())
noteId String
authorId String
parentId String?
body String
fromPos Int
toPos Int
resolved Boolean @default(false)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
note Note @relation(fields: [noteId], references: [id], onDelete: Cascade)
author User @relation(fields: [authorId], references: [id])
parent Comment? @relation("CommentThread", fields: [parentId], references: [id])
replies Comment[] @relation("CommentThread")
reactions Reaction[]
@@index([noteId])
}
// ─── Emoji Reactions ─────────────────────────────────────
model Reaction {
id String @id @default(cuid())
commentId String
userId String
emoji String
createdAt DateTime @default(now())
comment Comment @relation(fields: [commentId], references: [id], onDelete: Cascade)
user User @relation(fields: [userId], references: [id])
@@unique([commentId, userId, emoji])
}