/** * 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; } 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 = { module: 'cart', collection: 'catalog', version: 1, init: (): CatalogDoc => ({ meta: { module: 'cart', collection: 'catalog', version: 1, spaceSlug: '', createdAt: Date.now(), }, items: {}, }), }; export const orderSchema: DocSchema = { 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(), }, }), }; // ── Shopping Cart types ── export type CartStatus = 'OPEN' | 'FUNDING' | 'FUNDED' | 'CHECKING_OUT' | 'ORDERED' | 'CLOSED'; export interface CartItemVendor { name: string; domain: string; platform: string | null; // 'amazon' | 'shopify' | 'etsy' | null } export interface CartItem { name: string; price: number | null; currency: string; quantity: number; sourceUrl: string; imageUrl: string | null; description: string | null; vendor: CartItemVendor; addedBy: string | null; // DID addedAt: number; sku: string | null; } export interface CartContribution { userId: string | null; username: string; amount: number; currency: string; paymentMethod: string; // 'MANUAL' for MVP status: string; // 'pending' | 'confirmed' txHash: string | null; createdAt: number; updatedAt: number; } export interface CartEvent { type: string; // 'item_added' | 'item_removed' | 'contribution' | 'status_change' actor: string; detail: string; timestamp: number; } export interface ShoppingCartDoc { meta: { module: string; collection: string; version: number; spaceSlug: string; createdAt: number; }; cart: { id: string; name: string; description: string; status: CartStatus; createdBy: string | null; targetAmount: number; fundedAmount: number; currency: string; createdAt: number; updatedAt: number; }; items: Record; contributions: Record; events: CartEvent[]; } export interface ShoppingCartIndexEntry { name: string; status: CartStatus; itemCount: number; totalAmount: number; fundedAmount: number; currency: string; createdAt: number; updatedAt: number; } export interface ShoppingCartIndexDoc { meta: { module: string; collection: string; version: number; spaceSlug: string; createdAt: number; }; carts: Record; } // ── Shopping Cart schema registration ── export const shoppingCartSchema: DocSchema = { module: 'cart', collection: 'shopping', version: 1, init: (): ShoppingCartDoc => ({ meta: { module: 'cart', collection: 'shopping', version: 1, spaceSlug: '', createdAt: Date.now(), }, cart: { id: '', name: '', description: '', status: 'OPEN', createdBy: null, targetAmount: 0, fundedAmount: 0, currency: 'USD', createdAt: Date.now(), updatedAt: Date.now(), }, items: {}, contributions: {}, events: [], }), }; export const shoppingCartIndexSchema: DocSchema = { module: 'cart', collection: 'shopping-index', version: 1, init: (): ShoppingCartIndexDoc => ({ meta: { module: 'cart', collection: 'shopping-index', version: 1, spaceSlug: '', createdAt: Date.now(), }, carts: {}, }), }; // ── 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; } export function shoppingCartDocId(space: string, cartId: string) { return `${space}:cart:shopping:${cartId}` as const; } export function shoppingCartIndexDocId(space: string) { return `${space}:cart:shopping-index` as const; }