143 lines
3.6 KiB
TypeScript
143 lines
3.6 KiB
TypeScript
/**
|
|
* rCal Automerge document schemas.
|
|
*
|
|
* Granularity: one Automerge document per space (all events + sources).
|
|
* DocId format: {space}:cal:events
|
|
*/
|
|
|
|
import type { DocSchema } from '../../shared/local-first/document';
|
|
|
|
// ── Document types ──
|
|
|
|
export interface CalendarSource {
|
|
id: string;
|
|
name: string;
|
|
sourceType: string;
|
|
url: string | null;
|
|
color: string | null;
|
|
isActive: boolean;
|
|
isVisible: boolean;
|
|
syncIntervalMinutes: number | null;
|
|
lastSyncedAt: number;
|
|
ownerId: string | null;
|
|
createdAt: number;
|
|
}
|
|
|
|
export interface CalendarEvent {
|
|
id: string;
|
|
title: string;
|
|
description: string;
|
|
startTime: number;
|
|
endTime: number;
|
|
allDay: boolean;
|
|
timezone: string | null;
|
|
rrule: string | null;
|
|
status: string | null;
|
|
visibility: string | null;
|
|
sourceId: string | null;
|
|
sourceName: string | null;
|
|
sourceType: string | null;
|
|
sourceColor: string | null;
|
|
locationId: string | null;
|
|
locationName: string | null;
|
|
coordinates: { x: number; y: number } | null;
|
|
locationGranularity: string | null;
|
|
locationLat: number | null;
|
|
locationLng: number | null;
|
|
isVirtual: boolean;
|
|
virtualUrl: string | null;
|
|
virtualPlatform: string | null;
|
|
rToolSource: string | null;
|
|
rToolEntityId: string | null;
|
|
attendees: unknown[];
|
|
attendeeCount: number;
|
|
metadata: unknown | null;
|
|
createdAt: number;
|
|
updatedAt: number;
|
|
}
|
|
|
|
export interface CalendarDoc {
|
|
meta: {
|
|
module: string;
|
|
collection: string;
|
|
version: number;
|
|
spaceSlug: string;
|
|
createdAt: number;
|
|
};
|
|
sources: Record<string, CalendarSource>;
|
|
events: Record<string, CalendarEvent>;
|
|
}
|
|
|
|
// ── Schema registration ──
|
|
|
|
export const calendarSchema: DocSchema<CalendarDoc> = {
|
|
module: 'cal',
|
|
collection: 'events',
|
|
version: 1,
|
|
init: (): CalendarDoc => ({
|
|
meta: {
|
|
module: 'cal',
|
|
collection: 'events',
|
|
version: 1,
|
|
spaceSlug: '',
|
|
createdAt: Date.now(),
|
|
},
|
|
sources: {},
|
|
events: {},
|
|
}),
|
|
};
|
|
|
|
// ── KOI-Inspired Provenance (stored in CalendarEvent.metadata) ──
|
|
|
|
/** Lifecycle events following BlockScience KOI's RID pattern */
|
|
export type ProvenanceLifecycle = 'NEW' | 'UPDATE' | 'FORGET';
|
|
|
|
/** KOI-inspired provenance — stored in CalendarEvent.metadata.provenance */
|
|
export interface KnowledgeProvenance {
|
|
/** Reference identifier in "type:uuid" format, e.g. "folk-note:abc-123" */
|
|
rid: string;
|
|
/** SHA-256 hex digest of content at scheduling time */
|
|
contentHash: string | null;
|
|
/** Shape type that originated this item (e.g. "folk-note", "folk-photo") */
|
|
sourceType: string;
|
|
/** Space slug where the item lives */
|
|
sourceSpace: string;
|
|
/** KOI lifecycle event */
|
|
lifecycleEvent: ProvenanceLifecycle;
|
|
/** Original creation timestamp of the source item (epoch ms) */
|
|
originalCreatedAt: number;
|
|
/** DID or user identifier who scheduled this */
|
|
scheduledBy: string | null;
|
|
/** When the scheduling action occurred (epoch ms) */
|
|
scheduledAt: number;
|
|
}
|
|
|
|
/** Preview snapshot for email rendering — stored in metadata.itemPreview */
|
|
export interface ItemPreview {
|
|
/** First ~200 chars of content */
|
|
textPreview: string;
|
|
/** MIME type: text/markdown, image/jpeg, etc. */
|
|
mimeType: string;
|
|
/** Thumbnail URL for photos/media */
|
|
thumbnailUrl?: string;
|
|
/** Deep link back to canvas shape */
|
|
canvasUrl?: string;
|
|
/** Full serialized shape data for reconstruction */
|
|
shapeSnapshot?: Record<string, unknown>;
|
|
}
|
|
|
|
/** Typed metadata shape when CalendarEvent represents a scheduled knowledge item */
|
|
export interface ScheduledItemMetadata {
|
|
isScheduledItem: true;
|
|
provenance: KnowledgeProvenance;
|
|
itemPreview: ItemPreview;
|
|
reminderSent: boolean;
|
|
reminderSentAt: number | null;
|
|
}
|
|
|
|
// ── Helpers ──
|
|
|
|
export function calendarDocId(space: string) {
|
|
return `${space}:cal:events` as const;
|
|
}
|