382 lines
13 KiB
Plaintext
382 lines
13 KiB
Plaintext
generator client {
|
|
provider = "prisma-client-js"
|
|
binaryTargets = ["debian-openssl-1.1.x", "native"]
|
|
}
|
|
|
|
datasource db {
|
|
provider = "sqlite"
|
|
url = env("DATABASE_URL")
|
|
}
|
|
|
|
model User {
|
|
id String @id @default(cuid())
|
|
name String?
|
|
email String @unique
|
|
emailVerified DateTime?
|
|
password String?
|
|
role String @default("USER")
|
|
image String?
|
|
theme String @default("light")
|
|
cardSizeMode String @default("variable")
|
|
resetToken String? @unique
|
|
resetTokenExpiry DateTime?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
accounts Account[]
|
|
aiFeedback AiFeedback[]
|
|
labels Label[]
|
|
memoryEchoInsights MemoryEchoInsight[]
|
|
notes Note[]
|
|
sentShares NoteShare[] @relation("SentShares")
|
|
receivedShares NoteShare[] @relation("ReceivedShares")
|
|
notebooks Notebook[]
|
|
sessions Session[]
|
|
aiSettings UserAISettings?
|
|
agents Agent[]
|
|
workflows Workflow[]
|
|
conversations Conversation[]
|
|
canvases Canvas[]
|
|
}
|
|
|
|
model Account {
|
|
userId String
|
|
type String
|
|
provider String
|
|
providerAccountId String
|
|
refresh_token String?
|
|
access_token String?
|
|
expires_at Int?
|
|
token_type String?
|
|
scope String?
|
|
id_token String?
|
|
session_state String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
@@id([provider, providerAccountId])
|
|
}
|
|
|
|
model Session {
|
|
sessionToken String @unique
|
|
userId String
|
|
expires DateTime
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
}
|
|
|
|
model VerificationToken {
|
|
identifier String
|
|
token String
|
|
expires DateTime
|
|
|
|
@@id([identifier, token])
|
|
}
|
|
|
|
model Notebook {
|
|
id String @id @default(cuid())
|
|
name String
|
|
icon String?
|
|
color String?
|
|
order Int
|
|
userId String
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
labels Label[]
|
|
notes Note[]
|
|
agents Agent[]
|
|
workflows Workflow[]
|
|
conversations Conversation[]
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([userId, order])
|
|
@@index([userId])
|
|
}
|
|
|
|
model Label {
|
|
id String @id @default(cuid())
|
|
name String
|
|
color String @default("gray")
|
|
notebookId String?
|
|
userId String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
user User? @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
notebook Notebook? @relation(fields: [notebookId], references: [id], onDelete: Cascade)
|
|
notes Note[] @relation("LabelToNote")
|
|
|
|
@@unique([notebookId, name])
|
|
@@index([notebookId])
|
|
@@index([userId])
|
|
}
|
|
|
|
model Note {
|
|
id String @id @default(cuid())
|
|
title String?
|
|
content String
|
|
color String @default("default")
|
|
isPinned Boolean @default(false)
|
|
isArchived Boolean @default(false)
|
|
trashedAt DateTime?
|
|
type String @default("text")
|
|
dismissedFromRecent Boolean @default(false)
|
|
checkItems String?
|
|
labels String?
|
|
images String?
|
|
links String?
|
|
reminder DateTime?
|
|
isReminderDone Boolean @default(false)
|
|
reminderRecurrence String?
|
|
reminderLocation String?
|
|
isMarkdown Boolean @default(false)
|
|
size String @default("small")
|
|
sharedWith String?
|
|
userId String?
|
|
order Int @default(0)
|
|
notebookId String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
contentUpdatedAt DateTime @default(now())
|
|
autoGenerated Boolean?
|
|
aiProvider String?
|
|
aiConfidence Int?
|
|
language String?
|
|
languageConfidence Float?
|
|
lastAiAnalysis DateTime?
|
|
aiFeedback AiFeedback[]
|
|
memoryEchoAsNote2 MemoryEchoInsight[] @relation("EchoNote2")
|
|
memoryEchoAsNote1 MemoryEchoInsight[] @relation("EchoNote1")
|
|
notebook Notebook? @relation(fields: [notebookId], references: [id])
|
|
user User? @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
shares NoteShare[]
|
|
labelRelations Label[] @relation("LabelToNote")
|
|
noteEmbedding NoteEmbedding?
|
|
|
|
@@index([isPinned])
|
|
@@index([isArchived])
|
|
@@index([trashedAt])
|
|
@@index([order])
|
|
@@index([reminder])
|
|
@@index([userId])
|
|
@@index([userId, notebookId])
|
|
}
|
|
|
|
model NoteShare {
|
|
id String @id @default(cuid())
|
|
noteId String
|
|
userId String
|
|
sharedBy String
|
|
status String @default("pending")
|
|
permission String @default("view")
|
|
notifiedAt DateTime?
|
|
respondedAt DateTime?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
sharer User @relation("SentShares", fields: [sharedBy], references: [id], onDelete: Cascade)
|
|
user User @relation("ReceivedShares", fields: [userId], references: [id], onDelete: Cascade)
|
|
note Note @relation(fields: [noteId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([noteId, userId])
|
|
@@index([userId])
|
|
@@index([status])
|
|
@@index([sharedBy])
|
|
}
|
|
|
|
model SystemConfig {
|
|
key String @id
|
|
value String
|
|
}
|
|
|
|
model AiFeedback {
|
|
id String @id @default(cuid())
|
|
noteId String
|
|
userId String?
|
|
feedbackType String
|
|
feature String
|
|
originalContent String
|
|
correctedContent String?
|
|
metadata String?
|
|
createdAt DateTime @default(now())
|
|
user User? @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
note Note @relation(fields: [noteId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([noteId])
|
|
@@index([userId])
|
|
@@index([feature])
|
|
}
|
|
|
|
model MemoryEchoInsight {
|
|
id String @id @default(cuid())
|
|
userId String?
|
|
note1Id String
|
|
note2Id String
|
|
similarityScore Float
|
|
insight String
|
|
insightDate DateTime @default(now())
|
|
viewed Boolean @default(false)
|
|
feedback String?
|
|
dismissed Boolean @default(false)
|
|
user User? @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
note2 Note @relation("EchoNote2", fields: [note2Id], references: [id], onDelete: Cascade)
|
|
note1 Note @relation("EchoNote1", fields: [note1Id], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([userId, insightDate])
|
|
@@index([userId, insightDate])
|
|
@@index([userId, dismissed])
|
|
}
|
|
|
|
model UserAISettings {
|
|
userId String @id
|
|
titleSuggestions Boolean @default(true)
|
|
semanticSearch Boolean @default(true)
|
|
paragraphRefactor Boolean @default(true)
|
|
memoryEcho Boolean @default(true)
|
|
memoryEchoFrequency String @default("daily")
|
|
aiProvider String @default("auto")
|
|
preferredLanguage String @default("auto")
|
|
fontSize String @default("medium")
|
|
demoMode Boolean @default(false)
|
|
showRecentNotes Boolean @default(true)
|
|
/// "masonry" = grille cartes Muuri ; "tabs" = onglets + panneau (type OneNote). Ancienne valeur "list" migrée vers "tabs" en lecture.
|
|
notesViewMode String @default("masonry")
|
|
emailNotifications Boolean @default(false)
|
|
desktopNotifications Boolean @default(false)
|
|
anonymousAnalytics Boolean @default(false)
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([memoryEcho])
|
|
@@index([aiProvider])
|
|
@@index([memoryEchoFrequency])
|
|
@@index([preferredLanguage])
|
|
}
|
|
|
|
model NoteEmbedding {
|
|
id String @id @default(cuid())
|
|
noteId String @unique
|
|
embedding String
|
|
createdAt DateTime @default(now())
|
|
note Note @relation(fields: [noteId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([noteId])
|
|
}
|
|
|
|
// ============================================================================
|
|
// NEW MODELS FOR AGENTIC SYSTEM & LAB
|
|
// ============================================================================
|
|
|
|
model Agent {
|
|
id String @id @default(cuid())
|
|
name String
|
|
description String?
|
|
type String? @default("scraper") // scraper, researcher, monitor, custom
|
|
role String // System prompt / Persona
|
|
sourceUrls String? // JSON list of URLs to scrape
|
|
frequency String @default("manual") // manual, hourly, daily, weekly, monthly
|
|
lastRun DateTime?
|
|
nextRun DateTime?
|
|
isEnabled Boolean @default(true)
|
|
targetNotebookId String?
|
|
sourceNotebookId String? // For monitor type: notebook to watch
|
|
tools String? @default("[]") // JSON array: ["web_search", "note_search", ...]
|
|
maxSteps Int @default(10) // Max tool-use iterations
|
|
notifyEmail Boolean @default(false) // Send email notification after execution
|
|
includeImages Boolean @default(false) // Extract images from scraped pages
|
|
userId String
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
notebook Notebook? @relation(fields: [targetNotebookId], references: [id])
|
|
actions AgentAction[]
|
|
|
|
@@index([userId])
|
|
@@index([isEnabled])
|
|
}
|
|
|
|
model AgentAction {
|
|
id String @id @default(cuid())
|
|
agentId String
|
|
status String @default("pending") // pending, running, success, failure
|
|
result String? // ID of the created note or summary message
|
|
log String? // Error message or execution log
|
|
input String? // JSON: prompt initial + config
|
|
toolLog String? // JSON: trace [{step, toolCalls, toolResults}]
|
|
tokensUsed Int? // Token consumption
|
|
createdAt DateTime @default(now())
|
|
agent Agent @relation(fields: [agentId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([agentId])
|
|
}
|
|
|
|
model Conversation {
|
|
id String @id @default(cuid())
|
|
title String?
|
|
userId String
|
|
notebookId String? // Optional context
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
notebook Notebook? @relation(fields: [notebookId], references: [id])
|
|
messages ChatMessage[]
|
|
|
|
@@index([userId])
|
|
@@index([notebookId])
|
|
}
|
|
|
|
model ChatMessage {
|
|
id String @id @default(cuid())
|
|
conversationId String
|
|
role String // user, assistant, system
|
|
content String
|
|
createdAt DateTime @default(now())
|
|
conversation Conversation @relation(fields: [conversationId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([conversationId])
|
|
}
|
|
|
|
model Canvas {
|
|
id String @id @default(cuid())
|
|
name String
|
|
data String // Large JSON blob for tldraw state
|
|
userId String
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([userId])
|
|
}
|
|
|
|
// ============================================================================
|
|
// VISUAL WORKFLOW BUILDER
|
|
// ============================================================================
|
|
|
|
model Workflow {
|
|
id String @id @default(cuid())
|
|
name String
|
|
description String?
|
|
graph String @default("{\"nodes\":[],\"edges\":[]}") // JSON: React Flow nodes[] + edges[]
|
|
isEnabled Boolean @default(true)
|
|
userId String
|
|
notebookId String? // default target notebook for Create Note nodes
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
notebook Notebook? @relation(fields: [notebookId], references: [id])
|
|
runs WorkflowRun[]
|
|
|
|
@@index([userId])
|
|
@@index([isEnabled])
|
|
}
|
|
|
|
model WorkflowRun {
|
|
id String @id @default(cuid())
|
|
workflowId String
|
|
status String @default("running") // running, success, failure
|
|
log String? // JSON: per-node status + timing
|
|
createdAt DateTime @default(now())
|
|
workflow Workflow @relation(fields: [workflowId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([workflowId])
|
|
@@index([status])
|
|
}
|