rspace-online/modules/rflows/schemas.ts

94 lines
2.5 KiB
TypeScript

/**
* rFlows Automerge document schemas.
*
* Granularity: one Automerge document per space (flow associations).
* DocId format: {space}:flows:data
*
* v1: space-flow associations only
* v2: adds canvasFlows (full node data) and activeFlowId
* v3: adds mortgagePositions and reinvestmentPositions
* v4: adds budgetSegments, budgetAllocations, budgetTotalAmount
*/
import type { DocSchema } from '../../shared/local-first/document';
import type { FlowNode, MortgagePosition, ReinvestmentPosition } from './lib/types';
// ── Document types ──
export interface SpaceFlow {
id: string;
spaceSlug: string;
flowId: string;
addedBy: string | null;
createdAt: number;
}
export interface CanvasFlow {
id: string;
name: string;
nodes: FlowNode[];
createdAt: number;
updatedAt: number;
createdBy: string | null;
}
export interface FlowsDoc {
meta: {
module: string;
collection: string;
version: number;
spaceSlug: string;
createdAt: number;
};
spaceFlows: Record<string, SpaceFlow>;
canvasFlows: Record<string, CanvasFlow>;
activeFlowId: string;
mortgagePositions: Record<string, MortgagePosition>;
reinvestmentPositions: Record<string, ReinvestmentPosition>;
budgetSegments: Record<string, { name: string; color: string; createdBy: string | null }>;
budgetAllocations: Record<string, { participantDid: string; allocations: Record<string, number>; updatedAt: number }>;
budgetTotalAmount: number;
}
// ── Schema registration ──
export const flowsSchema: DocSchema<FlowsDoc> = {
module: 'flows',
collection: 'data',
version: 4,
init: (): FlowsDoc => ({
meta: {
module: 'flows',
collection: 'data',
version: 4,
spaceSlug: '',
createdAt: Date.now(),
},
spaceFlows: {},
canvasFlows: {},
activeFlowId: '',
mortgagePositions: {},
reinvestmentPositions: {},
budgetSegments: {},
budgetAllocations: {},
budgetTotalAmount: 0,
}),
migrate: (doc: any, _fromVersion: number) => {
if (!doc.canvasFlows) doc.canvasFlows = {};
if (!doc.activeFlowId) doc.activeFlowId = '';
if (!doc.mortgagePositions) doc.mortgagePositions = {};
if (!doc.reinvestmentPositions) doc.reinvestmentPositions = {};
if (!doc.budgetSegments) doc.budgetSegments = {};
if (!doc.budgetAllocations) doc.budgetAllocations = {};
if (doc.budgetTotalAmount === undefined) doc.budgetTotalAmount = 0;
doc.meta.version = 4;
return doc;
},
};
// ── Helpers ──
export function flowsDocId(space: string) {
return `${space}:flows:data` as const;
}