generator client { provider = "prisma-client-js" binaryTargets = ["debian-openssl-3.0.x", "native"] } datasource db { provider = "postgresql" 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") resetToken String? @unique resetTokenExpiry DateTime? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt cardSizeMode String @default("variable") accounts Account[] agents Agent[] aiFeedback AiFeedback[] canvases Canvas[] conversations Conversation[] labels Label[] memoryEchoInsights MemoryEchoInsight[] notes Note[] sentShares NoteShare[] @relation("SentShares") receivedShares NoteShare[] @relation("ReceivedShares") notebooks Notebook[] sessions Session[] aiSettings UserAISettings? workflows Workflow[] } 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 agents Agent[] conversations Conversation[] labels Label[] notes Note[] user User @relation(fields: [userId], references: [id], onDelete: Cascade) workflows Workflow[] @@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 notebook Notebook? @relation(fields: [notebookId], references: [id], onDelete: Cascade) user User? @relation(fields: [userId], 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) 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? trashedAt DateTime? aiFeedback AiFeedback[] memoryEchoAsNote1 MemoryEchoInsight[] @relation("EchoNote1") memoryEchoAsNote2 MemoryEchoInsight[] @relation("EchoNote2") notebook Notebook? @relation(fields: [notebookId], references: [id]) user User? @relation(fields: [userId], references: [id], onDelete: Cascade) noteEmbedding NoteEmbedding? shares NoteShare[] labelRelations Label[] @relation("LabelToNote") @@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 note Note @relation(fields: [noteId], references: [id], onDelete: Cascade) sharer User @relation("SentShares", fields: [sharedBy], references: [id], onDelete: Cascade) user User @relation("ReceivedShares", fields: [userId], 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()) note Note @relation(fields: [noteId], references: [id], onDelete: Cascade) user User? @relation(fields: [userId], 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) note1 Note @relation("EchoNote1", fields: [note1Id], references: [id], onDelete: Cascade) note2 Note @relation("EchoNote2", fields: [note2Id], references: [id], onDelete: Cascade) user User? @relation(fields: [userId], 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) autoLabeling Boolean @default(true) languageDetection Boolean @default(true) 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]) } model Agent { id String @id @default(cuid()) name String description String? type String? @default("scraper") role String sourceUrls String? frequency String @default("manual") lastRun DateTime? nextRun DateTime? isEnabled Boolean @default(true) targetNotebookId String? sourceNotebookId String? tools String? @default("[]") maxSteps Int @default(10) notifyEmail Boolean @default(false) includeImages Boolean @default(false) userId String createdAt DateTime @default(now()) updatedAt DateTime @updatedAt scheduledTime String? @default("08:00") scheduledDay Int? timezone String? notebook Notebook? @relation(fields: [targetNotebookId], references: [id]) user User @relation(fields: [userId], references: [id], onDelete: Cascade) actions AgentAction[] @@index([userId]) @@index([isEnabled]) } model AgentAction { id String @id @default(cuid()) agentId String status String @default("pending") result String? log String? input String? toolLog String? tokensUsed Int? 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? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt messages ChatMessage[] notebook Notebook? @relation(fields: [notebookId], references: [id]) user User @relation(fields: [userId], references: [id], onDelete: Cascade) @@index([userId]) @@index([notebookId]) } model ChatMessage { id String @id @default(cuid()) conversationId String role String 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 userId String createdAt DateTime @default(now()) updatedAt DateTime @updatedAt user User @relation(fields: [userId], references: [id], onDelete: Cascade) @@index([userId]) } model Workflow { id String @id @default(cuid()) name String description String? graph String @default("{\"nodes\":[],\"edges\":[]}") isEnabled Boolean @default(true) userId String notebookId String? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt notebook Notebook? @relation(fields: [notebookId], references: [id]) user User @relation(fields: [userId], references: [id], onDelete: Cascade) runs WorkflowRun[] @@index([userId]) @@index([isEnabled]) } model WorkflowRun { id String @id @default(cuid()) workflowId String status String @default("running") log String? createdAt DateTime @default(now()) workflow Workflow @relation(fields: [workflowId], references: [id], onDelete: Cascade) @@index([workflowId]) @@index([status]) }