@voyantjs/bookings 0.81.1 → 0.81.5

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.
@@ -18,9 +18,10 @@
18
18
  * quantities **stay as the operator picked them** (1 DBL room is
19
19
  * still 1 line, not 2).
20
20
  *
21
- * The `roomUnitAssignmentSource` enum on the traveler tracks operator
22
- * intent so the resolver knows when to re-derive ("auto") versus
23
- * respect an explicit choice ("manual" / "none" for No room).
21
+ * The `pricingUnitSource` and `inventoryUnitSource` enums on the
22
+ * traveler track operator intent so the resolver knows when to
23
+ * re-derive ("auto") versus respect an explicit choice ("manual" /
24
+ * "none" for No room).
24
25
  *
25
26
  * No React, no DB, no HTTP — just the assignment math.
26
27
  *
@@ -30,6 +31,8 @@ export type TravelerRole = "lead" | "adult" | "child" | "infant";
30
31
  export type AssignmentRoleHint = "adult" | "child" | "infant";
31
32
  export type BookingDraftUnitAssignmentSource = "auto" | "manual" | "none";
32
33
  export interface BookingDraftTraveler {
34
+ /** Stable client-side traveler key used by wire-format travelerKeys links. */
35
+ clientTravelerKey?: string | null;
33
36
  personId: string | null;
34
37
  firstName: string;
35
38
  lastName: string;
@@ -38,26 +41,29 @@ export interface BookingDraftTraveler {
38
41
  preferredLanguage: string;
39
42
  role: TravelerRole;
40
43
  dateOfBirth: string | null;
44
+ /** option_unit_id of the person pricing tier this traveler is billed as. */
45
+ pricingUnitId: string | null;
46
+ /** option_unit_id of the room/vehicle this traveler occupies, when applicable. */
47
+ inventoryUnitId: string | null;
41
48
  /**
42
- * Legacy field name kept for compatibility with the current dialog.
43
- * For person-priced products it carries the traveler's pricing
44
- * tier; for accommodation products it carries the selected
45
- * room/inventory unit. Source of intent disambiguated by
46
- * `roomUnitAssignmentSource` below.
47
- */
48
- roomUnitId: string | null;
49
- /**
50
- * Tracks operator intent around the legacy `roomUnitId` field.
49
+ * Tracks operator intent around `pricingUnitId`.
51
50
  *
52
51
  * - `auto`: derived from product shape, DOB, role hints, and
53
52
  * selected quantity. Eligible for re-derivation on every render.
54
- * - `manual`: operator explicitly clicked a category/room button.
55
- * The resolver respects the value when it's in the current unit
56
- * set; otherwise it re-derives.
57
- * - `none`: operator explicitly picked "No room". Stays null
58
- * regardless of unit demand.
53
+ * - `manual`: operator explicitly clicked a category button. The
54
+ * resolver respects the value when it's in the current unit set;
55
+ * otherwise it re-derives.
56
+ * - `none`: no pricing unit should be assigned.
59
57
  */
60
- roomUnitAssignmentSource?: BookingDraftUnitAssignmentSource;
58
+ pricingUnitSource?: BookingDraftUnitAssignmentSource;
59
+ /**
60
+ * Tracks operator intent around `inventoryUnitId`.
61
+ *
62
+ * - `auto`: derived from selected quantity and product shape.
63
+ * - `manual`: operator explicitly clicked a room/vehicle control.
64
+ * - `none`: operator explicitly picked "No room". Stays null.
65
+ */
66
+ inventoryUnitSource?: BookingDraftUnitAssignmentSource;
61
67
  }
62
68
  export interface PricingAssignmentUnit {
63
69
  /** Option the unit belongs to. Null for product-level units. */
@@ -82,8 +88,8 @@ export interface ResolvedBookingDraft<TTraveler extends BookingDraftTraveler> {
82
88
  /**
83
89
  * For each unit that ended up assigned, the indexes (into the input
84
90
  * traveler array) of travelers mapped to it. Used at submit time to
85
- * stamp `travelerIndexes` on `booking_item` lines so the server can
86
- * link items to travelers through `booking_item_travelers`.
91
+ * stamp stable `travelerKeys` on `booking_item` lines so the server
92
+ * can link items to travelers through `booking_item_travelers`.
87
93
  */
88
94
  travelerIndexesByUnitId: Record<string, number[]>;
89
95
  }
@@ -101,6 +107,7 @@ export interface ResolvableExtraLine {
101
107
  unitSellAmountCents?: number | null;
102
108
  totalSellAmountCents?: number | null;
103
109
  clientLineKey?: string | null;
110
+ travelerKeys?: string[] | null;
104
111
  travelerIndexes?: number[] | null;
105
112
  }
106
113
  /**
@@ -149,9 +156,9 @@ export declare function matchUnitByRoleHint<TUnit extends PricingAssignmentUnit>
149
156
  * traveler room assignments still update `travelerIndexesByUnitId`
150
157
  * so `booking_item_travelers` rows can be created.
151
158
  *
152
- * Respects `roomUnitAssignmentSource`:
153
- * - `none` → traveler stays null (explicit No room)
154
- * - `manual` → traveler's existing roomUnitId is kept when valid
159
+ * Respects assignment sources:
160
+ * - `none` → the corresponding field stays null
161
+ * - `manual` → the existing unit is kept when valid for the chosen option
155
162
  * - `auto` → re-derived against current options
156
163
  */
157
164
  export declare function resolveBookingDraft<TTraveler extends BookingDraftTraveler>(options: {
@@ -162,28 +169,34 @@ export declare function resolveBookingDraft<TTraveler extends BookingDraftTravel
162
169
  }): ResolvedBookingDraft<TTraveler>;
163
170
  /**
164
171
  * Normalize per-person extras to charged traveler quantity and
165
- * stamp `travelerIndexes` + `clientLineKey` so the server can link
172
+ * stamp traveler links + `clientLineKey` so the server can link
166
173
  * each extra line to the travelers it applies to via
167
174
  * `booking_item_travelers`.
168
175
  *
169
176
  * Per-person mode (`pricingMode === "per_person"` or
170
177
  * `pricedPerPerson === true`): quantity multiplied by travelerCount,
171
- * `travelerIndexes` set to all travelers (uniform applicability).
178
+ * `travelerKeys` set to all travelers when stable keys are supplied;
179
+ * otherwise `travelerIndexes` is set as a deprecated fallback.
172
180
  * Non-per-person lines pass through with `clientLineKey` only.
173
181
  */
174
182
  export declare function resolveBookingExtraLines<TLine extends ResolvableExtraLine>(options: {
175
183
  extraLines: readonly TLine[];
176
184
  travelerCount: number;
185
+ travelerKeys?: readonly (string | null | undefined)[];
177
186
  }): TLine[];
178
187
  /**
179
188
  * Project a resolved draft's traveler list into the wire-format
180
189
  * `BookingCreateTravelerInput[]` shape the dialog submits. Derives
181
- * the `travelerCategory` from DOB / role and respects the
182
- * `roomUnitAssignmentSource === "none"` carve-out.
190
+ * the `travelerCategory` from DOB / role.
191
+ *
192
+ * `roomUnitId` is a deprecated compatibility alias for the pricing tier
193
+ * option unit. Inventory placement is expressed only by item lines and their
194
+ * `travelerKeys`; the server accepts this field but does not persist it.
183
195
  */
184
196
  export declare function travelersToRows(value: {
185
197
  travelers: readonly BookingDraftTraveler[];
186
198
  }, now?: Date): Array<{
199
+ clientTravelerKey: string | null;
187
200
  personId: string | null;
188
201
  firstName: string;
189
202
  lastName: string;
@@ -205,6 +218,7 @@ export declare function travelersToRows(value: {
205
218
  * implicitly maps to.
206
219
  */
207
220
  export interface VerifiableTraveler {
221
+ clientTravelerKey?: string | null;
208
222
  isPrimary?: boolean | null;
209
223
  travelerCategory?: "adult" | "child" | "infant" | "senior" | "other" | null;
210
224
  }
@@ -215,6 +229,7 @@ export interface VerifiableTraveler {
215
229
  export interface VerifiableItemLine {
216
230
  optionUnitId: string;
217
231
  quantity: number;
232
+ travelerKeys?: string[] | null;
218
233
  travelerIndexes?: number[] | null;
219
234
  }
220
235
  export interface BookingDraftMismatch {
@@ -243,10 +258,12 @@ export interface VerifyBookingDraftResult {
243
258
  * no legitimate clients trip the warning.
244
259
  *
245
260
  * Notes on the reconstruction:
246
- * - The wire format doesn't carry per-traveler `roomUnitId` (the
247
- * join-table model encodes it through `itemLines[].travelerIndexes`),
248
- * so we reconstruct it by walking item lines and matching them
249
- * to traveler indexes.
261
+ * - The wire format doesn't carry split per-traveler assignment
262
+ * fields (the join-table model encodes them through
263
+ * `itemLines[].travelerKeys`), so we reconstruct the relevant
264
+ * pricing or inventory unit by walking item lines and matching
265
+ * them to traveler keys. Deprecated `travelerIndexes` remain a
266
+ * fallback for older clients.
250
267
  * - DOB doesn't round-trip on the wire today either; we feed the
251
268
  * resolver the `travelerCategory` as a role hint so age-banded
252
269
  * options can still be re-derived.
@@ -1 +1 @@
1
- {"version":3,"file":"pricing-assignment.d.ts","sourceRoot":"","sources":["../src/pricing-assignment.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pricing-assignment.d.ts","sourceRoot":"","sources":["../src/pricing-assignment.ts"],"names":[],"mappings":"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"}
@@ -18,9 +18,10 @@
18
18
  * quantities **stay as the operator picked them** (1 DBL room is
19
19
  * still 1 line, not 2).
20
20
  *
21
- * The `roomUnitAssignmentSource` enum on the traveler tracks operator
22
- * intent so the resolver knows when to re-derive ("auto") versus
23
- * respect an explicit choice ("manual" / "none" for No room).
21
+ * The `pricingUnitSource` and `inventoryUnitSource` enums on the
22
+ * traveler track operator intent so the resolver knows when to
23
+ * re-derive ("auto") versus respect an explicit choice ("manual" /
24
+ * "none" for No room).
24
25
  *
25
26
  * No React, no DB, no HTTP — just the assignment math.
26
27
  *
@@ -169,9 +170,9 @@ function roleHintForTraveler(traveler) {
169
170
  * traveler room assignments still update `travelerIndexesByUnitId`
170
171
  * so `booking_item_travelers` rows can be created.
171
172
  *
172
- * Respects `roomUnitAssignmentSource`:
173
- * - `none` → traveler stays null (explicit No room)
174
- * - `manual` → traveler's existing roomUnitId is kept when valid
173
+ * Respects assignment sources:
174
+ * - `none` → the corresponding field stays null
175
+ * - `manual` → the existing unit is kept when valid for the chosen option
175
176
  * - `auto` → re-derived against current options
176
177
  */
177
178
  export function resolveBookingDraft(options) {
@@ -193,6 +194,12 @@ export function resolveBookingDraft(options) {
193
194
  else
194
195
  unitsByOption.set(key, [unit]);
195
196
  }
197
+ const primaryInventoryByOption = new Map();
198
+ for (const [key, optionUnits] of unitsByOption) {
199
+ const inventoryUnit = optionUnits.find(isInventoryUnit);
200
+ if (inventoryUnit)
201
+ primaryInventoryByOption.set(key, inventoryUnit);
202
+ }
196
203
  // An option is "person-priced" when it has at least one person unit
197
204
  // and no inventory unit (room/vehicle). That's the excursion shape:
198
205
  // line quantities derive from travelers, not from the stepper's
@@ -217,52 +224,96 @@ export function resolveBookingDraft(options) {
217
224
  }
218
225
  const assignedForDefaulting = new Map();
219
226
  for (const traveler of travelers) {
220
- if (!traveler.roomUnitId || traveler.roomUnitAssignmentSource === "none")
227
+ const inventorySource = traveler.inventoryUnitSource ?? "auto";
228
+ const pricingSource = traveler.pricingUnitSource ?? "auto";
229
+ const assignedUnitId = inventorySource !== "none" && traveler.inventoryUnitId
230
+ ? traveler.inventoryUnitId
231
+ : pricingSource !== "none"
232
+ ? traveler.pricingUnitId
233
+ : null;
234
+ if (!assignedUnitId)
221
235
  continue;
222
- const key = unitToOption.get(traveler.roomUnitId);
236
+ const key = unitToOption.get(assignedUnitId);
223
237
  if (!key)
224
238
  continue;
225
239
  assignedForDefaulting.set(key, (assignedForDefaulting.get(key) ?? 0) + 1);
226
240
  }
227
241
  const optionDemand = Array.from(totalByOption.entries());
228
242
  const pickOptionWithDemand = () => optionDemand.find(([candidate, total]) => (assignedForDefaulting.get(candidate) ?? 0) < total)?.[0] ?? optionDemand[0]?.[0];
229
- const resolveUnitForTraveler = (traveler, key) => pickUnitForAge(unitsByOption.get(key) ?? [], computeAgeYears(traveler.dateOfBirth, now), roleHintForTraveler(traveler));
230
- const assignNextDemandUnit = (traveler) => {
243
+ const resolvePricingUnitForTraveler = (traveler, key) => pickUnitForAge((unitsByOption.get(key) ?? []).filter(isPersonUnit), computeAgeYears(traveler.dateOfBirth, now), roleHintForTraveler(traveler));
244
+ const resolveTargetOption = (traveler) => {
245
+ const inventorySource = traveler.inventoryUnitSource ?? "auto";
246
+ if (inventorySource !== "none" && traveler.inventoryUnitId) {
247
+ const inventoryUnit = unitById.get(traveler.inventoryUnitId);
248
+ const key = unitToOption.get(traveler.inventoryUnitId);
249
+ if (key && inventoryUnit && isInventoryUnit(inventoryUnit))
250
+ return { key, fromDemand: false };
251
+ }
252
+ const pricingSource = traveler.pricingUnitSource ?? "auto";
253
+ if (pricingSource !== "none" && traveler.pricingUnitId) {
254
+ const pricingUnit = unitById.get(traveler.pricingUnitId);
255
+ const key = unitToOption.get(traveler.pricingUnitId);
256
+ if (key && pricingUnit && isPersonUnit(pricingUnit))
257
+ return { key, fromDemand: false };
258
+ }
231
259
  const key = pickOptionWithDemand();
232
- if (!key)
233
- return { ...traveler, roomUnitId: null, roomUnitAssignmentSource: "auto" };
234
- const unit = resolveUnitForTraveler(traveler, key);
235
- if (!unit)
236
- return { ...traveler, roomUnitId: null, roomUnitAssignmentSource: "auto" };
237
- assignedForDefaulting.set(key, (assignedForDefaulting.get(key) ?? 0) + 1);
238
- return {
239
- ...traveler,
240
- roomUnitId: unit.optionUnitId,
241
- roomUnitAssignmentSource: "auto",
242
- };
260
+ return key ? { key, fromDemand: true } : null;
243
261
  };
244
262
  const nextTravelers = travelers.map((traveler) => {
245
- const source = traveler.roomUnitAssignmentSource ?? "auto";
246
- if (source === "none") {
247
- return { ...traveler, roomUnitId: null, roomUnitAssignmentSource: "none" };
263
+ const target = resolveTargetOption(traveler);
264
+ const pricingSource = traveler.pricingUnitSource ?? "auto";
265
+ const inventorySource = traveler.inventoryUnitSource ?? "auto";
266
+ if (!target) {
267
+ return {
268
+ ...traveler,
269
+ pricingUnitId: null,
270
+ inventoryUnitId: null,
271
+ pricingUnitSource: pricingSource === "none" ? "none" : "auto",
272
+ inventoryUnitSource: inventorySource === "none" ? "none" : "auto",
273
+ };
248
274
  }
249
- if (traveler.roomUnitId && unitById.has(traveler.roomUnitId)) {
250
- const key = unitToOption.get(traveler.roomUnitId);
251
- if (!key || source === "manual" || !personPricedOptions.has(key))
252
- return traveler;
253
- // Stale auto-assigned person-priced unit: re-derive against the
254
- // current bands so a child traveler who was placed on Adult by
255
- // an earlier pass moves to the right band on the next render.
256
- const unit = resolveUnitForTraveler(traveler, key);
257
- return unit && unit.optionUnitId !== traveler.roomUnitId
258
- ? {
259
- ...traveler,
260
- roomUnitId: unit.optionUnitId,
261
- roomUnitAssignmentSource: "auto",
262
- }
263
- : traveler;
275
+ const targetKey = target.key;
276
+ const currentPricingUnit = traveler.pricingUnitId
277
+ ? unitById.get(traveler.pricingUnitId)
278
+ : undefined;
279
+ const currentPricingKey = traveler.pricingUnitId
280
+ ? unitToOption.get(traveler.pricingUnitId)
281
+ : undefined;
282
+ const keepManualPricing = pricingSource === "manual" &&
283
+ currentPricingUnit &&
284
+ isPersonUnit(currentPricingUnit) &&
285
+ currentPricingKey === targetKey;
286
+ const nextPricingUnit = pricingSource === "none"
287
+ ? null
288
+ : keepManualPricing
289
+ ? currentPricingUnit
290
+ : (resolvePricingUnitForTraveler(traveler, targetKey) ?? null);
291
+ const currentInventoryUnit = traveler.inventoryUnitId
292
+ ? unitById.get(traveler.inventoryUnitId)
293
+ : undefined;
294
+ const currentInventoryKey = traveler.inventoryUnitId
295
+ ? unitToOption.get(traveler.inventoryUnitId)
296
+ : undefined;
297
+ const keepManualInventory = inventorySource === "manual" &&
298
+ currentInventoryUnit &&
299
+ isInventoryUnit(currentInventoryUnit) &&
300
+ currentInventoryKey === targetKey;
301
+ const targetInventoryUnit = primaryInventoryByOption.get(targetKey) ?? null;
302
+ const nextInventoryUnit = inventorySource === "none"
303
+ ? null
304
+ : keepManualInventory
305
+ ? currentInventoryUnit
306
+ : targetInventoryUnit;
307
+ if (target.fromDemand && (nextPricingUnit || nextInventoryUnit)) {
308
+ assignedForDefaulting.set(targetKey, (assignedForDefaulting.get(targetKey) ?? 0) + 1);
264
309
  }
265
- return assignNextDemandUnit(traveler);
310
+ return {
311
+ ...traveler,
312
+ pricingUnitId: nextPricingUnit?.optionUnitId ?? null,
313
+ inventoryUnitId: nextInventoryUnit?.optionUnitId ?? null,
314
+ pricingUnitSource: pricingSource === "none" ? "none" : keepManualPricing ? "manual" : "auto",
315
+ inventoryUnitSource: inventorySource === "none" ? "none" : keepManualInventory ? "manual" : "auto",
316
+ };
266
317
  });
267
318
  const next = {};
268
319
  const travelerIndexesByUnitId = {};
@@ -275,22 +326,39 @@ export function resolveBookingDraft(options) {
275
326
  const key = unitToOption.get(unitId);
276
327
  if (!key || personPricedOptions.has(key))
277
328
  continue;
278
- next[unitId] = quantity;
329
+ const submittedUnit = unitById.get(unitId);
330
+ const targetUnitId = submittedUnit && isInventoryUnit(submittedUnit)
331
+ ? unitId
332
+ : (primaryInventoryByOption.get(key)?.optionUnitId ?? unitId);
333
+ next[targetUnitId] = (next[targetUnitId] ?? 0) + quantity;
279
334
  }
280
335
  const assignedByOption = new Map();
281
336
  for (const [index, traveler] of nextTravelers.entries()) {
282
- if (!traveler.roomUnitId || traveler.roomUnitAssignmentSource === "none")
283
- continue;
284
- const key = unitToOption.get(traveler.roomUnitId);
337
+ const pricingSource = traveler.pricingUnitSource ?? "auto";
338
+ const inventorySource = traveler.inventoryUnitSource ?? "auto";
339
+ const pricingKey = pricingSource !== "none" && traveler.pricingUnitId
340
+ ? unitToOption.get(traveler.pricingUnitId)
341
+ : undefined;
342
+ const inventoryKey = inventorySource !== "none" && traveler.inventoryUnitId
343
+ ? unitToOption.get(traveler.inventoryUnitId)
344
+ : undefined;
345
+ const key = inventoryKey ?? pricingKey;
285
346
  if (!key)
286
347
  continue;
287
- const unitIndexes = travelerIndexesByUnitId[traveler.roomUnitId] ?? [];
288
- unitIndexes.push(index);
289
- travelerIndexesByUnitId[traveler.roomUnitId] = unitIndexes;
290
348
  if (personPricedOptions.has(key)) {
291
- next[traveler.roomUnitId] = (next[traveler.roomUnitId] ?? 0) + 1;
349
+ if (!traveler.pricingUnitId || pricingSource === "none")
350
+ continue;
351
+ const unitIndexes = travelerIndexesByUnitId[traveler.pricingUnitId] ?? [];
352
+ unitIndexes.push(index);
353
+ travelerIndexesByUnitId[traveler.pricingUnitId] = unitIndexes;
354
+ next[traveler.pricingUnitId] = (next[traveler.pricingUnitId] ?? 0) + 1;
292
355
  assignedByOption.set(key, (assignedByOption.get(key) ?? 0) + 1);
293
356
  }
357
+ else if (traveler.inventoryUnitId && inventorySource !== "none") {
358
+ const unitIndexes = travelerIndexesByUnitId[traveler.inventoryUnitId] ?? [];
359
+ unitIndexes.push(index);
360
+ travelerIndexesByUnitId[traveler.inventoryUnitId] = unitIndexes;
361
+ }
294
362
  }
295
363
  // Person-priced residual: operator picked N seats but only added M
296
364
  // travelers (M < N) → put the leftover on the option's adult unit
@@ -311,17 +379,20 @@ export function resolveBookingDraft(options) {
311
379
  }
312
380
  /**
313
381
  * Normalize per-person extras to charged traveler quantity and
314
- * stamp `travelerIndexes` + `clientLineKey` so the server can link
382
+ * stamp traveler links + `clientLineKey` so the server can link
315
383
  * each extra line to the travelers it applies to via
316
384
  * `booking_item_travelers`.
317
385
  *
318
386
  * Per-person mode (`pricingMode === "per_person"` or
319
387
  * `pricedPerPerson === true`): quantity multiplied by travelerCount,
320
- * `travelerIndexes` set to all travelers (uniform applicability).
388
+ * `travelerKeys` set to all travelers when stable keys are supplied;
389
+ * otherwise `travelerIndexes` is set as a deprecated fallback.
321
390
  * Non-per-person lines pass through with `clientLineKey` only.
322
391
  */
323
392
  export function resolveBookingExtraLines(options) {
324
393
  const travelerIndexes = Array.from({ length: options.travelerCount }, (_, index) => index);
394
+ const travelerKeys = (options.travelerKeys ?? []).filter((key) => typeof key === "string" && key.trim().length > 0);
395
+ const useTravelerKeys = travelerKeys.length === options.travelerCount;
325
396
  return options.extraLines.map((line) => {
326
397
  const perPerson = line.pricingMode === "per_person" || line.pricedPerPerson === true;
327
398
  if (!perPerson) {
@@ -338,18 +409,22 @@ export function resolveBookingExtraLines(options) {
338
409
  totalSellAmountCents: line.unitSellAmountCents == null
339
410
  ? line.totalSellAmountCents
340
411
  : line.unitSellAmountCents * quantity,
341
- travelerIndexes,
412
+ ...(useTravelerKeys ? { travelerKeys } : { travelerIndexes }),
342
413
  };
343
414
  });
344
415
  }
345
416
  /**
346
417
  * Project a resolved draft's traveler list into the wire-format
347
418
  * `BookingCreateTravelerInput[]` shape the dialog submits. Derives
348
- * the `travelerCategory` from DOB / role and respects the
349
- * `roomUnitAssignmentSource === "none"` carve-out.
419
+ * the `travelerCategory` from DOB / role.
420
+ *
421
+ * `roomUnitId` is a deprecated compatibility alias for the pricing tier
422
+ * option unit. Inventory placement is expressed only by item lines and their
423
+ * `travelerKeys`; the server accepts this field but does not persist it.
350
424
  */
351
425
  export function travelersToRows(value, now = new Date()) {
352
426
  return value.travelers.map((traveler) => ({
427
+ clientTravelerKey: traveler.clientTravelerKey?.trim() || null,
353
428
  personId: traveler.personId,
354
429
  firstName: traveler.firstName.trim(),
355
430
  lastName: traveler.lastName.trim(),
@@ -359,7 +434,7 @@ export function travelersToRows(value, now = new Date()) {
359
434
  participantType: "traveler",
360
435
  travelerCategory: deriveDraftPaxBand(traveler, now),
361
436
  isPrimary: traveler.role === "lead",
362
- roomUnitId: traveler.roomUnitAssignmentSource === "none" ? null : traveler.roomUnitId,
437
+ roomUnitId: traveler.pricingUnitSource === "none" ? null : traveler.pricingUnitId,
363
438
  }));
364
439
  }
365
440
  /**
@@ -375,10 +450,12 @@ export function travelersToRows(value, now = new Date()) {
375
450
  * no legitimate clients trip the warning.
376
451
  *
377
452
  * Notes on the reconstruction:
378
- * - The wire format doesn't carry per-traveler `roomUnitId` (the
379
- * join-table model encodes it through `itemLines[].travelerIndexes`),
380
- * so we reconstruct it by walking item lines and matching them
381
- * to traveler indexes.
453
+ * - The wire format doesn't carry split per-traveler assignment
454
+ * fields (the join-table model encodes them through
455
+ * `itemLines[].travelerKeys`), so we reconstruct the relevant
456
+ * pricing or inventory unit by walking item lines and matching
457
+ * them to traveler keys. Deprecated `travelerIndexes` remain a
458
+ * fallback for older clients.
382
459
  * - DOB doesn't round-trip on the wire today either; we feed the
383
460
  * resolver the `travelerCategory` as a role hint so age-banded
384
461
  * options can still be re-derived.
@@ -388,12 +465,27 @@ export function verifyBookingDraft(input) {
388
465
  return { ok: true, mismatches: [] };
389
466
  }
390
467
  // Walk the submitted itemLines to recover the per-traveler unit
391
- // assignment the client intended. If the client didn't send
392
- // `travelerIndexes` (legacy clients), we can't verify per-traveler
393
- // assignment just compare aggregate quantities.
468
+ // assignment the client intended. Prefer stable `travelerKeys`
469
+ // when present; fall back to deprecated `travelerIndexes` for
470
+ // legacy clients. If neither is present, we can't verify
471
+ // per-traveler assignment — just compare aggregate quantities.
472
+ // Booking-create schema validation rejects unknown traveler keys
473
+ // before this verifier runs.
474
+ const unitById = new Map(input.units.map((unit) => [unit.optionUnitId, unit]));
475
+ const travelerIndexByKey = new Map();
476
+ for (const [index, traveler] of input.travelers.entries()) {
477
+ const key = traveler.clientTravelerKey?.trim();
478
+ if (key && !travelerIndexByKey.has(key))
479
+ travelerIndexByKey.set(key, index);
480
+ }
394
481
  const unitByTravelerIndex = new Map();
395
482
  for (const line of input.itemLines) {
396
- for (const idx of line.travelerIndexes ?? []) {
483
+ const travelerKeys = (line.travelerKeys ?? []).filter((key) => key.trim().length > 0);
484
+ const keyedIndexes = travelerKeys
485
+ .map((key) => travelerIndexByKey.get(key.trim()))
486
+ .filter((index) => typeof index === "number");
487
+ const indexes = travelerKeys.length > 0 ? keyedIndexes : (line.travelerIndexes ?? []);
488
+ for (const idx of indexes) {
397
489
  unitByTravelerIndex.set(idx, line.optionUnitId);
398
490
  }
399
491
  }
@@ -405,6 +497,7 @@ export function verifyBookingDraft(input) {
405
497
  ? cat
406
498
  : "adult";
407
499
  const assigned = unitByTravelerIndex.get(i);
500
+ const assignedUnit = assigned ? unitById.get(assigned) : undefined;
408
501
  return {
409
502
  personId: null,
410
503
  firstName: "",
@@ -423,8 +516,10 @@ export function verifyBookingDraft(input) {
423
516
  // value as ground truth. Otherwise the day-tour bug shape
424
517
  // (3 travelers all manually frozen to Adult) would round-trip
425
518
  // through the verifier unchanged.
426
- roomUnitId: assigned ?? null,
427
- roomUnitAssignmentSource: "auto",
519
+ pricingUnitId: assigned && assignedUnit && isPersonUnit(assignedUnit) ? assigned : null,
520
+ inventoryUnitId: assigned && assignedUnit && isInventoryUnit(assignedUnit) ? assigned : null,
521
+ pricingUnitSource: "auto",
522
+ inventoryUnitSource: "auto",
428
523
  };
429
524
  });
430
525
  // Aggregate submitted quantities for resolver input. For
@@ -333,6 +333,8 @@ export declare const convertProductSchema: z.ZodObject<{
333
333
  description: z.ZodNullable<z.ZodOptional<z.ZodString>>;
334
334
  unitSellAmountCents: z.ZodNullable<z.ZodOptional<z.ZodNumber>>;
335
335
  totalSellAmountCents: z.ZodNullable<z.ZodOptional<z.ZodNumber>>;
336
+ travelerKeys: z.ZodNullable<z.ZodOptional<z.ZodArray<z.ZodString>>>;
337
+ travelerIndexes: z.ZodNullable<z.ZodOptional<z.ZodArray<z.ZodNumber>>>;
336
338
  }, z.core.$strip>>>;
337
339
  }, z.core.$strip>;
338
340
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":"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"}
@@ -198,6 +198,8 @@ export const convertProductSchema = z
198
198
  description: z.string().max(5000).optional().nullable(),
199
199
  unitSellAmountCents: z.number().int().min(0).optional().nullable(),
200
200
  totalSellAmountCents: z.number().int().min(0).optional().nullable(),
201
+ travelerKeys: z.array(z.string().min(1).max(255)).optional().nullable(),
202
+ travelerIndexes: z.array(z.number().int().min(0)).optional().nullable(),
201
203
  }))
202
204
  .optional(),
203
205
  })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voyantjs/bookings",
3
- "version": "0.81.1",
3
+ "version": "0.81.5",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "exports": {
@@ -84,15 +84,15 @@
84
84
  "drizzle-orm": "^0.45.2",
85
85
  "hono": "^4.12.10",
86
86
  "zod": "^4.3.6",
87
- "@voyantjs/action-ledger": "0.81.1",
88
- "@voyantjs/core": "0.81.1",
89
- "@voyantjs/db": "0.81.1",
90
- "@voyantjs/hono": "0.81.1",
91
- "@voyantjs/utils": "0.81.1"
87
+ "@voyantjs/action-ledger": "0.81.5",
88
+ "@voyantjs/core": "0.81.5",
89
+ "@voyantjs/db": "0.81.5",
90
+ "@voyantjs/hono": "0.81.5",
91
+ "@voyantjs/utils": "0.81.5"
92
92
  },
93
93
  "devDependencies": {
94
94
  "typescript": "^6.0.2",
95
- "@voyantjs/products": "0.81.1",
95
+ "@voyantjs/products": "0.81.5",
96
96
  "@voyantjs/voyant-typescript-config": "0.1.0"
97
97
  },
98
98
  "files": [