171 lines
3.6 KiB
TypeScript
171 lines
3.6 KiB
TypeScript
/**
|
|
* rTasks Automerge document schemas.
|
|
*
|
|
* Granularity: one Automerge document per board/workspace.
|
|
* DocId format: {space}:tasks:boards:{boardId}
|
|
*/
|
|
|
|
import type { DocSchema } from '../../shared/local-first/document';
|
|
|
|
// ── Document types ──
|
|
|
|
export interface ClickUpTaskMeta {
|
|
taskId: string; // ClickUp task ID
|
|
listId: string; // ClickUp list ID
|
|
url: string; // Direct link to ClickUp task
|
|
lastSyncedAt: number;
|
|
syncStatus: 'synced' | 'pending-push' | 'conflict' | 'push-failed';
|
|
contentHash: string; // SHA of title+desc+status+priority at last sync
|
|
remoteHash?: string; // ClickUp state hash at last pull
|
|
}
|
|
|
|
export interface TaskItem {
|
|
id: string;
|
|
spaceId: string;
|
|
title: string;
|
|
description: string;
|
|
status: string;
|
|
priority: string | null;
|
|
labels: string[];
|
|
assigneeId: string | null;
|
|
createdBy: string | null;
|
|
sortOrder: number;
|
|
createdAt: number;
|
|
updatedAt: number;
|
|
clickup?: ClickUpTaskMeta;
|
|
}
|
|
|
|
export interface ClickUpBoardMeta {
|
|
listId: string; // ClickUp list this board mirrors
|
|
listName: string;
|
|
workspaceId: string; // ClickUp team ID
|
|
webhookId?: string; // For teardown on disconnect
|
|
syncEnabled: boolean;
|
|
statusMap: Record<string, string>; // rTasks → ClickUp
|
|
reverseStatusMap: Record<string, string>; // ClickUp → rTasks
|
|
}
|
|
|
|
export interface BoardMeta {
|
|
id: string;
|
|
name: string;
|
|
slug: string;
|
|
description: string;
|
|
icon: string | null;
|
|
ownerDid: string | null;
|
|
statuses: string[];
|
|
labels: string[];
|
|
createdAt: number;
|
|
updatedAt: number;
|
|
clickup?: ClickUpBoardMeta;
|
|
}
|
|
|
|
export interface BoardDoc {
|
|
meta: {
|
|
module: string;
|
|
collection: string;
|
|
version: number;
|
|
spaceSlug: string;
|
|
createdAt: number;
|
|
};
|
|
board: BoardMeta;
|
|
tasks: Record<string, TaskItem>;
|
|
}
|
|
|
|
// ── Schema registration ──
|
|
|
|
export const boardSchema: DocSchema<BoardDoc> = {
|
|
module: 'tasks',
|
|
collection: 'boards',
|
|
version: 1,
|
|
init: (): BoardDoc => ({
|
|
meta: {
|
|
module: 'tasks',
|
|
collection: 'boards',
|
|
version: 1,
|
|
spaceSlug: '',
|
|
createdAt: Date.now(),
|
|
},
|
|
board: {
|
|
id: '',
|
|
name: 'Untitled Board',
|
|
slug: '',
|
|
description: '',
|
|
icon: null,
|
|
ownerDid: null,
|
|
statuses: ['TODO', 'IN_PROGRESS', 'DONE'],
|
|
labels: [],
|
|
createdAt: Date.now(),
|
|
updatedAt: Date.now(),
|
|
},
|
|
tasks: {},
|
|
}),
|
|
};
|
|
|
|
// ── Helpers ──
|
|
|
|
export function boardDocId(space: string, boardId: string) {
|
|
return `${space}:tasks:boards:${boardId}` as const;
|
|
}
|
|
|
|
// ── ClickUp connection doc (one per space) ──
|
|
|
|
export interface ClickUpConnectionDoc {
|
|
meta: {
|
|
module: string;
|
|
collection: string;
|
|
version: number;
|
|
spaceSlug: string;
|
|
createdAt: number;
|
|
};
|
|
clickup?: {
|
|
accessToken: string; // OAuth token or personal API token
|
|
teamId: string;
|
|
teamName: string;
|
|
connectedAt: number;
|
|
webhookSecret: string; // HMAC secret for webhook validation
|
|
};
|
|
}
|
|
|
|
export const clickupConnectionSchema: DocSchema<ClickUpConnectionDoc> = {
|
|
module: 'tasks',
|
|
collection: 'clickup-connection',
|
|
version: 1,
|
|
init: (): ClickUpConnectionDoc => ({
|
|
meta: {
|
|
module: 'tasks',
|
|
collection: 'clickup-connection',
|
|
version: 1,
|
|
spaceSlug: '',
|
|
createdAt: Date.now(),
|
|
},
|
|
}),
|
|
};
|
|
|
|
export function clickupConnectionDocId(space: string) {
|
|
return `${space}:tasks:clickup-connection` as const;
|
|
}
|
|
|
|
export function createTaskItem(
|
|
id: string,
|
|
spaceId: string,
|
|
title: string,
|
|
opts: Partial<TaskItem> = {},
|
|
): TaskItem {
|
|
const now = Date.now();
|
|
return {
|
|
id,
|
|
spaceId,
|
|
title,
|
|
description: '',
|
|
status: 'TODO',
|
|
priority: null,
|
|
labels: [],
|
|
assigneeId: null,
|
|
createdBy: null,
|
|
sortOrder: 0,
|
|
createdAt: now,
|
|
updatedAt: now,
|
|
...opts,
|
|
};
|
|
}
|