rspace-online/modules/rschedule/schemas.ts

122 lines
2.6 KiB
TypeScript

/**
* rSchedule Automerge document schemas.
*
* Granularity: one Automerge document per space (all jobs + execution log).
* DocId format: {space}:schedule:jobs
*/
import type { DocSchema } from '../../shared/local-first/document';
// ── Document types ──
export type ActionType = 'email' | 'webhook' | 'calendar-event' | 'broadcast' | 'backlog-briefing' | 'calendar-reminder';
export interface ScheduleJob {
id: string;
name: string;
description: string;
enabled: boolean;
// Timing
cronExpression: string;
timezone: string;
// Action
actionType: ActionType;
actionConfig: Record<string, unknown>;
// Execution state
lastRunAt: number | null;
lastRunStatus: 'success' | 'error' | null;
lastRunMessage: string;
nextRunAt: number | null;
runCount: number;
// Metadata
createdBy: string;
createdAt: number;
updatedAt: number;
}
export interface ExecutionLogEntry {
id: string;
jobId: string;
status: 'success' | 'error';
message: string;
durationMs: number;
timestamp: number;
}
export interface Reminder {
id: string;
title: string;
description: string;
remindAt: number; // epoch ms — when to fire
allDay: boolean;
timezone: string;
notifyEmail: string | null;
notified: boolean; // has email been sent?
completed: boolean; // dismissed by user?
// Cross-module reference (null for free-form reminders)
sourceModule: string | null; // "rwork", "rnotes", etc.
sourceEntityId: string | null;
sourceLabel: string | null; // "rWork Task"
sourceColor: string | null; // "#f97316"
// Optional recurrence
cronExpression: string | null;
// Link to rCal event (bidirectional)
calendarEventId: string | null;
createdBy: string;
createdAt: number;
updatedAt: number;
}
export interface ScheduleDoc {
meta: {
module: string;
collection: string;
version: number;
spaceSlug: string;
createdAt: number;
};
jobs: Record<string, ScheduleJob>;
reminders: Record<string, Reminder>;
log: ExecutionLogEntry[];
}
// ── Schema registration ──
export const scheduleSchema: DocSchema<ScheduleDoc> = {
module: 'schedule',
collection: 'jobs',
version: 1,
init: (): ScheduleDoc => ({
meta: {
module: 'schedule',
collection: 'jobs',
version: 1,
spaceSlug: '',
createdAt: Date.now(),
},
jobs: {},
reminders: {},
log: [],
}),
};
// ── Helpers ──
export function scheduleDocId(space: string) {
return `${space}:schedule:jobs` as const;
}
/** Maximum execution log entries to keep per doc */
export const MAX_LOG_ENTRIES = 200;
/** Maximum reminders per space */
export const MAX_REMINDERS = 500;