feat: rename keep-notes to memento-note, migrate to PostgreSQL, fix MCP bugs
- Rename directory keep-notes -> memento-note with all code references - Prisma: SQLite -> PostgreSQL (both app and MCP server schemas) - Sync MCP schema with main app (add missing fields, relations, indexes) - Delete 17 SQLite migrations (clean slate for PostgreSQL) - Remove SQLite dependencies (@libsql/client, better-sqlite3, etc.) - Fix MCP server: hardcoded Windows DB paths -> DATABASE_URL env var - Fix MCP server: .dockerignore excluded index-sse.js (SSE mode broken) - MCP Dockerfile: node:20 -> node:22 - Docker Compose: add postgres service, remove SQLite volume - Generate favicon.ico, icon-192.png, icon-512.png, apple-icon.png - Update layout.tsx icons and manifest.json for PNG icons - Update all .env files for PostgreSQL - Rewrite README.md with updated sections - Remove mcp-server/node_modules and prisma/client-generated from git tracking Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
BIN
memento-note/prisma/dev.db
Normal file
BIN
memento-note/prisma/dev.db
Normal file
Binary file not shown.
BIN
memento-note/prisma/dev.db.backup-20260111
Normal file
BIN
memento-note/prisma/dev.db.backup-20260111
Normal file
Binary file not shown.
@@ -0,0 +1,20 @@
|
||||
-- CreateTable
|
||||
CREATE TABLE "Note" (
|
||||
"id" TEXT NOT NULL PRIMARY KEY,
|
||||
"title" TEXT,
|
||||
"content" TEXT NOT NULL,
|
||||
"color" TEXT NOT NULL DEFAULT 'default',
|
||||
"isPinned" BOOLEAN NOT NULL DEFAULT false,
|
||||
"isArchived" BOOLEAN NOT NULL DEFAULT false,
|
||||
"type" TEXT NOT NULL DEFAULT 'text',
|
||||
"checkItems" JSONB,
|
||||
"labels" JSONB,
|
||||
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" DATETIME NOT NULL
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Note_isPinned_idx" ON "Note"("isPinned");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Note_isArchived_idx" ON "Note"("isArchived");
|
||||
@@ -0,0 +1,23 @@
|
||||
-- RedefineTables
|
||||
PRAGMA defer_foreign_keys=ON;
|
||||
PRAGMA foreign_keys=OFF;
|
||||
CREATE TABLE "new_Note" (
|
||||
"id" TEXT NOT NULL PRIMARY KEY,
|
||||
"title" TEXT,
|
||||
"content" TEXT NOT NULL,
|
||||
"color" TEXT NOT NULL DEFAULT 'default',
|
||||
"isPinned" BOOLEAN NOT NULL DEFAULT false,
|
||||
"isArchived" BOOLEAN NOT NULL DEFAULT false,
|
||||
"type" TEXT NOT NULL DEFAULT 'text',
|
||||
"checkItems" TEXT,
|
||||
"labels" TEXT,
|
||||
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" DATETIME NOT NULL
|
||||
);
|
||||
INSERT INTO "new_Note" ("checkItems", "color", "content", "createdAt", "id", "isArchived", "isPinned", "labels", "title", "type", "updatedAt") SELECT "checkItems", "color", "content", "createdAt", "id", "isArchived", "isPinned", "labels", "title", "type", "updatedAt" FROM "Note";
|
||||
DROP TABLE "Note";
|
||||
ALTER TABLE "new_Note" RENAME TO "Note";
|
||||
CREATE INDEX "Note_isPinned_idx" ON "Note"("isPinned");
|
||||
CREATE INDEX "Note_isArchived_idx" ON "Note"("isArchived");
|
||||
PRAGMA foreign_keys=ON;
|
||||
PRAGMA defer_foreign_keys=OFF;
|
||||
@@ -0,0 +1,25 @@
|
||||
-- RedefineTables
|
||||
PRAGMA defer_foreign_keys=ON;
|
||||
PRAGMA foreign_keys=OFF;
|
||||
CREATE TABLE "new_Note" (
|
||||
"id" TEXT NOT NULL PRIMARY KEY,
|
||||
"title" TEXT,
|
||||
"content" TEXT NOT NULL,
|
||||
"color" TEXT NOT NULL DEFAULT 'default',
|
||||
"isPinned" BOOLEAN NOT NULL DEFAULT false,
|
||||
"isArchived" BOOLEAN NOT NULL DEFAULT false,
|
||||
"type" TEXT NOT NULL DEFAULT 'text',
|
||||
"checkItems" TEXT,
|
||||
"labels" TEXT,
|
||||
"order" INTEGER NOT NULL DEFAULT 0,
|
||||
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" DATETIME NOT NULL
|
||||
);
|
||||
INSERT INTO "new_Note" ("checkItems", "color", "content", "createdAt", "id", "isArchived", "isPinned", "labels", "title", "type", "updatedAt") SELECT "checkItems", "color", "content", "createdAt", "id", "isArchived", "isPinned", "labels", "title", "type", "updatedAt" FROM "Note";
|
||||
DROP TABLE "Note";
|
||||
ALTER TABLE "new_Note" RENAME TO "Note";
|
||||
CREATE INDEX "Note_isPinned_idx" ON "Note"("isPinned");
|
||||
CREATE INDEX "Note_isArchived_idx" ON "Note"("isArchived");
|
||||
CREATE INDEX "Note_order_idx" ON "Note"("order");
|
||||
PRAGMA foreign_keys=ON;
|
||||
PRAGMA defer_foreign_keys=OFF;
|
||||
@@ -0,0 +1,2 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "Note" ADD COLUMN "images" TEXT;
|
||||
@@ -0,0 +1,5 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "Note" ADD COLUMN "reminder" DATETIME;
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Note_reminder_idx" ON "Note"("reminder");
|
||||
@@ -0,0 +1,29 @@
|
||||
-- RedefineTables
|
||||
PRAGMA defer_foreign_keys=ON;
|
||||
PRAGMA foreign_keys=OFF;
|
||||
CREATE TABLE "new_Note" (
|
||||
"id" TEXT NOT NULL PRIMARY KEY,
|
||||
"title" TEXT,
|
||||
"content" TEXT NOT NULL,
|
||||
"color" TEXT NOT NULL DEFAULT 'default',
|
||||
"isPinned" BOOLEAN NOT NULL DEFAULT false,
|
||||
"isArchived" BOOLEAN NOT NULL DEFAULT false,
|
||||
"type" TEXT NOT NULL DEFAULT 'text',
|
||||
"checkItems" TEXT,
|
||||
"labels" TEXT,
|
||||
"images" TEXT,
|
||||
"reminder" DATETIME,
|
||||
"isMarkdown" BOOLEAN NOT NULL DEFAULT false,
|
||||
"order" INTEGER NOT NULL DEFAULT 0,
|
||||
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" DATETIME NOT NULL
|
||||
);
|
||||
INSERT INTO "new_Note" ("checkItems", "color", "content", "createdAt", "id", "images", "isArchived", "isPinned", "labels", "order", "reminder", "title", "type", "updatedAt") SELECT "checkItems", "color", "content", "createdAt", "id", "images", "isArchived", "isPinned", "labels", "order", "reminder", "title", "type", "updatedAt" FROM "Note";
|
||||
DROP TABLE "Note";
|
||||
ALTER TABLE "new_Note" RENAME TO "Note";
|
||||
CREATE INDEX "Note_isPinned_idx" ON "Note"("isPinned");
|
||||
CREATE INDEX "Note_isArchived_idx" ON "Note"("isArchived");
|
||||
CREATE INDEX "Note_order_idx" ON "Note"("order");
|
||||
CREATE INDEX "Note_reminder_idx" ON "Note"("reminder");
|
||||
PRAGMA foreign_keys=ON;
|
||||
PRAGMA defer_foreign_keys=OFF;
|
||||
@@ -0,0 +1,3 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "Note" ADD COLUMN "reminderLocation" TEXT;
|
||||
ALTER TABLE "Note" ADD COLUMN "reminderRecurrence" TEXT;
|
||||
@@ -0,0 +1,90 @@
|
||||
-- CreateTable
|
||||
CREATE TABLE "User" (
|
||||
"id" TEXT NOT NULL PRIMARY KEY,
|
||||
"name" TEXT,
|
||||
"email" TEXT NOT NULL,
|
||||
"emailVerified" DATETIME,
|
||||
"image" TEXT,
|
||||
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" DATETIME NOT NULL
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Account" (
|
||||
"userId" TEXT NOT NULL,
|
||||
"type" TEXT NOT NULL,
|
||||
"provider" TEXT NOT NULL,
|
||||
"providerAccountId" TEXT NOT NULL,
|
||||
"refresh_token" TEXT,
|
||||
"access_token" TEXT,
|
||||
"expires_at" INTEGER,
|
||||
"token_type" TEXT,
|
||||
"scope" TEXT,
|
||||
"id_token" TEXT,
|
||||
"session_state" TEXT,
|
||||
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" DATETIME NOT NULL,
|
||||
|
||||
PRIMARY KEY ("provider", "providerAccountId"),
|
||||
CONSTRAINT "Account_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User" ("id") ON DELETE CASCADE ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Session" (
|
||||
"sessionToken" TEXT NOT NULL,
|
||||
"userId" TEXT NOT NULL,
|
||||
"expires" DATETIME NOT NULL,
|
||||
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" DATETIME NOT NULL,
|
||||
CONSTRAINT "Session_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User" ("id") ON DELETE CASCADE ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "VerificationToken" (
|
||||
"identifier" TEXT NOT NULL,
|
||||
"token" TEXT NOT NULL,
|
||||
"expires" DATETIME NOT NULL,
|
||||
|
||||
PRIMARY KEY ("identifier", "token")
|
||||
);
|
||||
|
||||
-- RedefineTables
|
||||
PRAGMA defer_foreign_keys=ON;
|
||||
PRAGMA foreign_keys=OFF;
|
||||
CREATE TABLE "new_Note" (
|
||||
"id" TEXT NOT NULL PRIMARY KEY,
|
||||
"title" TEXT,
|
||||
"content" TEXT NOT NULL,
|
||||
"color" TEXT NOT NULL DEFAULT 'default',
|
||||
"isPinned" BOOLEAN NOT NULL DEFAULT false,
|
||||
"isArchived" BOOLEAN NOT NULL DEFAULT false,
|
||||
"type" TEXT NOT NULL DEFAULT 'text',
|
||||
"checkItems" TEXT,
|
||||
"labels" TEXT,
|
||||
"images" TEXT,
|
||||
"reminder" DATETIME,
|
||||
"reminderRecurrence" TEXT,
|
||||
"reminderLocation" TEXT,
|
||||
"isMarkdown" BOOLEAN NOT NULL DEFAULT false,
|
||||
"userId" TEXT,
|
||||
"order" INTEGER NOT NULL DEFAULT 0,
|
||||
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" DATETIME NOT NULL,
|
||||
CONSTRAINT "Note_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User" ("id") ON DELETE CASCADE ON UPDATE CASCADE
|
||||
);
|
||||
INSERT INTO "new_Note" ("checkItems", "color", "content", "createdAt", "id", "images", "isArchived", "isMarkdown", "isPinned", "labels", "order", "reminder", "reminderLocation", "reminderRecurrence", "title", "type", "updatedAt") SELECT "checkItems", "color", "content", "createdAt", "id", "images", "isArchived", "isMarkdown", "isPinned", "labels", "order", "reminder", "reminderLocation", "reminderRecurrence", "title", "type", "updatedAt" FROM "Note";
|
||||
DROP TABLE "Note";
|
||||
ALTER TABLE "new_Note" RENAME TO "Note";
|
||||
CREATE INDEX "Note_isPinned_idx" ON "Note"("isPinned");
|
||||
CREATE INDEX "Note_isArchived_idx" ON "Note"("isArchived");
|
||||
CREATE INDEX "Note_order_idx" ON "Note"("order");
|
||||
CREATE INDEX "Note_reminder_idx" ON "Note"("reminder");
|
||||
CREATE INDEX "Note_userId_idx" ON "Note"("userId");
|
||||
PRAGMA foreign_keys=ON;
|
||||
PRAGMA defer_foreign_keys=OFF;
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "User_email_key" ON "User"("email");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Session_sessionToken_key" ON "Session"("sessionToken");
|
||||
@@ -0,0 +1,16 @@
|
||||
-- CreateTable
|
||||
CREATE TABLE "Label" (
|
||||
"id" TEXT NOT NULL PRIMARY KEY,
|
||||
"name" TEXT NOT NULL,
|
||||
"color" TEXT NOT NULL DEFAULT 'gray',
|
||||
"userId" TEXT,
|
||||
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" DATETIME NOT NULL,
|
||||
CONSTRAINT "Label_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User" ("id") ON DELETE CASCADE ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Label_name_key" ON "Label"("name");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Label_userId_idx" ON "Label"("userId");
|
||||
@@ -0,0 +1,35 @@
|
||||
-- RedefineTables
|
||||
PRAGMA defer_foreign_keys=ON;
|
||||
PRAGMA foreign_keys=OFF;
|
||||
CREATE TABLE "new_Note" (
|
||||
"id" TEXT NOT NULL PRIMARY KEY,
|
||||
"title" TEXT,
|
||||
"content" TEXT NOT NULL,
|
||||
"color" TEXT NOT NULL DEFAULT 'default',
|
||||
"isPinned" BOOLEAN NOT NULL DEFAULT false,
|
||||
"isArchived" BOOLEAN NOT NULL DEFAULT false,
|
||||
"type" TEXT NOT NULL DEFAULT 'text',
|
||||
"checkItems" TEXT,
|
||||
"labels" TEXT,
|
||||
"images" TEXT,
|
||||
"reminder" DATETIME,
|
||||
"isReminderDone" BOOLEAN NOT NULL DEFAULT false,
|
||||
"reminderRecurrence" TEXT,
|
||||
"reminderLocation" TEXT,
|
||||
"isMarkdown" BOOLEAN NOT NULL DEFAULT false,
|
||||
"userId" TEXT,
|
||||
"order" INTEGER NOT NULL DEFAULT 0,
|
||||
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" DATETIME NOT NULL,
|
||||
CONSTRAINT "Note_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User" ("id") ON DELETE CASCADE ON UPDATE CASCADE
|
||||
);
|
||||
INSERT INTO "new_Note" ("checkItems", "color", "content", "createdAt", "id", "images", "isArchived", "isMarkdown", "isPinned", "labels", "order", "reminder", "reminderLocation", "reminderRecurrence", "title", "type", "updatedAt", "userId") SELECT "checkItems", "color", "content", "createdAt", "id", "images", "isArchived", "isMarkdown", "isPinned", "labels", "order", "reminder", "reminderLocation", "reminderRecurrence", "title", "type", "updatedAt", "userId" FROM "Note";
|
||||
DROP TABLE "Note";
|
||||
ALTER TABLE "new_Note" RENAME TO "Note";
|
||||
CREATE INDEX "Note_isPinned_idx" ON "Note"("isPinned");
|
||||
CREATE INDEX "Note_isArchived_idx" ON "Note"("isArchived");
|
||||
CREATE INDEX "Note_order_idx" ON "Note"("order");
|
||||
CREATE INDEX "Note_reminder_idx" ON "Note"("reminder");
|
||||
CREATE INDEX "Note_userId_idx" ON "Note"("userId");
|
||||
PRAGMA foreign_keys=ON;
|
||||
PRAGMA defer_foreign_keys=OFF;
|
||||
@@ -0,0 +1,2 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "Note" ADD COLUMN "links" TEXT;
|
||||
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
Warnings:
|
||||
|
||||
- A unique constraint covering the columns `[name,userId]` on the table `Label` will be added. If there are existing duplicate values, this will fail.
|
||||
|
||||
*/
|
||||
-- DropIndex
|
||||
DROP INDEX "Label_name_key";
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "User" ADD COLUMN "password" TEXT;
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "Label_name_userId_key" ON "Label"("name", "userId");
|
||||
@@ -0,0 +1,2 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "Note" ADD COLUMN "embedding" TEXT;
|
||||
@@ -0,0 +1,2 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "UserAISettings" ADD COLUMN "showRecentNotes" BOOLEAN NOT NULL DEFAULT false;
|
||||
@@ -0,0 +1,7 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "Note" ADD COLUMN "autoGenerated" BOOLEAN;
|
||||
ALTER TABLE "Note" ADD COLUMN "aiProvider" TEXT;
|
||||
ALTER TABLE "Note" ADD COLUMN "aiConfidence" INTEGER;
|
||||
ALTER TABLE "Note" ADD COLUMN "language" TEXT;
|
||||
ALTER TABLE "Note" ADD COLUMN "languageConfidence" REAL;
|
||||
ALTER TABLE "Note" ADD COLUMN "lastAiAnalysis" DATETIME;
|
||||
@@ -0,0 +1,26 @@
|
||||
-- CreateTable
|
||||
CREATE TABLE "AiFeedback" (
|
||||
"id" TEXT NOT NULL PRIMARY KEY,
|
||||
"noteId" TEXT NOT NULL,
|
||||
"userId" TEXT,
|
||||
"feedbackType" TEXT NOT NULL,
|
||||
"feature" TEXT NOT NULL,
|
||||
"originalContent" TEXT NOT NULL,
|
||||
"correctedContent" TEXT,
|
||||
"metadata" TEXT,
|
||||
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY ("noteId") REFERENCES "Note"("id") ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "AiFeedback_noteId_idx" ON "AiFeedback"("noteId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "AiFeedback_userId_idx" ON "AiFeedback"("userId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "AiFeedback_feature_idx" ON "AiFeedback"("feature");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "AiFeedback_createdAt_idx" ON "AiFeedback"("createdAt");
|
||||
@@ -0,0 +1,4 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "UserAISettings" ADD COLUMN "emailNotifications" BOOLEAN NOT NULL DEFAULT false;
|
||||
ALTER TABLE "UserAISettings" ADD COLUMN "desktopNotifications" BOOLEAN NOT NULL DEFAULT false;
|
||||
ALTER TABLE "UserAISettings" ADD COLUMN "anonymousAnalytics" BOOLEAN NOT NULL DEFAULT false;
|
||||
3
memento-note/prisma/migrations/migration_lock.toml
Normal file
3
memento-note/prisma/migrations/migration_lock.toml
Normal file
@@ -0,0 +1,3 @@
|
||||
# Please do not edit this file manually
|
||||
# It should be added in your version-control system (i.e. Git)
|
||||
provider = "postgresql"
|
||||
240
memento-note/prisma/schema.prisma
Normal file
240
memento-note/prisma/schema.prisma
Normal file
@@ -0,0 +1,240 @@
|
||||
generator client {
|
||||
provider = "prisma-client-js"
|
||||
output = "./client-generated"
|
||||
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
|
||||
accounts Account[]
|
||||
aiFeedback AiFeedback[]
|
||||
labels Label[]
|
||||
memoryEchoInsights MemoryEchoInsight[]
|
||||
notes Note[]
|
||||
sentShares NoteShare[] @relation("SentShares")
|
||||
receivedShares NoteShare[] @relation("ReceivedShares")
|
||||
notebooks Notebook[]
|
||||
sessions Session[]
|
||||
aiSettings UserAISettings?
|
||||
}
|
||||
|
||||
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[]
|
||||
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)
|
||||
type String @default("text")
|
||||
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")
|
||||
embedding String?
|
||||
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")
|
||||
|
||||
@@index([isPinned])
|
||||
@@index([isArchived])
|
||||
@@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(false)
|
||||
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])
|
||||
}
|
||||
Reference in New Issue
Block a user