rspace-online/modules/rtime/schemas.ts

195 lines
4.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* rTime Automerge document schemas.
*
* DocId formats:
* {space}:rtime:commitments → CommitmentsDoc (commitment pool)
* {space}:rtime:tasks → TasksDoc (weaving: tasks, connections, exec states)
*/
import type { DocSchema } from '../../shared/local-first/document';
// ── Skill type ──
export type Skill = 'facilitation' | 'design' | 'tech' | 'outreach' | 'logistics';
export const SKILL_COLORS: Record<Skill, string> = {
facilitation: '#8b5cf6',
design: '#ec4899',
tech: '#3b82f6',
outreach: '#10b981',
logistics: '#f59e0b',
};
export const SKILL_LABELS: Record<Skill, string> = {
facilitation: 'Facilitation',
design: 'Design',
tech: 'Tech',
outreach: 'Outreach',
logistics: 'Logistics',
};
// ── Commitment ──
export interface Commitment {
id: string;
memberName: string;
hours: number; // 110
skill: Skill;
desc: string;
cyclosMemberId?: string;
createdAt: number;
intentId?: string; // links commitment to its intent
status?: 'active' | 'matched' | 'settled' | 'withdrawn';
ownerDid?: string; // DID of the commitment creator (for notifications)
}
// ── Task / Connection / ExecState ──
export interface Task {
id: string;
name: string;
description: string;
needs: Record<string, number>; // skill → hours needed
links: { label: string; url: string }[];
notes: string;
intentFrameId?: string; // links task to solver result that spawned it
}
export interface Connection {
id: string;
fromCommitmentId: string;
toTaskId: string;
skill: string;
hours: number; // hours allocated in this connection
status: 'proposed' | 'committed'; // approval state
}
export interface ExecState {
taskId: string;
steps: Record<string, 'pending' | 'active' | 'done'>;
launchedAt?: number;
}
// ── Documents ──
export interface CommitmentsDoc {
meta: {
module: string;
collection: string;
version: number;
spaceSlug: string;
createdAt: number;
seeded?: boolean;
};
items: Record<string, Commitment>;
}
export interface TasksDoc {
meta: {
module: string;
collection: string;
version: number;
spaceSlug: string;
createdAt: number;
};
tasks: Record<string, Task>;
connections: Record<string, Connection>;
execStates: Record<string, ExecState>;
}
// ── External Time Log (backlog-md integration) ──
export type ExternalTimeLogStatus = 'pending' | 'commitment_created' | 'settled';
export interface ExternalTimeLog {
id: string;
backlogTaskId: string;
backlogTaskTitle: string;
memberName: string;
memberId?: string; // DID
hours: number;
skill: Skill;
note?: string;
loggedAt: number; // unix ms (when work was done)
importedAt: number; // unix ms (when imported to rTime)
status: ExternalTimeLogStatus;
commitmentId?: string; // auto-created commitment ID
}
export interface ExternalTimeLogsDoc {
meta: {
module: string;
collection: string;
version: number;
spaceSlug: string;
createdAt: number;
};
logs: Record<string, ExternalTimeLog>;
}
// ── DocId helpers ──
export function commitmentsDocId(space: string) {
return `${space}:rtime:commitments` as const;
}
export function tasksDocId(space: string) {
return `${space}:rtime:tasks` as const;
}
export function externalTimeLogsDocId(space: string) {
return `${space}:rtime:external-time-logs` as const;
}
// ── Schema registrations ──
export const commitmentsSchema: DocSchema<CommitmentsDoc> = {
module: 'rtime',
collection: 'commitments',
version: 1,
init: (): CommitmentsDoc => ({
meta: {
module: 'rtime',
collection: 'commitments',
version: 1,
spaceSlug: '',
createdAt: Date.now(),
},
items: {},
}),
};
export const tasksSchema: DocSchema<TasksDoc> = {
module: 'rtime',
collection: 'tasks',
version: 1,
init: (): TasksDoc => ({
meta: {
module: 'rtime',
collection: 'tasks',
version: 1,
spaceSlug: '',
createdAt: Date.now(),
},
tasks: {},
connections: {},
execStates: {},
}),
};
export const externalTimeLogsSchema: DocSchema<ExternalTimeLogsDoc> = {
module: 'rtime',
collection: 'external-time-logs',
version: 1,
init: (): ExternalTimeLogsDoc => ({
meta: {
module: 'rtime',
collection: 'external-time-logs',
version: 1,
spaceSlug: '',
createdAt: Date.now(),
},
logs: {},
}),
};