152 lines
2.9 KiB
TypeScript
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;
|
|
}
|