@voyantjs/accommodations 0.55.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/README.md +11 -0
  2. package/dist/booking-engine/handler.d.ts +103 -0
  3. package/dist/booking-engine/handler.d.ts.map +1 -0
  4. package/dist/booking-engine/handler.js +254 -0
  5. package/dist/booking-engine/index.d.ts +8 -0
  6. package/dist/booking-engine/index.d.ts.map +1 -0
  7. package/dist/booking-engine/index.js +7 -0
  8. package/dist/catalog-policy.d.ts +23 -0
  9. package/dist/catalog-policy.d.ts.map +1 -0
  10. package/dist/catalog-policy.js +422 -0
  11. package/dist/content-shape.d.ts +185 -0
  12. package/dist/content-shape.d.ts.map +1 -0
  13. package/dist/content-shape.js +122 -0
  14. package/dist/draft-shape.d.ts +35 -0
  15. package/dist/draft-shape.d.ts.map +1 -0
  16. package/dist/draft-shape.js +84 -0
  17. package/dist/index.d.ts +8 -0
  18. package/dist/index.d.ts.map +1 -0
  19. package/dist/index.js +7 -0
  20. package/dist/routes-content.d.ts +31 -0
  21. package/dist/routes-content.d.ts.map +1 -0
  22. package/dist/routes-content.js +87 -0
  23. package/dist/schema-bookings.d.ts +582 -0
  24. package/dist/schema-bookings.d.ts.map +1 -0
  25. package/dist/schema-bookings.js +65 -0
  26. package/dist/schema-inventory.d.ts +1361 -0
  27. package/dist/schema-inventory.d.ts.map +1 -0
  28. package/dist/schema-inventory.js +132 -0
  29. package/dist/schema-shared.d.ts +5 -0
  30. package/dist/schema-shared.d.ts.map +1 -0
  31. package/dist/schema-shared.js +24 -0
  32. package/dist/schema-sourced-content.d.ts +254 -0
  33. package/dist/schema-sourced-content.d.ts.map +1 -0
  34. package/dist/schema-sourced-content.js +48 -0
  35. package/dist/schema.d.ts +5 -0
  36. package/dist/schema.d.ts.map +1 -0
  37. package/dist/schema.js +4 -0
  38. package/dist/service-catalog-plane.d.ts +55 -0
  39. package/dist/service-catalog-plane.d.ts.map +1 -0
  40. package/dist/service-catalog-plane.js +202 -0
  41. package/dist/service-content-synthesizer.d.ts +43 -0
  42. package/dist/service-content-synthesizer.d.ts.map +1 -0
  43. package/dist/service-content-synthesizer.js +149 -0
  44. package/dist/service-content.d.ts +54 -0
  45. package/dist/service-content.d.ts.map +1 -0
  46. package/dist/service-content.js +480 -0
  47. package/package.json +113 -0
