rspace-online/modules/rinbox/schemas.ts

147 lines
2.8 KiB
TypeScript

/**
* rInbox Automerge document schemas.
*
* Granularity: one Automerge document per mailbox.
* DocId format: {space}:inbox:mailboxes:{mailboxId}
*
* IMAP sync stays server-side — Automerge holds thread/comment state.
*/
import type { DocSchema } from '../../shared/local-first/document';
// ── Document types ──
export interface MailboxMember {
id: string;
mailboxId: string;
userId: string;
role: string;
joinedAt: number;
}
export interface ThreadComment {
id: string;
threadId: string;
authorId: string;
body: string;
mentions: string[];
createdAt: number;
}
export interface ThreadItem {
id: string;
mailboxId: string;
messageId: string | null;
subject: string;
fromAddress: string | null;
fromName: string | null;
toAddresses: string[];
ccAddresses: string[];
bodyText: string;
bodyHtml: string;
tags: string[];
status: string;
isRead: boolean;
isStarred: boolean;
assignedTo: string | null;
hasAttachments: boolean;
receivedAt: number;
createdAt: number;
comments: ThreadComment[];
}
export interface ApprovalSignature {
id: string;
approvalId: string;
signerId: string;
vote: string;
signedAt: number;
}
export interface ApprovalItem {
id: string;
mailboxId: string;
threadId: string | null;
authorId: string;
subject: string;
bodyText: string;
bodyHtml: string;
toAddresses: string[];
ccAddresses: string[];
status: string;
requiredSignatures: number;
safeTxHash: string | null;
createdAt: number;
resolvedAt: number;
signatures: ApprovalSignature[];
}
export interface MailboxMeta {
id: string;
workspaceId: string | null;
slug: string;
name: string;
email: string;
description: string;
visibility: string;
ownerDid: string;
safeAddress: string | null;
safeChainId: number | null;
approvalThreshold: number;
createdAt: number;
}
export interface MailboxDoc {
meta: {
module: string;
collection: string;
version: number;
spaceSlug: string;
createdAt: number;
};
mailbox: MailboxMeta;
members: MailboxMember[];
threads: Record<string, ThreadItem>;
approvals: Record<string, ApprovalItem>;
}
// ── Schema registration ──
export const mailboxSchema: DocSchema<MailboxDoc> = {
module: 'inbox',
collection: 'mailboxes',
version: 1,
init: (): MailboxDoc => ({
meta: {
module: 'inbox',
collection: 'mailboxes',
version: 1,
spaceSlug: '',
createdAt: Date.now(),
},
mailbox: {
id: '',
workspaceId: null,
slug: '',
name: '',
email: '',
description: '',
visibility: 'private',
ownerDid: '',
safeAddress: null,
safeChainId: null,
approvalThreshold: 1,
createdAt: Date.now(),
},
members: [],
threads: {},
approvals: {},
}),
};
// ── Helpers ──
export function mailboxDocId(space: string, mailboxId: string) {
return `${space}:inbox:mailboxes:${mailboxId}` as const;
}