242 lines
7.3 KiB
Plaintext
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])
|
|
}
|