147 lines
2.8 KiB
TypeScript
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;
|
|
}
|