package/README.md ADDED
@@ -0,0 +1,11 @@
1
+ # @voyantjs/accommodations
2
+
3
+ Accommodation resale contracts for Voyant.
4
+
5
+ This package is for OTAs, tour operators, and DMCs selling lodging as catalog
6
+ inventory or trip components. It is not a hotel-operations or PMS surface.
7
+
8
+ Retained scope includes sourced lodging content, room options, board basis,
9
+ rate plans, payment-policy lookup, booking draft shape, and catalog projection.
10
+ Do not add hotel staff workflows such as room-unit management, housekeeping,
11
+ maintenance, folios, or in-stay operations.
@@ -0,0 +1,103 @@
1
+ /**
2
+ * Owned-arm booking handler for the `accommodation` vertical.
3
+ *
4
+ * Per `docs/architecture/booking-journey-architecture.md` §6.
5
+ *
6
+ * Phase B scope (deliberately narrow):
7
+ * - `computeQuote` projects the property's accommodation content
8
+ * into a `BookingDraftShape` with date-range + occupancy
9
+ * sub-steps and a Rooms accommodation step. Pricing is best-
10
+ * effort: `nights × room_count × baseRateHint` when the content
11
+ * surfaces a rate hint; otherwise no pricing returned (the
12
+ * wizard hides the total until a real quote lands).
13
+ * - `commit` uses a caller-supplied bridge when the host template has a
14
+ * resale booking write path. Without one, it fails explicitly.
15
+ *
16
+ * Templates wire this handler at boot the same way they wire the
17
+ * products handler. Once `commit` ships, the registry is genuinely
18
+ * multi-vertical with no further dispatch changes.
19
+ */
20
+ import type { OwnedBookingHandler, OwnedHandlerContext } from "@voyantjs/catalog/booking-engine";
21
+ import type { AccommodationContent } from "../content-shape.js";
22
+ /**
23
+ * Caller-supplied loader — keeps the handler free of a hard
24
+ * dependency on the template's content service wiring (which spans
25
+ * sourced + owned + overlays). Templates wire this to
26
+ * `getAccommodationContent` from `@voyantjs/accommodations/service-content`.
27
+ */
28
+ export type AccommodationContentLoader = (ctx: OwnedHandlerContext, entityId: string) => Promise<AccommodationContent | null>;
29
+ /**
30
+ * Resale booking-line commit input. Structural so the handler stays free of a
31
+ * dependency on any host template's persistence path.
32
+ */
33
+ export interface AccommodationCommitBridgeInput {
34
+ propertyId: string;
35
+ roomTypeId: string;
36
+ ratePlanId: string;
37
+ mealPlanId?: string | null;
38
+ checkInDate: string;
39
+ checkOutDate: string;
40
+ roomCount?: number;
41
+ adults?: number;
42
+ children?: number;
43
+ infants?: number;
44
+ dailyRates: Array<{
45
+ sellCurrency: string;
46
+ sellAmountCents?: number | null;
47
+ costCurrency?: string | null;
48
+ costAmountCents?: number | null;
49
+ }>;
50
+ personId?: string | null;
51
+ organizationId?: string | null;
52
+ contact: {
53
+ firstName: string;
54
+ lastName: string;
55
+ email?: string | null;
56
+ phone?: string | null;
57
+ country?: string | null;
58
+ };
59
+ passengers: Array<{
60
+ firstName: string;
61
+ lastName: string;
62
+ email?: string | null;
63
+ phone?: string | null;
64
+ travelerCategory?: "adult" | "child" | "infant" | "senior" | "other" | null;
65
+ isPrimary?: boolean | null;
66
+ }>;
67
+ notes?: string | null;
68
+ }
69
+ export interface AccommodationCommitBridgeResult {
70
+ status: "ok" | "failed";
71
+ bookingId?: string;
72
+ bookingNumber?: string;
73
+ reason?: string;
74
+ }
75
+ export type AccommodationCommitBridge = (input: AccommodationCommitBridgeInput, options?: {
76
+ userId?: string;
77
+ }) => Promise<AccommodationCommitBridgeResult>;
78
+ export interface CreateAccommodationBookingHandlerOptions {
79
+ /** Loader for the property's content payload. */
80
+ loadContent: AccommodationContentLoader;
81
+ /**
82
+ * Default min/max nights when the supplier hasn't declared bounds.
83
+ * The journey's date-range sub-step uses these as guard rails.
84
+ */
85
+ defaultMinNights?: number;
86
+ defaultMaxNights?: number;
87
+ /**
88
+ * Caller-supplied bridge to a host template's accommodation booking write
89
+ * path. When omitted, commit returns
90
+ * `failed:accommodation_commit_bridge_not_wired`.
91
+ *
92
+ * The journey doesn't currently surface room-type / rate-plan
93
+ * picks at the granularity reserveStay needs (specifically
94
+ * `ratePlanId` and per-night `dailyRates`). Until the journey's
95
+ * Accommodation step + content shape extend to expose those, the
96
+ * caller may map drafts to a "best guess" room/rate from the
97
+ * descriptor's room-options projection — we leave that decision
98
+ * to the template.
99
+ */
100
+ commitBridge?: AccommodationCommitBridge;
101
+ }
102
+ export declare function createAccommodationBookingHandler(options: CreateAccommodationBookingHandlerOptions): OwnedBookingHandler;
103
+ //# sourceMappingURL=handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../src/booking-engine/handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAMV,mBAAmB,EACnB,mBAAmB,EAEpB,MAAM,kCAAkC,CAAA;AAEzC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAuB/D;;;;;GAKG;AACH,MAAM,MAAM,0BAA0B,GAAG,CACvC,GAAG,EAAE,mBAAmB,EACxB,QAAQ,EAAE,MAAM,KACb,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAAA;AAEzC;;;GAGG;AACH,MAAM,WAAW,8BAA8B;IAC7C,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,KAAK,CAAC;QAChB,YAAY,EAAE,MAAM,CAAA;QACpB,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;QAC/B,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;QAC5B,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAChC,CAAC,CAAA;IACF,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B,OAAO,EAAE;QACP,SAAS,EAAE,MAAM,CAAA;QACjB,QAAQ,EAAE,MAAM,CAAA;QAChB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;QACrB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;QACrB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KACxB,CAAA;IACD,UAAU,EAAE,KAAK,CAAC;QAChB,SAAS,EAAE,MAAM,CAAA;QACjB,QAAQ,EAAE,MAAM,CAAA;QAChB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;QACrB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;QACrB,gBAAgB,CAAC,EAAE,OAAO,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,GAAG,IAAI,CAAA;QAC3E,SAAS,CAAC,EAAE,OAAO,GAAG,IAAI,CAAA;KAC3B,CAAC,CAAA;IACF,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CACtB;AAED,MAAM,WAAW,+BAA+B;IAC9C,MAAM,EAAE,IAAI,GAAG,QAAQ,CAAA;IACvB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,MAAM,yBAAyB,GAAG,CACtC,KAAK,EAAE,8BAA8B,EACrC,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,KAC1B,OAAO,CAAC,+BAA+B,CAAC,CAAA;AAE7C,MAAM,WAAW,wCAAwC;IACvD,iDAAiD;IACjD,WAAW,EAAE,0BAA0B,CAAA;IACvC;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB;;;;;;;;;;;;OAYG;IACH,YAAY,CAAC,EAAE,yBAAyB,CAAA;CACzC;AAED,wBAAgB,iCAAiC,CAC/C,OAAO,EAAE,wCAAwC,GAChD,mBAAmB,CAkLrB"}
@@ -0,0 +1,254 @@
1
+ /**
2
+ * Owned-arm booking handler for the `accommodation` vertical.
3
+ *
4
+ * Per `docs/architecture/booking-journey-architecture.md` §6.
5
+ *
6
+ * Phase B scope (deliberately narrow):
7
+ * - `computeQuote` projects the property's accommodation content
8
+ * into a `BookingDraftShape` with date-range + occupancy
9
+ * sub-steps and a Rooms accommodation step. Pricing is best-
10
+ * effort: `nights × room_count × baseRateHint` when the content
11
+ * surfaces a rate hint; otherwise no pricing returned (the
12
+ * wizard hides the total until a real quote lands).
13
+ * - `commit` uses a caller-supplied bridge when the host template has a
14
+ * resale booking write path. Without one, it fails explicitly.
15
+ *
16
+ * Templates wire this handler at boot the same way they wire the
17
+ * products handler. Once `commit` ships, the registry is genuinely
18
+ * multi-vertical with no further dispatch changes.
19
+ */
20
+ import { buildAccommodationDraftShape } from "../draft-shape.js";
21
+ export function createAccommodationBookingHandler(options) {
22
+ return {
23
+ entityModule: "accommodations",
24
+ async computeQuote(ctx, request) {
25
+ const content = await options.loadContent(ctx, request.entityId);
26
+ if (!content) {
27
+ return { available: false, invalidReason: "property_not_found" };
28
+ }
29
+ const shape = buildAccommodationDraftShape(content, {
30
+ minNights: options.defaultMinNights,
31
+ maxNights: options.defaultMaxNights,
32
+ });
33
+ const draft = (request.draft ?? {});
34
+ const pricing = computeBestEffortPricing(shape, draft);
35
+ return {
36
+ available: true,
37
+ pricing,
38
+ shape,
39
+ };
40
+ },
41
+ async commit(_ctx, request) {
42
+ if (!options.commitBridge) {
43
+ return {
44
+ status: "failed",
45
+ orderRef: "",
46
+ upstreamPayload: { reason: "accommodation_commit_bridge_not_wired" },
47
+ };
48
+ }
49
+ const draft = (request.draft ?? {});
50
+ const range = draft.configure?.dateRange;
51
+ if (!range?.checkIn || !range?.checkOut) {
52
+ return {
53
+ status: "failed",
54
+ orderRef: "",
55
+ upstreamPayload: {
56
+ reason: "accommodation_commit_missing_inputs",
57
+ need: ["dateRange.checkIn", "dateRange.checkOut"],
58
+ },
59
+ };
60
+ }
61
+ // Map the draft's room selection into a single (roomType, ratePlan) pair.
62
+ // The journey's Accommodation step picks an option_unit_id (which is
63
+ // accommodation's `roomTypeId`); rate plan defaults to the room's first
64
+ // available — templates can override the default by augmenting the
65
+ // bridge output. When no room is picked yet, the commit fails fast.
66
+ const firstRoom = draft.accommodation?.rooms?.[0];
67
+ if (!firstRoom) {
68
+ return {
69
+ status: "failed",
70
+ orderRef: "",
71
+ upstreamPayload: {
72
+ reason: "accommodation_commit_missing_inputs",
73
+ need: ["accommodation.rooms[0]"],
74
+ },
75
+ };
76
+ }
77
+ const adults = draft.configure?.pax?.adult ?? draft.travelers?.length ?? 1;
78
+ const children = draft.configure?.pax?.child ?? 0;
79
+ const infants = draft.configure?.pax?.infant ?? 0;
80
+ const billing = draft.billing ?? {};
81
+ const contact = {
82
+ firstName: billing.contact?.firstName ?? "",
83
+ lastName: billing.contact?.lastName ?? "",
84
+ email: billing.contact?.email ?? null,
85
+ phone: billing.contact?.phone ?? null,
86
+ country: billing.address?.country ?? null,
87
+ };
88
+ const passengers = (draft.travelers ?? []).map((t, idx) => ({
89
+ firstName: t.firstName,
90
+ lastName: t.lastName,
91
+ travelerCategory: t.band === "child" || t.band === "infant"
92
+ ? t.band
93
+ : "adult",
94
+ isPrimary: idx === 0,
95
+ }));
96
+ if (passengers.length === 0) {
97
+ passengers.push({
98
+ firstName: contact.firstName,
99
+ lastName: contact.lastName,
100
+ travelerCategory: "adult",
101
+ isPrimary: true,
102
+ });
103
+ }
104
+ // Per-night rate hint from the draft's pricing breakdown
105
+ // (computed by the handler earlier). The bridge expects
106
+ // `dailyRates[]` with one entry per night — we replicate the
107
+ // averaged hint across nights as a placeholder; production
108
+ // needs supplier-provided rate-plan rows.
109
+ const nights = nightsBetween(range.checkIn, range.checkOut);
110
+ const totalCents = readPricingTotalCents(request.pricing);
111
+ const perNightCents = nights > 0 && totalCents > 0 ? Math.round(totalCents / nights / firstRoom.quantity) : 0;
112
+ const currency = readPricingCurrency(request.pricing) ?? "EUR";
113
+ const dailyRates = Array.from({ length: nights }, () => ({
114
+ sellCurrency: currency,
115
+ sellAmountCents: perNightCents,
116
+ }));
117
+ // The journey now surfaces rate-plan choice via the descriptor's
118
+ // `RoomOption.ratePlans`. When the user hasn't picked one — e.g.
119
+ // the property has no rate plans configured — the commit fails
120
+ // with a helpful reason; the bridge no longer guesses.
121
+ if (!firstRoom.ratePlanId) {
122
+ return {
123
+ status: "failed",
124
+ orderRef: "",
125
+ upstreamPayload: {
126
+ reason: "accommodation_commit_missing_inputs",
127
+ need: ["accommodation.rooms[0].ratePlanId"],
128
+ },
129
+ };
130
+ }
131
+ const bridge = await options.commitBridge({
132
+ propertyId: request.entityId,
133
+ roomTypeId: firstRoom.optionUnitId,
134
+ ratePlanId: firstRoom.ratePlanId,
135
+ checkInDate: range.checkIn,
136
+ checkOutDate: range.checkOut,
137
+ roomCount: firstRoom.quantity,
138
+ adults,
139
+ children,
140
+ infants,
141
+ dailyRates,
142
+ personId: extractPersonId(request.party),
143
+ organizationId: extractOrganizationId(request.party),
144
+ contact,
145
+ passengers,
146
+ notes: typeof draft.internalNotes === "string" ? draft.internalNotes : null,
147
+ });
148
+ if (bridge.status !== "ok" || !bridge.bookingId) {
149
+ return {
150
+ status: "failed",
151
+ orderRef: "",
152
+ upstreamPayload: { reason: bridge.reason ?? "accommodation_commit_failed" },
153
+ };
154
+ }
155
+ return {
156
+ status: "held",
157
+ orderRef: bridge.bookingNumber ?? bridge.bookingId,
158
+ pricing: request.pricing,
159
+ upstreamPayload: { bridgeBookingId: bridge.bookingId },
160
+ };
161
+ },
162
+ async placeHold(_ctx, request) {
163
+ const token = request.draftId ?? `acc_${Date.now().toString(36)}`;
164
+ return {
165
+ holdToken: token,
166
+ expiresAt: new Date(Date.now() + request.ttlMs),
167
+ };
168
+ },
169
+ async releaseHold(_ctx, _holdToken) {
170
+ // No-op until inventory reservation against rate plans + room
171
+ // inventory lands.
172
+ },
173
+ };
174
+ }
175
+ // ─────────────────────────────────────────────────────────────────
176
+ // Pricing heuristic
177
+ // ─────────────────────────────────────────────────────────────────
178
+ function computeBestEffortPricing(shape, draft) {
179
+ const range = draft.configure?.dateRange;
180
+ if (!range?.checkIn || !range?.checkOut)
181
+ return undefined;
182
+ const nights = nightsBetween(range.checkIn, range.checkOut);
183
+ if (nights <= 0)
184
+ return undefined;
185
+ const rooms = draft.accommodation?.rooms ?? [];
186
+ const totalRooms = rooms.length === 0 ? 1 : rooms.reduce((sum, r) => sum + r.quantity, 0);
187
+ if (totalRooms <= 0)
188
+ return undefined;
189
+ // Pick the cheapest available room option's hint (when surfaced).
190
+ // The journey's Configure step doesn't pin a rate until the user
191
+ // picks a room — this is just a starter total.
192
+ const roomOptions = (shape.accommodation?.roomOptions ?? []);
193
+ const hint = roomOptions
194
+ .map((r) => r.baseRateHint ?? 0)
195
+ .filter((n) => n > 0)
196
+ .sort((a, b) => a - b)[0];
197
+ if (!hint)
198
+ return undefined;
199
+ const totalCents = hint * nights * totalRooms;
200
+ return {
201
+ base_amount: totalCents,
202
+ taxes: 0,
203
+ fees: 0,
204
+ surcharges: 0,
205
+ // Currency is unknown until the rate plan is picked — fall back
206
+ // to EUR as the most common storefront default. Real commits
207
+ // override at quote time.
208
+ currency: "EUR",
209
+ breakdown: {
210
+ lines: [
211
+ {
212
+ kind: "accommodations",
213
+ label: `${totalRooms} room × ${nights} night${nights === 1 ? "" : "s"}`,
214
+ quantity: nights * totalRooms,
215
+ unitAmount: hint,
216
+ totalAmount: totalCents,
217
+ },
218
+ ],
219
+ subtotal: totalCents,
220
+ taxTotal: 0,
221
+ total: totalCents,
222
+ nights,
223
+ rooms: totalRooms,
224
+ },
225
+ };
226
+ }
227
+ function nightsBetween(checkIn, checkOut) {
228
+ const inDate = new Date(checkIn);
229
+ const outDate = new Date(checkOut);
230
+ if (Number.isNaN(inDate.getTime()) || Number.isNaN(outDate.getTime()))
231
+ return 0;
232
+ const ms = outDate.getTime() - inDate.getTime();
233
+ return Math.round(ms / (1000 * 60 * 60 * 24));
234
+ }
235
+ function extractPersonId(party) {
236
+ if (!party)
237
+ return undefined;
238
+ const v = party.personId;
239
+ return typeof v === "string" && v.length > 0 ? v : undefined;
240
+ }
241
+ function extractOrganizationId(party) {
242
+ if (!party)
243
+ return undefined;
244
+ const v = party.organizationId;
245
+ return typeof v === "string" && v.length > 0 ? v : undefined;
246
+ }
247
+ function readPricingTotalCents(pricing) {
248
+ if (!pricing)
249
+ return 0;
250
+ return (pricing.base_amount ?? 0) + (pricing.taxes ?? 0);
251
+ }
252
+ function readPricingCurrency(pricing) {
253
+ return pricing?.currency;
254
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * `@voyantjs/accommodations/booking-engine` — owned-arm booking
3
+ * handler for the accommodation vertical.
4
+ *
5
+ * Per `docs/architecture/booking-journey-architecture.md` §6.
6
+ */
7
+ export { type AccommodationCommitBridge, type AccommodationCommitBridgeInput, type AccommodationCommitBridgeResult, type AccommodationContentLoader, type CreateAccommodationBookingHandlerOptions, createAccommodationBookingHandler, } from "./handler.js";
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/booking-engine/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,KAAK,yBAAyB,EAC9B,KAAK,8BAA8B,EACnC,KAAK,+BAA+B,EACpC,KAAK,0BAA0B,EAC/B,KAAK,wCAAwC,EAC7C,iCAAiC,GAClC,MAAM,cAAc,CAAA"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * `@voyantjs/accommodations/booking-engine` — owned-arm booking
3
+ * handler for the accommodation vertical.
4
+ *
5
+ * Per `docs/architecture/booking-journey-architecture.md` §6.
6
+ */
7
+ export { createAccommodationBookingHandler, } from "./handler.js";
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Catalog plane field policy for `packages/accommodations`.
3
+ *
4
+ * The accommodation vertical's catalog entry is the **room type** — the
5
+ * sellable variant within a property. Properties themselves live in
6
+ * `packages/facilities` and are referenced via `propertyId`.
7
+ *
8
+ * Scope of this file:
9
+ * - The root `room_types` table (from `schema-inventory.ts`).
10
+ * - Provenance + identity fields the catalog plane needs to track.
11
+ *
12
+ * Out of scope for this resale package:
13
+ * - hotel-managed physical room units and their lifecycle.
14
+ * - `rate_plans` — variant pricing axis with its own lifecycle.
15
+ * - `meal_plans` — board-basis variants, structural choice axis.
16
+ * - `room_type_bed_configs` — composite list with managed structural
17
+ * fields under each row.
18
+ */
19
+ import { type FieldPolicyInput } from "@voyantjs/catalog/contract";
20
+ declare const ACCOMMODATION_FIELD_POLICY: FieldPolicyInput[];
21
+ export declare const accommodationCatalogPolicy: import("@voyantjs/catalog").FieldPolicy[];
22
+ export { ACCOMMODATION_FIELD_POLICY };
23
+ //# sourceMappingURL=catalog-policy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog-policy.d.ts","sourceRoot":"","sources":["../src/catalog-policy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAqB,KAAK,gBAAgB,EAAE,MAAM,4BAA4B,CAAA;AAErF,QAAA,MAAM,0BAA0B,EAAE,gBAAgB,EAsZjD,CAAA;AAED,eAAO,MAAM,0BAA0B,2CAAgD,CAAA;AAEvF,OAAO,EAAE,0BAA0B,EAAE,CAAA"}