/** * rDesign Automerge document schemas. * * Syncs full design state (pages, frames) per space via CRDT. * Source of truth for collaborative editing — Scribus state is * periodically reconciled via sla-bridge.ts. * * DocId format: {space}:design:doc */ import type { DocSchema } from '../../shared/local-first/document'; export interface DesignFrame { id: string; type: 'text' | 'image' | 'rect' | 'ellipse'; page: number; x: number; y: number; width: number; height: number; text?: string; fontSize?: number; fontName?: string; imageUrl?: string; imagePath?: string; shapeType?: string; fill?: string; stroke?: string; strokeWidth?: number; createdBy?: string; createdAt?: number; updatedAt?: number; } export interface DesignPage { id: string; number: number; width: number; height: number; margins: number; background?: string; } export interface DesignDoc { meta: { module: string; collection: string; version: number; spaceSlug: string; createdAt: number; }; document: { title: string; unit: string; pages: Record; frames: Record; }; } export const designSchema: DocSchema = { module: 'design', collection: 'doc', version: 2, init: (): DesignDoc => ({ meta: { module: 'design', collection: 'doc', version: 2, spaceSlug: '', createdAt: Date.now() }, document: { title: 'Untitled Design', unit: 'mm', pages: {}, frames: {}, }, }), migrate: (doc: any) => { // v1 → v2: migrate from LinkedProject schema to full design state if (doc.linkedProjects && !doc.document) { doc.document = { title: 'Untitled Design', unit: 'mm', pages: {}, frames: {} }; delete doc.linkedProjects; } if (!doc.document) doc.document = { title: 'Untitled Design', unit: 'mm', pages: {}, frames: {} }; if (!doc.document.pages) doc.document.pages = {}; if (!doc.document.frames) doc.document.frames = {}; doc.meta.version = 2; return doc; }, }; export function designDocId(space: string) { return `${space}:design:doc` as const; }