@voyantjs/customer-portal 0.6.8 → 0.7.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.
@@ -1,4 +1,4 @@
1
- import { bookingDocuments, bookingFulfillments, bookingItemParticipants, bookingItems, bookingParticipants, bookingSessionStates, bookings, } from "@voyantjs/bookings/schema";
1
+ import { bookingDocuments, bookingFulfillments, bookingItems, bookingItemTravelers, bookingSessionStates, bookingStaffAssignments, bookings, bookingTravelers, } from "@voyantjs/bookings/schema";
2
2
  import { crmService, people } from "@voyantjs/crm";
3
3
  import { authUser, travelDocumentSchema, userProfilesTable, } from "@voyantjs/db/schema/iam";
4
4
  import { invoiceRenditions, invoices, payments } from "@voyantjs/finance/schema";
@@ -109,20 +109,6 @@ function getRecord(value) {
109
109
  }
110
110
  return value;
111
111
  }
112
- function formatCustomerAddress(address) {
113
- if (address.fullText) {
114
- return address.fullText;
115
- }
116
- const parts = [
117
- address.line1,
118
- address.line2,
119
- address.city,
120
- address.region,
121
- address.postalCode,
122
- address.country,
123
- ].filter((value) => Boolean(value));
124
- return parts.length > 0 ? parts.join(", ") : null;
125
- }
126
112
  function toCustomerAddress(address) {
127
113
  return {
128
114
  id: address.id,
@@ -358,7 +344,7 @@ async function listLegalDocumentsForBooking(db, bookingId, options = {}) {
358
344
  {
359
345
  id: attachment.id,
360
346
  source: "legal",
361
- participantId: null,
347
+ travelerId: null,
362
348
  type: "contract",
363
349
  fileName: attachment.name,
364
350
  fileUrl: downloadUrl,
@@ -477,7 +463,7 @@ async function getFinanceDataForBooking(db, bookingId, options = {}) {
477
463
  {
478
464
  id: document.invoiceId,
479
465
  source: "finance",
480
- participantId: null,
466
+ travelerId: null,
481
467
  type: document.invoiceType,
482
468
  fileName: resolveFinanceDocumentFileName(document.invoiceNumber, document.invoiceType, document.format),
483
469
  fileUrl: document.downloadUrl,
@@ -600,9 +586,6 @@ async function listCustomerRecordCandidatesByEmail(db, email) {
600
586
  birthday: row.birthday ?? null,
601
587
  email: normalizedEmail,
602
588
  phone: null,
603
- address: null,
604
- city: null,
605
- country: null,
606
589
  billingAddress: null,
607
590
  relation: row.relation ?? null,
608
591
  status: row.status,
@@ -644,9 +627,6 @@ async function listCustomerRecordCandidatesByPhone(db, phone) {
644
627
  birthday: row.birthday ?? null,
645
628
  email: null,
646
629
  phone: normalizedPhone,
647
- address: null,
648
- city: null,
649
- country: null,
650
630
  billingAddress: null,
651
631
  relation: row.relation ?? null,
652
632
  status: row.status,
@@ -676,32 +656,23 @@ async function getCustomerRecord(db, userId) {
676
656
  birthday: person.birthday ?? null,
677
657
  email: person.email ?? null,
678
658
  phone: person.phone ?? null,
679
- address: person.address ?? null,
680
- city: person.city ?? null,
681
- country: person.country ?? null,
682
659
  billingAddress: billingAddress ? toCustomerAddress(billingAddress) : null,
683
660
  relation: person.relation ?? null,
684
661
  status: person.status,
685
662
  };
686
663
  }
687
- async function upsertCustomerBillingAddress(db, personId, input, fallback) {
664
+ async function upsertCustomerBillingAddress(db, personId, input) {
688
665
  const existingAddresses = await identityService.listAddressesForEntity(db, "person", personId);
689
666
  const existingAddress = selectPreferredAddress(existingAddresses);
690
- const fallbackAddress = normalizeNullableString(fallback?.address);
691
- const fallbackCity = normalizeNullableString(fallback?.city);
692
- const fallbackCountry = normalizeNullableString(fallback?.country);
693
667
  const merged = {
694
668
  label: input.label ?? existingAddress?.label ?? "billing",
695
- fullText: normalizeNullableString(input.fullText) ??
696
- (input.line1 === undefined ? fallbackAddress : null) ??
697
- existingAddress?.fullText ??
698
- null,
669
+ fullText: normalizeNullableString(input.fullText) ?? existingAddress?.fullText ?? null,
699
670
  line1: normalizeNullableString(input.line1) ?? existingAddress?.line1 ?? null,
700
671
  line2: normalizeNullableString(input.line2) ?? existingAddress?.line2 ?? null,
701
- city: normalizeNullableString(input.city) ?? fallbackCity ?? existingAddress?.city ?? null,
672
+ city: normalizeNullableString(input.city) ?? existingAddress?.city ?? null,
702
673
  region: normalizeNullableString(input.region) ?? existingAddress?.region ?? null,
703
674
  postalCode: normalizeNullableString(input.postalCode) ?? existingAddress?.postalCode ?? null,
704
- country: normalizeNullableString(input.country) ?? fallbackCountry ?? existingAddress?.country ?? null,
675
+ country: normalizeNullableString(input.country) ?? existingAddress?.country ?? null,
705
676
  isPrimary: input.isPrimary ?? existingAddress?.isPrimary ?? existingAddresses.length === 0,
706
677
  };
707
678
  if (existingAddress) {
@@ -725,27 +696,27 @@ async function getAccessibleBookingIds(db, params) {
725
696
  : Promise.resolve([]),
726
697
  linkedPersonId
727
698
  ? db
728
- .select({ bookingId: bookingParticipants.bookingId })
729
- .from(bookingParticipants)
730
- .where(eq(bookingParticipants.personId, linkedPersonId))
699
+ .select({ bookingId: bookingTravelers.bookingId })
700
+ .from(bookingTravelers)
701
+ .where(eq(bookingTravelers.personId, linkedPersonId))
731
702
  : Promise.resolve([]),
732
703
  db
733
- .select({ bookingId: bookingParticipants.bookingId })
734
- .from(bookingParticipants)
735
- .where(sql `lower(${bookingParticipants.email}) = ${email}`),
704
+ .select({ bookingId: bookingTravelers.bookingId })
705
+ .from(bookingTravelers)
706
+ .where(sql `lower(${bookingTravelers.email}) = ${email}`),
736
707
  ]);
737
708
  return Array.from(new Set([...directBookingRows, ...participantPersonRows, ...participantEmailRows].map((row) => row.bookingId)));
738
709
  }
739
710
  async function hasBookingAccess(params) {
740
- const ownershipConditions = [sql `lower(${bookingParticipants.email}) = ${params.authEmail}`];
711
+ const ownershipConditions = [sql `lower(${bookingTravelers.email}) = ${params.authEmail}`];
741
712
  if (params.linkedPersonId) {
742
- ownershipConditions.push(eq(bookingParticipants.personId, params.linkedPersonId));
713
+ ownershipConditions.push(eq(bookingTravelers.personId, params.linkedPersonId));
743
714
  }
744
715
  const [participantMatch, bookingMatch] = await Promise.all([
745
716
  params.db
746
- .select({ bookingId: bookingParticipants.bookingId })
747
- .from(bookingParticipants)
748
- .where(and(eq(bookingParticipants.bookingId, params.bookingId), or(...ownershipConditions)))
717
+ .select({ bookingId: bookingTravelers.bookingId })
718
+ .from(bookingTravelers)
719
+ .where(and(eq(bookingTravelers.bookingId, params.bookingId), or(...ownershipConditions)))
749
720
  .limit(1),
750
721
  params.linkedPersonId
751
722
  ? params.db
@@ -758,7 +729,22 @@ async function hasBookingAccess(params) {
758
729
  return Boolean(participantMatch[0] || bookingMatch[0]);
759
730
  }
760
731
  async function getBookingBillingContact(db, bookingId, customerRecord) {
761
- const [stateRows, primaryParticipantRows] = await Promise.all([
732
+ const [bookingRows, stateRows, primaryParticipantRows] = await Promise.all([
733
+ db
734
+ .select({
735
+ contactFirstName: bookings.contactFirstName,
736
+ contactLastName: bookings.contactLastName,
737
+ contactEmail: bookings.contactEmail,
738
+ contactPhone: bookings.contactPhone,
739
+ contactCountry: bookings.contactCountry,
740
+ contactRegion: bookings.contactRegion,
741
+ contactCity: bookings.contactCity,
742
+ contactAddressLine1: bookings.contactAddressLine1,
743
+ contactPostalCode: bookings.contactPostalCode,
744
+ })
745
+ .from(bookings)
746
+ .where(eq(bookings.id, bookingId))
747
+ .limit(1),
762
748
  db
763
749
  .select({ payload: bookingSessionStates.payload })
764
750
  .from(bookingSessionStates)
@@ -766,36 +752,53 @@ async function getBookingBillingContact(db, bookingId, customerRecord) {
766
752
  .limit(1),
767
753
  db
768
754
  .select({
769
- firstName: bookingParticipants.firstName,
770
- lastName: bookingParticipants.lastName,
771
- email: bookingParticipants.email,
772
- phone: bookingParticipants.phone,
755
+ firstName: bookingTravelers.firstName,
756
+ lastName: bookingTravelers.lastName,
757
+ email: bookingTravelers.email,
758
+ phone: bookingTravelers.phone,
773
759
  })
774
- .from(bookingParticipants)
775
- .where(and(eq(bookingParticipants.bookingId, bookingId), eq(bookingParticipants.isPrimary, true)))
776
- .orderBy(asc(bookingParticipants.createdAt))
760
+ .from(bookingTravelers)
761
+ .where(and(eq(bookingTravelers.bookingId, bookingId), eq(bookingTravelers.isPrimary, true)))
762
+ .orderBy(asc(bookingTravelers.createdAt))
777
763
  .limit(1),
778
764
  ]);
765
+ const booking = bookingRows[0] ?? null;
779
766
  const stateRow = stateRows[0] ?? null;
780
767
  const primaryParticipant = primaryParticipantRows[0] ?? null;
781
768
  const sessionBillingContact = resolveBillingContactFromSessionPayload(stateRow?.payload ?? null);
782
769
  const billingAddress = customerRecord?.billingAddress ?? null;
783
770
  const result = {
784
- email: sessionBillingContact?.email ?? primaryParticipant?.email ?? customerRecord?.email ?? null,
785
- phone: sessionBillingContact?.phone ?? primaryParticipant?.phone ?? customerRecord?.phone ?? null,
786
- firstName: sessionBillingContact?.firstName ??
771
+ email: booking?.contactEmail ??
772
+ sessionBillingContact?.email ??
773
+ primaryParticipant?.email ??
774
+ customerRecord?.email ??
775
+ null,
776
+ phone: booking?.contactPhone ??
777
+ sessionBillingContact?.phone ??
778
+ primaryParticipant?.phone ??
779
+ customerRecord?.phone ??
780
+ null,
781
+ firstName: booking?.contactFirstName ??
782
+ sessionBillingContact?.firstName ??
787
783
  primaryParticipant?.firstName ??
788
784
  customerRecord?.firstName ??
789
785
  null,
790
- lastName: sessionBillingContact?.lastName ??
786
+ lastName: booking?.contactLastName ??
787
+ sessionBillingContact?.lastName ??
791
788
  primaryParticipant?.lastName ??
792
789
  customerRecord?.lastName ??
793
790
  null,
794
- country: sessionBillingContact?.country ?? billingAddress?.country ?? customerRecord?.country ?? null,
795
- state: sessionBillingContact?.state ?? billingAddress?.region ?? null,
796
- city: sessionBillingContact?.city ?? billingAddress?.city ?? customerRecord?.city ?? null,
797
- address1: sessionBillingContact?.address1 ?? billingAddress?.line1 ?? null,
798
- postal: sessionBillingContact?.postal ?? billingAddress?.postalCode ?? null,
791
+ country: booking?.contactCountry ?? sessionBillingContact?.country ?? billingAddress?.country ?? null,
792
+ state: booking?.contactRegion ?? sessionBillingContact?.state ?? billingAddress?.region ?? null,
793
+ city: booking?.contactCity ?? sessionBillingContact?.city ?? billingAddress?.city ?? null,
794
+ address1: booking?.contactAddressLine1 ??
795
+ sessionBillingContact?.address1 ??
796
+ billingAddress?.line1 ??
797
+ null,
798
+ postal: booking?.contactPostalCode ??
799
+ sessionBillingContact?.postal ??
800
+ billingAddress?.postalCode ??
801
+ null,
799
802
  };
800
803
  const hasValue = Object.values(result).some((value) => typeof value === "string" && value.length > 0);
801
804
  return hasValue ? result : null;
@@ -808,9 +811,9 @@ async function buildBookingDetail(db, bookingId, customerRecord = null, options
808
811
  const [participants, items, itemParticipantLinks, documents, fulfillments, legalDocuments, financeData, billingContact,] = await Promise.all([
809
812
  db
810
813
  .select()
811
- .from(bookingParticipants)
812
- .where(eq(bookingParticipants.bookingId, booking.id))
813
- .orderBy(asc(bookingParticipants.createdAt)),
814
+ .from(bookingTravelers)
815
+ .where(eq(bookingTravelers.bookingId, booking.id))
816
+ .orderBy(asc(bookingTravelers.createdAt)),
814
817
  db
815
818
  .select()
816
819
  .from(bookingItems)
@@ -818,16 +821,16 @@ async function buildBookingDetail(db, bookingId, customerRecord = null, options
818
821
  .orderBy(asc(bookingItems.createdAt)),
819
822
  db
820
823
  .select({
821
- id: bookingItemParticipants.id,
822
- bookingItemId: bookingItemParticipants.bookingItemId,
823
- participantId: bookingItemParticipants.participantId,
824
- role: bookingItemParticipants.role,
825
- isPrimary: bookingItemParticipants.isPrimary,
824
+ id: bookingItemTravelers.id,
825
+ bookingItemId: bookingItemTravelers.bookingItemId,
826
+ travelerId: bookingItemTravelers.travelerId,
827
+ role: bookingItemTravelers.role,
828
+ isPrimary: bookingItemTravelers.isPrimary,
826
829
  })
827
- .from(bookingItemParticipants)
828
- .innerJoin(bookingItems, eq(bookingItems.id, bookingItemParticipants.bookingItemId))
830
+ .from(bookingItemTravelers)
831
+ .innerJoin(bookingItems, eq(bookingItems.id, bookingItemTravelers.bookingItemId))
829
832
  .where(eq(bookingItems.bookingId, booking.id))
830
- .orderBy(asc(bookingItemParticipants.createdAt)),
833
+ .orderBy(asc(bookingItemTravelers.createdAt)),
831
834
  db
832
835
  .select()
833
836
  .from(bookingDocuments)
@@ -847,7 +850,7 @@ async function buildBookingDetail(db, bookingId, customerRecord = null, options
847
850
  const existing = itemLinksByItemId.get(link.bookingItemId) ?? [];
848
851
  existing.push({
849
852
  id: link.id,
850
- participantId: link.participantId,
853
+ travelerId: link.travelerId,
851
854
  role: link.role,
852
855
  isPrimary: link.isPrimary,
853
856
  });
@@ -857,7 +860,7 @@ async function buildBookingDetail(db, bookingId, customerRecord = null, options
857
860
  ...documents.map((document) => ({
858
861
  id: document.id,
859
862
  source: "booking_document",
860
- participantId: document.participantId ?? null,
863
+ travelerId: document.travelerId ?? null,
861
864
  type: document.type,
862
865
  fileName: document.fileName,
863
866
  fileUrl: document.fileUrl,
@@ -871,6 +874,7 @@ async function buildBookingDetail(db, bookingId, customerRecord = null, options
871
874
  documents: financeData.documents,
872
875
  payments: financeData.payments,
873
876
  };
877
+ const travelerParticipants = participants.filter((participant) => ["traveler", "occupant", "other"].includes(participant.participantType));
874
878
  return customerPortalBookingDetailSchema.parse({
875
879
  bookingId: booking.id,
876
880
  bookingNumber: booking.bookingNumber,
@@ -883,7 +887,7 @@ async function buildBookingDetail(db, bookingId, customerRecord = null, options
883
887
  confirmedAt: normalizeDateTime(booking.confirmedAt),
884
888
  cancelledAt: normalizeDateTime(booking.cancelledAt),
885
889
  completedAt: normalizeDateTime(booking.completedAt),
886
- participants: participants.map((participant) => ({
890
+ travelers: travelerParticipants.map((participant) => ({
887
891
  id: participant.id,
888
892
  participantType: participant.participantType,
889
893
  firstName: participant.firstName,
@@ -904,7 +908,7 @@ async function buildBookingDetail(db, bookingId, customerRecord = null, options
904
908
  unitSellAmountCents: item.unitSellAmountCents ?? null,
905
909
  totalSellAmountCents: item.totalSellAmountCents ?? null,
906
910
  notes: item.notes ?? null,
907
- participantLinks: itemLinksByItemId.get(item.id) ?? [],
911
+ travelerLinks: itemLinksByItemId.get(item.id) ?? [],
908
912
  })),
909
913
  billingContact,
910
914
  documents: unifiedDocuments,
@@ -912,7 +916,7 @@ async function buildBookingDetail(db, bookingId, customerRecord = null, options
912
916
  fulfillments: fulfillments.map((fulfillment) => ({
913
917
  id: fulfillment.id,
914
918
  bookingItemId: fulfillment.bookingItemId ?? null,
915
- participantId: fulfillment.participantId ?? null,
919
+ travelerId: fulfillment.travelerId ?? null,
916
920
  fulfillmentType: fulfillment.fulfillmentType,
917
921
  deliveryChannel: fulfillment.deliveryChannel,
918
922
  status: fulfillment.status,
@@ -1021,8 +1025,6 @@ export const publicCustomerPortalService = {
1021
1025
  const nextDateOfBirth = input.dateOfBirth !== undefined ? input.dateOfBirth : undefined;
1022
1026
  const nextAddressRecord = input.address !== undefined
1023
1027
  ? {
1024
- city: input.address.city,
1025
- country: input.address.country,
1026
1028
  billingAddress: {
1027
1029
  line1: input.address.addressLine1,
1028
1030
  line2: input.address.addressLine2,
@@ -1110,13 +1112,9 @@ export const publicCustomerPortalService = {
1110
1112
  }
1111
1113
  : undefined;
1112
1114
  if (nextCustomerRecord || input.firstName !== undefined || input.lastName !== undefined) {
1113
- const billingAddress = nextCustomerRecord?.billingAddress !== undefined
1114
- ? await upsertCustomerBillingAddress(db, customerRecordId, nextCustomerRecord.billingAddress, {
1115
- address: nextCustomerRecord.address,
1116
- city: nextCustomerRecord.city,
1117
- country: nextCustomerRecord.country,
1118
- })
1119
- : null;
1115
+ if (nextCustomerRecord?.billingAddress !== undefined) {
1116
+ await upsertCustomerBillingAddress(db, customerRecordId, nextCustomerRecord.billingAddress);
1117
+ }
1120
1118
  await crmService.updatePerson(db, customerRecordId, {
1121
1119
  ...(input.firstName !== undefined ? { firstName: input.firstName ?? "" } : {}),
1122
1120
  ...(input.lastName !== undefined ? { lastName: input.lastName ?? "" } : {}),
@@ -1130,30 +1128,6 @@ export const publicCustomerPortalService = {
1130
1128
  ? { birthday: nextCustomerRecord.birthday }
1131
1129
  : {}),
1132
1130
  ...(nextCustomerRecord?.phone !== undefined ? { phone: nextCustomerRecord.phone } : {}),
1133
- ...(nextCustomerRecord?.address !== undefined
1134
- ? { address: nextCustomerRecord.address }
1135
- : {}),
1136
- ...(nextCustomerRecord?.city !== undefined ? { city: nextCustomerRecord.city } : {}),
1137
- ...(nextCustomerRecord?.country !== undefined
1138
- ? { country: nextCustomerRecord.country }
1139
- : {}),
1140
- ...(nextCustomerRecord?.billingAddress !== undefined
1141
- ? {
1142
- address: nextCustomerRecord.address !== undefined
1143
- ? nextCustomerRecord.address
1144
- : formatCustomerAddress(billingAddress ?? nextCustomerRecord.billingAddress),
1145
- city: nextCustomerRecord.city !== undefined
1146
- ? nextCustomerRecord.city
1147
- : (normalizeNullableString(nextCustomerRecord.billingAddress.city) ??
1148
- billingAddress?.city ??
1149
- null),
1150
- country: nextCustomerRecord.country !== undefined
1151
- ? nextCustomerRecord.country
1152
- : (normalizeNullableString(nextCustomerRecord.billingAddress.country) ??
1153
- billingAddress?.country ??
1154
- null),
1155
- }
1156
- : {}),
1157
1131
  });
1158
1132
  }
1159
1133
  }
@@ -1231,36 +1205,12 @@ export const publicCustomerPortalService = {
1231
1205
  ? { birthday: input.customerRecord.birthday }
1232
1206
  : {}),
1233
1207
  ...(input.customerRecord?.phone !== undefined ? { phone: input.customerRecord.phone } : {}),
1234
- ...(input.customerRecord?.address !== undefined
1235
- ? { address: input.customerRecord.address }
1236
- : {}),
1237
- ...(input.customerRecord?.city !== undefined ? { city: input.customerRecord.city } : {}),
1238
- ...(input.customerRecord?.country !== undefined
1239
- ? { country: input.customerRecord.country }
1240
- : {}),
1241
- ...(input.customerRecord?.billingAddress !== undefined
1242
- ? {
1243
- address: input.customerRecord.address !== undefined
1244
- ? input.customerRecord.address
1245
- : formatCustomerAddress(input.customerRecord.billingAddress),
1246
- city: input.customerRecord.city !== undefined
1247
- ? input.customerRecord.city
1248
- : (normalizeNullableString(input.customerRecord.billingAddress.city) ?? null),
1249
- country: input.customerRecord.country !== undefined
1250
- ? input.customerRecord.country
1251
- : (normalizeNullableString(input.customerRecord.billingAddress.country) ?? null),
1252
- }
1253
- : {}),
1254
1208
  });
1255
1209
  if (!updated) {
1256
1210
  return { error: "customer_record_not_found" };
1257
1211
  }
1258
1212
  if (input.customerRecord?.billingAddress) {
1259
- await upsertCustomerBillingAddress(db, input.customerRecordId, input.customerRecord.billingAddress, {
1260
- address: input.customerRecord.address,
1261
- city: input.customerRecord.city,
1262
- country: input.customerRecord.country,
1263
- });
1213
+ await upsertCustomerBillingAddress(db, input.customerRecordId, input.customerRecord.billingAddress);
1264
1214
  }
1265
1215
  const profile = await this.getProfile(db, userId);
1266
1216
  return {
@@ -1299,31 +1249,12 @@ export const publicCustomerPortalService = {
1299
1249
  email: normalizedEmail,
1300
1250
  phone: input.customerRecord?.phone ?? null,
1301
1251
  website: null,
1302
- address: input.customerRecord?.billingAddress !== undefined
1303
- ? input.customerRecord.address !== undefined
1304
- ? input.customerRecord.address
1305
- : formatCustomerAddress(input.customerRecord.billingAddress)
1306
- : (input.customerRecord?.address ?? null),
1307
- city: input.customerRecord?.billingAddress !== undefined
1308
- ? input.customerRecord.city !== undefined
1309
- ? input.customerRecord.city
1310
- : (normalizeNullableString(input.customerRecord.billingAddress.city) ?? null)
1311
- : (input.customerRecord?.city ?? null),
1312
- country: input.customerRecord?.billingAddress !== undefined
1313
- ? input.customerRecord.country !== undefined
1314
- ? input.customerRecord.country
1315
- : (normalizeNullableString(input.customerRecord.billingAddress.country) ?? null)
1316
- : (input.customerRecord?.country ?? null),
1317
1252
  });
1318
1253
  if (!created) {
1319
1254
  return { error: "not_found" };
1320
1255
  }
1321
1256
  if (input.customerRecord?.billingAddress) {
1322
- await upsertCustomerBillingAddress(db, created.id, input.customerRecord.billingAddress, {
1323
- address: input.customerRecord.address,
1324
- city: input.customerRecord.city,
1325
- country: input.customerRecord.country,
1326
- });
1257
+ await upsertCustomerBillingAddress(db, created.id, input.customerRecord.billingAddress);
1327
1258
  }
1328
1259
  const profile = await this.getProfile(db, userId);
1329
1260
  return {
@@ -1343,7 +1274,7 @@ export const publicCustomerPortalService = {
1343
1274
  companionMetadataKind)
1344
1275
  .map(toCustomerCompanion);
1345
1276
  },
1346
- async importBookingParticipantsAsCompanions(db, userId, input) {
1277
+ async importBookingTravelersAsCompanions(db, userId, input) {
1347
1278
  const authProfile = await getAuthProfileRow(db, userId);
1348
1279
  const personId = await resolveLinkedCustomerRecordId(db, userId);
1349
1280
  if (!authProfile || !personId) {
@@ -1358,13 +1289,18 @@ export const publicCustomerPortalService = {
1358
1289
  if (targetBookingIds.length === 0) {
1359
1290
  return { created: [], skippedCount: 0 };
1360
1291
  }
1361
- const [existingCompanionRows, participantRows] = await Promise.all([
1292
+ const [existingCompanionRows, participantRows, staffAssignmentRows] = await Promise.all([
1362
1293
  identityService.listNamedContactsForEntity(db, "person", personId),
1363
1294
  db
1364
1295
  .select()
1365
- .from(bookingParticipants)
1366
- .where(inArray(bookingParticipants.bookingId, targetBookingIds))
1367
- .orderBy(asc(bookingParticipants.createdAt)),
1296
+ .from(bookingTravelers)
1297
+ .where(inArray(bookingTravelers.bookingId, targetBookingIds))
1298
+ .orderBy(asc(bookingTravelers.createdAt)),
1299
+ db
1300
+ .select()
1301
+ .from(bookingStaffAssignments)
1302
+ .where(inArray(bookingStaffAssignments.bookingId, targetBookingIds))
1303
+ .orderBy(asc(bookingStaffAssignments.createdAt)),
1368
1304
  ]);
1369
1305
  const existingKeys = new Set(existingCompanionRows
1370
1306
  .filter((row) => (row.metadata?.kind ?? null) ===
@@ -1376,11 +1312,19 @@ export const publicCustomerPortalService = {
1376
1312
  })));
1377
1313
  let skippedCount = 0;
1378
1314
  const created = [];
1315
+ const distinctStaffAssignmentKeys = new Set();
1316
+ for (const assignment of staffAssignmentRows) {
1317
+ distinctStaffAssignmentKeys.add(JSON.stringify([
1318
+ assignment.bookingId,
1319
+ assignment.personId ?? null,
1320
+ assignment.firstName,
1321
+ assignment.lastName,
1322
+ assignment.email ?? null,
1323
+ assignment.phone ?? null,
1324
+ ]));
1325
+ }
1326
+ skippedCount += distinctStaffAssignmentKeys.size;
1379
1327
  for (const participant of participantRows) {
1380
- if (participant.participantType === "staff") {
1381
- skippedCount += 1;
1382
- continue;
1383
- }
1384
1328
  const name = `${participant.firstName} ${participant.lastName}`.trim();
1385
1329
  if (!name) {
1386
1330
  skippedCount += 1;
@@ -1407,7 +1351,7 @@ export const publicCustomerPortalService = {
1407
1351
  metadata: {
1408
1352
  source: "booking_participant_import",
1409
1353
  bookingId: participant.bookingId,
1410
- participantId: participant.id,
1354
+ travelerId: participant.id,
1411
1355
  participantType: participant.participantType,
1412
1356
  travelerCategory: participant.travelerCategory ?? null,
1413
1357
  },
@@ -1428,6 +1372,9 @@ export const publicCustomerPortalService = {
1428
1372
  }
1429
1373
  return { created, skippedCount };
1430
1374
  },
1375
+ async importBookingParticipantsAsCompanions(db, userId, input) {
1376
+ return this.importBookingTravelersAsCompanions(db, userId, input);
1377
+ },
1431
1378
  async createCompanion(db, userId, input) {
1432
1379
  const personId = await resolveLinkedCustomerRecordId(db, userId);
1433
1380
  if (!personId) {
@@ -1522,9 +1469,9 @@ export const publicCustomerPortalService = {
1522
1469
  .orderBy(desc(bookings.createdAt)),
1523
1470
  db
1524
1471
  .select()
1525
- .from(bookingParticipants)
1526
- .where(inArray(bookingParticipants.bookingId, bookingIds))
1527
- .orderBy(asc(bookingParticipants.createdAt)),
1472
+ .from(bookingTravelers)
1473
+ .where(inArray(bookingTravelers.bookingId, bookingIds))
1474
+ .orderBy(asc(bookingTravelers.createdAt)),
1528
1475
  db
1529
1476
  .select({
1530
1477
  bookingId: bookingItems.bookingId,
@@ -1584,7 +1531,7 @@ export const publicCustomerPortalService = {
1584
1531
  pax: booking.pax ?? null,
1585
1532
  confirmedAt: normalizeDateTime(booking.confirmedAt),
1586
1533
  completedAt: normalizeDateTime(booking.completedAt),
1587
- participantCount: participants.length,
1534
+ travelerCount: participants.length,
1588
1535
  primaryTravelerName: primaryTraveler
1589
1536
  ? `${primaryTraveler.firstName} ${primaryTraveler.lastName}`.trim()
1590
1537
  : null,