Files
everclone/prisma/schema.prisma
T

242 lines
7.3 KiB
Plaintext

generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model User {
id String @id @default(cuid())
email String @unique
name String
avatarColor String @default("#00a82d")
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model NotebookStack {
id String @id @default(cuid())
userId String @default("default")
name String
sortOrder Int @default(0)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
notebooks Notebook[]
@@unique([userId, name])
@@index([userId])
}
model Notebook {
id String @id @default(cuid())
userId String @default("default")
name String
stackId String?
stack NotebookStack? @relation(fields: [stackId], references: [id], onDelete: SetNull)
isDefault Boolean @default(false)
isShortcut Boolean @default(false)
sortOrder Int @default(0)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
notes Note[]
autoSortRules AutoSortRule[]
shares NotebookShare[]
@@unique([userId, name])
@@index([userId])
@@index([stackId])
}
model NotebookShare {
id String @id @default(cuid())
notebookId String
notebook Notebook @relation(fields: [notebookId], references: [id], onDelete: Cascade)
userId String // Collaborator user ID
role String @default("write") // "read" | "write"
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@unique([notebookId, userId])
@@index([userId])
@@index([notebookId])
}
model Note {
id String @id @default(cuid())
userId String @default("default")
title String @default("Untitled Note")
contentHtml String @default("")
contentText String @default("")
excerpt String @default("")
notebookId String
notebook Notebook @relation(fields: [notebookId], references: [id], onDelete: Cascade)
isPinned Boolean @default(false)
isShortcut Boolean @default(false)
isTrashed Boolean @default(false)
trashedAt DateTime?
thumbnailUrl String?
sourceUrl String?
author String?
latitude Float?
longitude Float?
reminderAt DateTime?
reminderDone Boolean @default(false)
createdAt DateTime @default(now())
updatedAt DateTime @default(now())
tags NoteTag[]
attachments Attachment[]
history NoteHistory[]
@@index([userId, isTrashed, isPinned, updatedAt(sort: Desc)])
@@index([notebookId, isTrashed, updatedAt(sort: Desc)])
@@index([isTrashed, isPinned, updatedAt(sort: Desc)])
@@index([isShortcut, isTrashed])
@@index([createdAt(sort: Desc)])
@@index([title])
}
model NoteHistory {
id String @id @default(cuid())
noteId String
note Note @relation(fields: [noteId], references: [id], onDelete: Cascade)
title String
contentHtml String
contentText String
excerpt String @default("")
wordCount Int @default(0)
createdBy String?
createdAt DateTime @default(now())
@@index([noteId, createdAt(sort: Desc)])
}
model Tag {
id String @id @default(cuid())
userId String @default("default")
name String
color String @default("#00a82d")
parentId String?
parent Tag? @relation("TagHierarchy", fields: [parentId], references: [id], onDelete: SetNull)
children Tag[] @relation("TagHierarchy")
isShortcut Boolean @default(false)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
notes NoteTag[]
@@unique([userId, name])
@@index([userId])
@@index([parentId])
}
model NoteTag {
noteId String
tagId String
note Note @relation(fields: [noteId], references: [id], onDelete: Cascade)
tag Tag @relation(fields: [tagId], references: [id], onDelete: Cascade)
assignedAt DateTime @default(now())
@@id([noteId, tagId])
@@index([tagId])
}
model Attachment {
id String @id @default(cuid())
noteId String
note Note @relation(fields: [noteId], references: [id], onDelete: Cascade)
filename String
mimeType String
sizeBytes Int
md5Hash String
storagePath String
width Int?
height Int?
extractedText String?
createdAt DateTime @default(now())
@@index([noteId])
@@index([md5Hash])
}
model SavedSearch {
id String @id @default(cuid())
userId String @default("default")
name String
query String
isShortcut Boolean @default(false)
sortOrder Int @default(0)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@unique([userId, name])
@@index([userId])
}
model ApiKey {
id String @id @default(cuid())
userId String @default("default")
name String
keyHash String @unique
keyPrefix String
lastUsedAt DateTime?
createdAt DateTime @default(now())
}
model ImportJob {
id String @id @default(cuid())
userId String @default("default")
sourceType String
filename String
status String @default("running")
totalNotes Int @default(0)
processedNotes Int @default(0)
failedNotes Int @default(0)
errorLog String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model EmailConfig {
id String @id @default("default")
userId String @default("default")
enabled Boolean @default(false)
imapHost String @default("imap.gmail.com")
imapPort Int @default(993)
imapSecure Boolean @default(true)
imapUser String @default("")
imapPassword String @default("")
mailbox String @default("INBOX")
subjectFilter String @default("")
allowedSenders String @default("")
defaultNotebook String @default("Inbox")
defaultTags String @default("emailed")
markSeen Boolean @default(true)
lastCheckedAt DateTime?
lastStatus String?
emailsImported Int @default(0)
updatedAt DateTime @updatedAt
}
model AutoSortRule {
id String @id @default(cuid())
userId String @default("default")
name String
enabled Boolean @default(true)
priority Int @default(0)
conditionField String @default("title") // title | content | sourceUrl | author | attachmentType | hasTodo
conditionOperator String @default("contains") // contains | not_contains | equals | startsWith | endsWith | matchesRegex
conditionValue String @default("")
targetNotebookId String?
targetNotebook Notebook? @relation(fields: [targetNotebookId], references: [id], onDelete: SetNull)
addTags String @default("") // comma-separated tag names
isPinned Boolean?
isShortcut Boolean?
stopOnMatch Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([userId, enabled, priority])
@@index([targetNotebookId])
}