import prisma from '@/lib/prisma' import { asArray } from '@/lib/utils' import type { NoteHistoryEntry } from '@/lib/types' const HISTORY_TRACKED_FIELDS = [ 'title', 'content', 'color', 'isPinned', 'isArchived', 'type', 'checkItems', 'labels', 'images', 'links', 'isMarkdown', 'size', 'notebookId', ] as const export function shouldCaptureHistorySnapshot(data: Record): boolean { return HISTORY_TRACKED_FIELDS.some((field) => field in data) } export async function isNoteHistoryEnabledForUser(userId: string): Promise { const settings = await prisma.userAISettings.findUnique({ where: { userId }, select: { noteHistory: true }, }) return settings?.noteHistory === true } export async function createNoteHistorySnapshot({ noteId, userId, reason, }: { noteId: string userId: string reason?: string }): Promise { const note = await prisma.note.findFirst({ where: { id: noteId, userId }, select: { id: true, userId: true, title: true, content: true, color: true, isPinned: true, isArchived: true, type: true, checkItems: true, labels: true, images: true, links: true, isMarkdown: true, size: true, notebookId: true, }, }) if (!note || !note.userId) return await prisma.$transaction(async (tx) => { const lastVersionEntry = await (tx as any).noteHistory.findFirst({ where: { noteId }, orderBy: { version: 'desc' }, select: { version: true }, }) const nextVersion = ((lastVersionEntry?.version as number | undefined) ?? 0) + 1 await (tx as any).noteHistory.create({ data: { noteId: note.id, userId: note.userId, version: nextVersion, reason: reason ?? null, title: note.title, content: note.content, color: note.color, isPinned: note.isPinned, isArchived: note.isArchived, type: note.type, checkItems: note.checkItems, labels: note.labels, images: note.images, links: note.links, isMarkdown: note.isMarkdown, size: note.size, notebookId: note.notebookId, }, }) }) } export function parseNoteHistoryEntry(entry: any): NoteHistoryEntry { return { id: entry.id, noteId: entry.noteId, userId: entry.userId, version: entry.version, reason: entry.reason ?? null, title: entry.title ?? null, content: entry.content, color: entry.color, isPinned: entry.isPinned, isArchived: entry.isArchived, type: entry.type, checkItems: asArray(entry.checkItems, null as any) ?? null, labels: asArray(entry.labels) || null, images: asArray(entry.images) || null, links: asArray(entry.links) || null, isMarkdown: entry.isMarkdown, size: entry.size, notebookId: entry.notebookId ?? null, createdAt: entry.createdAt, } }