rspace-online/modules/rcart/schemas.ts

148 lines
3.0 KiB
TypeScript

/**
* rCart Automerge document schemas.
*
* Two document types:
* - Catalog: one doc per space holding all catalog entries.
* DocId: {space}:cart:catalog
* - Orders: one doc per order (server-validated via Intent/Claim).
* DocId: {space}:cart:orders:{orderId}
*/
import type { DocSchema } from '../../shared/local-first/document';
// ── Document types ──
export interface CatalogEntry {
id: string;
artifactId: string;
artifact: unknown;
title: string;
productType: string | null;
requiredCapabilities: string[];
substrates: string[];
creatorId: string | null;
sourceSpace: string | null;
tags: string[];
status: string;
createdAt: number;
updatedAt: number;
}
export interface CatalogDoc {
meta: {
module: string;
collection: string;
version: number;
spaceSlug: string;
createdAt: number;
};
items: Record<string, CatalogEntry>;
}
export interface OrderMeta {
id: string;
catalogEntryId: string;
artifactId: string;
buyerId: string | null;
buyerLocation: string | null;
buyerContact: string | null;
providerId: string | null;
providerName: string | null;
providerDistanceKm: number | null;
quantity: number;
productionCost: number | null;
creatorPayout: number | null;
communityPayout: number | null;
totalPrice: number | null;
currency: string;
status: string;
paymentMethod: string | null;
paymentTx: string | null;
paymentNetwork: string | null;
createdAt: number;
paidAt: number;
acceptedAt: number;
completedAt: number;
updatedAt: number;
}
export interface OrderDoc {
meta: {
module: string;
collection: string;
version: number;
spaceSlug: string;
createdAt: number;
};
order: OrderMeta;
}
// ── Schema registration ──
export const catalogSchema: DocSchema<CatalogDoc> = {
module: 'cart',
collection: 'catalog',
version: 1,
init: (): CatalogDoc => ({
meta: {
module: 'cart',
collection: 'catalog',
version: 1,
spaceSlug: '',
createdAt: Date.now(),
},
items: {},
}),
};
export const orderSchema: DocSchema<OrderDoc> = {
module: 'cart',
collection: 'orders',
version: 1,
init: (): OrderDoc => ({
meta: {
module: 'cart',
collection: 'orders',
version: 1,
spaceSlug: '',
createdAt: Date.now(),
},
order: {
id: '',
catalogEntryId: '',
artifactId: '',
buyerId: null,
buyerLocation: null,
buyerContact: null,
providerId: null,
providerName: null,
providerDistanceKm: null,
quantity: 1,
productionCost: null,
creatorPayout: null,
communityPayout: null,
totalPrice: null,
currency: 'USD',
status: 'pending',
paymentMethod: null,
paymentTx: null,
paymentNetwork: null,
createdAt: Date.now(),
paidAt: 0,
acceptedAt: 0,
completedAt: 0,
updatedAt: Date.now(),
},
}),
};
// ── Helpers ──
export function catalogDocId(space: string) {
return `${space}:cart:catalog` as const;
}
export function orderDocId(space: string, orderId: string) {
return `${space}:cart:orders:${orderId}` as const;
}