/** * rChoices Automerge document schemas. * * Stores collaborative voting sessions with real-time vote sync. * Canvas-based choice shapes remain in community-store; this doc * handles standalone multiplayer sessions via the dashboard. * * DocId format: {space}:choices:sessions */ import type { DocSchema } from '../../shared/local-first/document'; // ── Document types ── export interface ChoiceOption { id: string; label: string; color: string; } export interface ChoiceSession { id: string; title: string; type: 'vote' | 'rank' | 'score'; /** 'vote' mode: plurality, approval, or single */ mode?: 'plurality' | 'approval' | 'single'; options: ChoiceOption[]; createdBy: string | null; createdAt: number; closed: boolean; } export interface ChoiceVote { participantDid: string; /** For 'vote': optionId → 1 (selected). For 'rank': optionId → rank position. For 'score': optionId → 0-100. */ choices: Record; updatedAt: number; } export interface ChoicesDoc { meta: { module: string; collection: string; version: number; spaceSlug: string; createdAt: number; }; sessions: Record; /** Keyed by `${sessionId}:${participantDid}` */ votes: Record; } // ── Schema registration ── export const choicesSchema: DocSchema = { module: 'choices', collection: 'sessions', version: 1, init: (): ChoicesDoc => ({ meta: { module: 'choices', collection: 'sessions', version: 1, spaceSlug: '', createdAt: Date.now(), }, sessions: {}, votes: {}, }), migrate: (doc: any, _fromVersion: number) => { if (!doc.sessions) doc.sessions = {}; if (!doc.votes) doc.votes = {}; doc.meta.version = 1; return doc; }, }; // ── Helpers ── export function choicesDocId(space: string) { return `${space}:choices:sessions` as const; }