/** * rNotes Automerge document schemas. * * Granularity: one Automerge document per notebook. * DocId format: {space}:notes:notebooks:{notebookId} * * The shape matches the PG→Automerge migration adapter * (server/local-first/migration/pg-to-automerge.ts:notesMigration) * and the client-side NotebookDoc type in folk-notes-app.ts. */ import type { DocSchema } from '../../shared/local-first/document'; // ── Document types ── export interface NoteItem { id: string; notebookId: string; authorId: string | null; title: string; content: string; contentPlain: string; type: 'NOTE' | 'CLIP' | 'BOOKMARK' | 'CODE' | 'IMAGE' | 'FILE' | 'AUDIO'; url: string | null; language: string | null; fileUrl: string | null; mimeType: string | null; fileSize: number | null; duration: number | null; isPinned: boolean; sortOrder: number; tags: string[]; createdAt: number; updatedAt: number; } export interface NotebookMeta { id: string; title: string; slug: string; description: string; coverColor: string; isPublic: boolean; createdAt: number; updatedAt: number; } export interface NotebookDoc { meta: { module: string; collection: string; version: number; spaceSlug: string; createdAt: number; }; notebook: NotebookMeta; items: Record; } // ── Schema registration ── export const notebookSchema: DocSchema = { module: 'notes', collection: 'notebooks', version: 1, init: (): NotebookDoc => ({ meta: { module: 'notes', collection: 'notebooks', version: 1, spaceSlug: '', createdAt: Date.now(), }, notebook: { id: '', title: 'Untitled Notebook', slug: '', description: '', coverColor: '#3b82f6', isPublic: false, createdAt: Date.now(), updatedAt: Date.now(), }, items: {}, }), }; // ── Helpers ── /** Generate a docId for a notebook. */ export function notebookDocId(space: string, notebookId: string) { return `${space}:notes:notebooks:${notebookId}` as const; } /** Create a fresh NoteItem with defaults. */ export function createNoteItem( id: string, notebookId: string, title: string, opts: Partial = {}, ): NoteItem { const now = Date.now(); return { id, notebookId, authorId: null, title, content: '', contentPlain: '', type: 'NOTE', url: null, language: null, fileUrl: null, mimeType: null, fileSize: null, duration: null, isPinned: false, sortOrder: 0, tags: [], createdAt: now, updatedAt: now, ...opts, }; }