rspace-online/modules/rtrips/schemas.ts

152 lines
2.9 KiB
TypeScript

/**
* rTrips Automerge document schemas.
*
* Granularity: one Automerge document per trip.
* DocId format: {space}:trips:trips:{tripId}
*/
import type { DocSchema } from '../../shared/local-first/document';
// ── Document types ──
export interface TripMeta {
id: string;
title: string;
slug: string;
description: string;
startDate: string | null;
endDate: string | null;
budgetTotal: number | null;
budgetCurrency: string | null;
status: string;
createdBy: string | null;
createdAt: number;
updatedAt: number;
}
export interface Destination {
id: string;
tripId: string;
name: string;
country: string | null;
lat: number | null;
lng: number | null;
arrivalDate: string | null;
departureDate: string | null;
notes: string;
sortOrder: number;
createdAt: number;
}
export interface ItineraryItem {
id: string;
tripId: string;
destinationId: string | null;
title: string;
category: string | null;
date: string | null;
startTime: string | null;
endTime: string | null;
notes: string;
sortOrder: number;
createdAt: number;
}
export interface Booking {
id: string;
tripId: string;
type: string | null;
provider: string | null;
confirmationNumber: string | null;
cost: number | null;
currency: string | null;
startDate: string | null;
endDate: string | null;
status: string | null;
notes: string;
createdAt: number;
}
export interface Expense {
id: string;
tripId: string;
paidBy: string | null;
description: string;
amount: number;
currency: string | null;
category: string | null;
date: string | null;
splitType: string | null;
createdAt: number;
}
export interface PackingItem {
id: string;
tripId: string;
addedBy: string | null;
name: string;
category: string | null;
packed: boolean;
quantity: number;
sortOrder: number;
createdAt: number;
}
export interface TripDoc {
meta: {
module: string;
collection: string;
version: number;
spaceSlug: string;
createdAt: number;
};
trip: TripMeta;
destinations: Record<string, Destination>;
itinerary: Record<string, ItineraryItem>;
bookings: Record<string, Booking>;
expenses: Record<string, Expense>;
packingItems: Record<string, PackingItem>;
}
// ── Schema registration ──
export const tripSchema: DocSchema<TripDoc> = {
module: 'trips',
collection: 'trips',
version: 1,
init: (): TripDoc => ({
meta: {
module: 'trips',
collection: 'trips',
version: 1,
spaceSlug: '',
createdAt: Date.now(),
},
trip: {
id: '',
title: 'Untitled Trip',
slug: '',
description: '',
startDate: null,
endDate: null,
budgetTotal: null,
budgetCurrency: null,
status: 'planning',
createdBy: null,
createdAt: Date.now(),
updatedAt: Date.now(),
},
destinations: {},
itinerary: {},
bookings: {},
expenses: {},
packingItems: {},
}),
};
// ── Helpers ──
export function tripDocId(space: string, tripId: string) {
return `${space}:trips:trips:${tripId}` as const;
}