89 lines
1.7 KiB
TypeScript
89 lines
1.7 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';
|
|
|
|
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 ScheduleDoc {
|
|
meta: {
|
|
module: string;
|
|
collection: string;
|
|
version: number;
|
|
spaceSlug: string;
|
|
createdAt: number;
|
|
};
|
|
jobs: Record<string, ScheduleJob>;
|
|
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: {},
|
|
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;
|