@bash-app/bash-common 30.260.1 → 30.263.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 (89) hide show
  1. package/dist/__tests__/serviceCheckoutPaymentMethods.test.d.ts +2 -0
  2. package/dist/__tests__/serviceCheckoutPaymentMethods.test.d.ts.map +1 -0
  3. package/dist/__tests__/serviceCheckoutPaymentMethods.test.js +41 -0
  4. package/dist/__tests__/serviceCheckoutPaymentMethods.test.js.map +1 -0
  5. package/dist/__tests__/ticketBnplPaymentMethods.bankTransfer.test.d.ts +2 -0
  6. package/dist/__tests__/ticketBnplPaymentMethods.bankTransfer.test.d.ts.map +1 -0
  7. package/dist/__tests__/ticketBnplPaymentMethods.bankTransfer.test.js +30 -0
  8. package/dist/__tests__/ticketBnplPaymentMethods.bankTransfer.test.js.map +1 -0
  9. package/dist/__tests__/ticketBnplPaymentMethods.cashapp.test.d.ts +2 -0
  10. package/dist/__tests__/ticketBnplPaymentMethods.cashapp.test.d.ts.map +1 -0
  11. package/dist/__tests__/ticketBnplPaymentMethods.cashapp.test.js +33 -0
  12. package/dist/__tests__/ticketBnplPaymentMethods.cashapp.test.js.map +1 -0
  13. package/dist/__tests__/ticketBnplPaymentMethods.test.d.ts +2 -0
  14. package/dist/__tests__/ticketBnplPaymentMethods.test.d.ts.map +1 -0
  15. package/dist/__tests__/ticketBnplPaymentMethods.test.js +46 -0
  16. package/dist/__tests__/ticketBnplPaymentMethods.test.js.map +1 -0
  17. package/dist/definitions.d.ts +7 -1
  18. package/dist/definitions.d.ts.map +1 -1
  19. package/dist/definitions.js.map +1 -1
  20. package/dist/index.d.ts +6 -0
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +6 -0
  23. package/dist/index.js.map +1 -1
  24. package/dist/ticketBnplPaymentMethods.d.ts +61 -0
  25. package/dist/ticketBnplPaymentMethods.d.ts.map +1 -0
  26. package/dist/ticketBnplPaymentMethods.js +83 -0
  27. package/dist/ticketBnplPaymentMethods.js.map +1 -0
  28. package/dist/utils/__tests__/featuredDiscoveryGeo.test.d.ts +2 -0
  29. package/dist/utils/__tests__/featuredDiscoveryGeo.test.d.ts.map +1 -0
  30. package/dist/utils/__tests__/featuredDiscoveryGeo.test.js +98 -0
  31. package/dist/utils/__tests__/featuredDiscoveryGeo.test.js.map +1 -0
  32. package/dist/utils/__tests__/flyerUtils.test.js +7 -1
  33. package/dist/utils/__tests__/flyerUtils.test.js.map +1 -1
  34. package/dist/utils/__tests__/guestSurface.test.d.ts +2 -0
  35. package/dist/utils/__tests__/guestSurface.test.d.ts.map +1 -0
  36. package/dist/utils/__tests__/guestSurface.test.js +94 -0
  37. package/dist/utils/__tests__/guestSurface.test.js.map +1 -0
  38. package/dist/utils/__tests__/ticketTierSchedule.test.d.ts +2 -0
  39. package/dist/utils/__tests__/ticketTierSchedule.test.d.ts.map +1 -0
  40. package/dist/utils/__tests__/ticketTierSchedule.test.js +84 -0
  41. package/dist/utils/__tests__/ticketTierSchedule.test.js.map +1 -0
  42. package/dist/utils/featuredDiscoveryGeo.d.ts +30 -0
  43. package/dist/utils/featuredDiscoveryGeo.d.ts.map +1 -0
  44. package/dist/utils/featuredDiscoveryGeo.js +47 -0
  45. package/dist/utils/featuredDiscoveryGeo.js.map +1 -0
  46. package/dist/utils/flyerUtils.d.ts +5 -0
  47. package/dist/utils/flyerUtils.d.ts.map +1 -1
  48. package/dist/utils/flyerUtils.js +24 -0
  49. package/dist/utils/flyerUtils.js.map +1 -1
  50. package/dist/utils/guestSurface.d.ts +114 -0
  51. package/dist/utils/guestSurface.d.ts.map +1 -0
  52. package/dist/utils/guestSurface.js +164 -0
  53. package/dist/utils/guestSurface.js.map +1 -0
  54. package/dist/utils/promotionBlastUtils.d.ts +38 -0
  55. package/dist/utils/promotionBlastUtils.d.ts.map +1 -0
  56. package/dist/utils/promotionBlastUtils.js +88 -0
  57. package/dist/utils/promotionBlastUtils.js.map +1 -0
  58. package/dist/utils/service/__tests__/defaultOfferAmountUtils.test.d.ts +2 -0
  59. package/dist/utils/service/__tests__/defaultOfferAmountUtils.test.d.ts.map +1 -0
  60. package/dist/utils/service/__tests__/defaultOfferAmountUtils.test.js +65 -0
  61. package/dist/utils/service/__tests__/defaultOfferAmountUtils.test.js.map +1 -0
  62. package/dist/utils/service/defaultOfferAmountUtils.d.ts +32 -0
  63. package/dist/utils/service/defaultOfferAmountUtils.d.ts.map +1 -0
  64. package/dist/utils/service/defaultOfferAmountUtils.js +115 -0
  65. package/dist/utils/service/defaultOfferAmountUtils.js.map +1 -0
  66. package/dist/utils/ticketTierSchedule.d.ts +58 -0
  67. package/dist/utils/ticketTierSchedule.d.ts.map +1 -0
  68. package/dist/utils/ticketTierSchedule.js +279 -0
  69. package/dist/utils/ticketTierSchedule.js.map +1 -0
  70. package/package.json +5 -2
  71. package/prisma/schema.prisma +340 -1
  72. package/src/__tests__/serviceCheckoutPaymentMethods.test.ts +59 -0
  73. package/src/__tests__/ticketBnplPaymentMethods.bankTransfer.test.ts +42 -0
  74. package/src/__tests__/ticketBnplPaymentMethods.cashapp.test.ts +45 -0
  75. package/src/__tests__/ticketBnplPaymentMethods.test.ts +66 -0
  76. package/src/definitions.ts +7 -1
  77. package/src/index.ts +6 -0
  78. package/src/ticketBnplPaymentMethods.ts +177 -0
  79. package/src/utils/__tests__/featuredDiscoveryGeo.test.ts +120 -0
  80. package/src/utils/__tests__/flyerUtils.test.ts +10 -0
  81. package/src/utils/__tests__/guestSurface.test.ts +128 -0
  82. package/src/utils/__tests__/ticketTierSchedule.test.ts +131 -0
  83. package/src/utils/featuredDiscoveryGeo.ts +75 -0
  84. package/src/utils/flyerUtils.ts +33 -0
  85. package/src/utils/guestSurface.ts +315 -0
  86. package/src/utils/promotionBlastUtils.ts +127 -0
  87. package/src/utils/service/__tests__/defaultOfferAmountUtils.test.ts +102 -0
  88. package/src/utils/service/defaultOfferAmountUtils.ts +170 -0
  89. package/src/utils/ticketTierSchedule.ts +387 -0
@@ -0,0 +1,47 @@
1
+ /** Default featured-discovery radius when the client omits `featuredRadiusMiles`. */
2
+ export const DEFAULT_FEATURED_RADIUS_MILES = 200;
3
+ /**
4
+ * Haversine distance in miles between two WGS84 points.
5
+ */
6
+ export function haversineMiles(lat1, lng1, lat2, lng2) {
7
+ const R = 3958.8;
8
+ const dLat = ((lat2 - lat1) * Math.PI) / 180;
9
+ const dLng = ((lng2 - lng1) * Math.PI) / 180;
10
+ const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
11
+ Math.cos((lat1 * Math.PI) / 180) *
12
+ Math.cos((lat2 * Math.PI) / 180) *
13
+ Math.sin(dLng / 2) *
14
+ Math.sin(dLng / 2);
15
+ const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
16
+ return R * c;
17
+ }
18
+ export function effectiveFeaturedForGeoScope(isFeatured, coordinates, viewer) {
19
+ if (!isFeatured)
20
+ return false;
21
+ if (!viewer)
22
+ return true;
23
+ const first = coordinates?.find((c) => c.lat != null && c.lng != null);
24
+ if (!first || first.lat == null || first.lng == null)
25
+ return false;
26
+ const d = haversineMiles(first.lat, first.lng, viewer.lat, viewer.lng);
27
+ return d <= viewer.radiusMiles;
28
+ }
29
+ /**
30
+ * Sort: effective featured (in geo scope if viewer set) first, then by startDateTime.
31
+ */
32
+ export function sortPublicEventsForFeaturedDiscovery(events, viewer) {
33
+ const withKeys = events.map((e) => {
34
+ const eff = effectiveFeaturedForGeoScope(!!e.isFeatured, e.coordinates, viewer);
35
+ const start = e.startDateTime
36
+ ? new Date(e.startDateTime).getTime()
37
+ : 0;
38
+ return { e, eff, start };
39
+ });
40
+ withKeys.sort((a, b) => {
41
+ if (a.eff !== b.eff)
42
+ return (b.eff ? 1 : 0) - (a.eff ? 1 : 0);
43
+ return a.start - b.start;
44
+ });
45
+ return withKeys.map((x) => x.e);
46
+ }
47
+ //# sourceMappingURL=featuredDiscoveryGeo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"featuredDiscoveryGeo.js","sourceRoot":"","sources":["../../src/utils/featuredDiscoveryGeo.ts"],"names":[],"mappings":"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"}
@@ -48,6 +48,11 @@ export declare function isEddmFlatSizeCompliant(widthIn: number, heightIn: numbe
48
48
  */
49
49
  export declare function quoteFlyerTierForHouseholds(totalHouseholds: number): FlyerTierQuote | null;
50
50
  export declare function computeHostTotalAfterSponsors(printPostageCostCents: number, sponsorRevenueCents: number): number;
51
+ /** Default slot price in cents for Featured vs Supporting flyer slots. */
52
+ export declare function flyerSponsorSlotPriceCents(slot: "FEATURED" | "SUPPORTING_1" | "SUPPORTING_2", requestedPrice?: number): number;
53
+ /** Host revenue share for a flyer sponsor slot. */
54
+ export declare function flyerSponsorSlotHostPct(slot: "FEATURED" | "SUPPORTING_1" | "SUPPORTING_2"): number;
55
+ export declare function flyerSponsorSlotLabel(slot: "FEATURED" | "SUPPORTING_1" | "SUPPORTING_2"): string;
51
56
  /** Haversine distance in miles between two WGS84 points. */
52
57
  export declare function distanceMiles(lat1: number, lng1: number, lat2: number, lng2: number): number;
53
58
  /** URL path for the public QR scan endpoint (prepend API origin in clients). */
@@ -1 +1 @@
1
- {"version":3,"file":"flyerUtils.d.ts","sourceRoot":"","sources":["../../src/utils/flyerUtils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,mBAAmB,OAAO,CAAC;AACxC,eAAO,MAAM,oBAAoB,KAAK,CAAC;AACvC,eAAO,MAAM,uBAAuB,QAAQ,CAAC;AAC7C,eAAO,MAAM,wBAAwB,KAAK,CAAC;AAE3C,uEAAuE;AACvE,eAAO,MAAM,gCAAgC,OAAO,CAAC;AAErD;;;GAGG;AACH,eAAO,MAAM,+BAA+B,MAAM,CAAC;AAEnD,MAAM,MAAM,kBAAkB,GAAG,SAAS,GAAG,cAAc,GAAG,UAAU,GAAG,OAAO,CAAC;AAEnF,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,kBAAkB,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,eAAO,MAAM,mBAAmB,EAAE,cAAc,EA6B/C,CAAC;AAEF,uEAAuE;AACvE,eAAO,MAAM,oCAAoC,QAAQ,CAAC;AAC1D,eAAO,MAAM,sCAAsC,OAAO,CAAC;AAC3D,eAAO,MAAM,sCAAsC,KAAK,CAAC;AACzD,eAAO,MAAM,4BAA4B,KAAK,CAAC;AAC/C,eAAO,MAAM,iCAAiC,KAAK,CAAC;AACpD,eAAO,MAAM,iCAAiC,KAAK,CAAC;AACpD,eAAO,MAAM,4BAA4B,QAAkB,CAAC;AAC5D,eAAO,MAAM,qCAAqC,qEAKxC,CAAC;AAEX,MAAM,WAAW,yBAAyB;IACxC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,MAAM,WAAW,oCAAoC;IACnD,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,yBAAyB,GAC/B,oCAAoC,CAgCtC;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAIlF;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CACzC,eAAe,EAAE,MAAM,GACtB,cAAc,GAAG,IAAI,CAkBvB;AAED,wBAAgB,6BAA6B,CAC3C,qBAAqB,EAAE,MAAM,EAC7B,mBAAmB,EAAE,MAAM,GAC1B,MAAM,CAER;AAID,4DAA4D;AAC5D,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,GACX,MAAM,CAUR;AAED,gFAAgF;AAChF,wBAAgB,eAAe,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,CAE9D;AAED,+DAA+D;AAC/D,wBAAgB,sBAAsB,CACpC,cAAc,EAAE,MAAM,EACtB,aAAa,EAAE,MAAM,GACpB,MAAM,CAIR;AAED;;GAEG;AACH,wBAAgB,yBAAyB,IAAI,MAAM,CAOlD"}
1
+ {"version":3,"file":"flyerUtils.d.ts","sourceRoot":"","sources":["../../src/utils/flyerUtils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,mBAAmB,OAAO,CAAC;AACxC,eAAO,MAAM,oBAAoB,KAAK,CAAC;AACvC,eAAO,MAAM,uBAAuB,QAAQ,CAAC;AAC7C,eAAO,MAAM,wBAAwB,KAAK,CAAC;AAE3C,uEAAuE;AACvE,eAAO,MAAM,gCAAgC,OAAO,CAAC;AAErD;;;GAGG;AACH,eAAO,MAAM,+BAA+B,MAAM,CAAC;AAEnD,MAAM,MAAM,kBAAkB,GAAG,SAAS,GAAG,cAAc,GAAG,UAAU,GAAG,OAAO,CAAC;AAEnF,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,kBAAkB,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,eAAO,MAAM,mBAAmB,EAAE,cAAc,EA6B/C,CAAC;AAEF,uEAAuE;AACvE,eAAO,MAAM,oCAAoC,QAAQ,CAAC;AAC1D,eAAO,MAAM,sCAAsC,OAAO,CAAC;AAC3D,eAAO,MAAM,sCAAsC,KAAK,CAAC;AACzD,eAAO,MAAM,4BAA4B,KAAK,CAAC;AAC/C,eAAO,MAAM,iCAAiC,KAAK,CAAC;AACpD,eAAO,MAAM,iCAAiC,KAAK,CAAC;AACpD,eAAO,MAAM,4BAA4B,QAAkB,CAAC;AAC5D,eAAO,MAAM,qCAAqC,qEAKxC,CAAC;AAEX,MAAM,WAAW,yBAAyB;IACxC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,MAAM,WAAW,oCAAoC;IACnD,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,yBAAyB,GAC/B,oCAAoC,CAgCtC;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAIlF;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CACzC,eAAe,EAAE,MAAM,GACtB,cAAc,GAAG,IAAI,CAkBvB;AAED,wBAAgB,6BAA6B,CAC3C,qBAAqB,EAAE,MAAM,EAC7B,mBAAmB,EAAE,MAAM,GAC1B,MAAM,CAER;AAED,0EAA0E;AAC1E,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,UAAU,GAAG,cAAc,GAAG,cAAc,EAClD,cAAc,CAAC,EAAE,MAAM,GACtB,MAAM,CAKR;AAED,mDAAmD;AACnD,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,UAAU,GAAG,cAAc,GAAG,cAAc,GACjD,MAAM,CAER;AAED,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,UAAU,GAAG,cAAc,GAAG,cAAc,GACjD,MAAM,CAWR;AAID,4DAA4D;AAC5D,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,GACX,MAAM,CAUR;AAED,gFAAgF;AAChF,wBAAgB,eAAe,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,CAE9D;AAED,+DAA+D;AAC/D,wBAAgB,sBAAsB,CACpC,cAAc,EAAE,MAAM,EACtB,aAAa,EAAE,MAAM,GACpB,MAAM,CAIR;AAED;;GAEG;AACH,wBAAgB,yBAAyB,IAAI,MAAM,CAOlD"}
@@ -108,6 +108,30 @@ export function quoteFlyerTierForHouseholds(totalHouseholds) {
108
108
  export function computeHostTotalAfterSponsors(printPostageCostCents, sponsorRevenueCents) {
109
109
  return Math.max(0, printPostageCostCents - sponsorRevenueCents);
110
110
  }
111
+ /** Default slot price in cents for Featured vs Supporting flyer slots. */
112
+ export function flyerSponsorSlotPriceCents(slot, requestedPrice) {
113
+ if (requestedPrice != null)
114
+ return requestedPrice;
115
+ return slot === "FEATURED"
116
+ ? FLYER_SPONSOR_DEFAULT_FEATURED_CENTS
117
+ : FLYER_SPONSOR_DEFAULT_SUPPORTING_CENTS;
118
+ }
119
+ /** Host revenue share for a flyer sponsor slot. */
120
+ export function flyerSponsorSlotHostPct(slot) {
121
+ return slot === "FEATURED" ? 0.6 : 0.65;
122
+ }
123
+ export function flyerSponsorSlotLabel(slot) {
124
+ switch (slot) {
125
+ case "FEATURED":
126
+ return "Featured";
127
+ case "SUPPORTING_1":
128
+ return "Supporting 1";
129
+ case "SUPPORTING_2":
130
+ return "Supporting 2";
131
+ default:
132
+ return slot;
133
+ }
134
+ }
111
135
  const EARTH_RADIUS_MI = 3958.8;
112
136
  /** Haversine distance in miles between two WGS84 points. */
113
137
  export function distanceMiles(lat1, lng1, lat2, lng2) {
@@ -1 +1 @@
1
- {"version":3,"file":"flyerUtils.js","sourceRoot":"","sources":["../../src/utils/flyerUtils.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"flyerUtils.js","sourceRoot":"","sources":["../../src/utils/flyerUtils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,114 @@
1
+ /**
2
+ * Curated guest visibility — shared policy resolver for API + bash-app.
3
+ * Three layers compose: event teaser policy, per-guest visibility, viewer roster depth.
4
+ */
5
+ import type { PublicTeaserUser } from "../extendedSchemas.js";
6
+ export type AttendeeDisplayMode = "All" | "CountOnly" | "NetworkOnly" | "Hidden";
7
+ export type AttendeeVisibility = "Visible" | "Hidden" | "FeaturedPending" | "FeaturedInvited";
8
+ export type GuestListDepth = "None" | "Partial" | "Full";
9
+ export type { PublicTeaserUser };
10
+ export type NetworkOverlapPayload = {
11
+ connections: PublicTeaserUser[];
12
+ contacts: PublicTeaserUser[];
13
+ customLists: Array<{
14
+ listId: string;
15
+ listName: string;
16
+ users: PublicTeaserUser[];
17
+ }>;
18
+ };
19
+ export type GuestSurfacePayload = {
20
+ count: {
21
+ totalTickets: number;
22
+ visibleAttendees: number;
23
+ };
24
+ preview: PublicTeaserUser[];
25
+ featured: PublicTeaserUser[];
26
+ featuredHeadline: string | null;
27
+ network: NetworkOverlapPayload | null;
28
+ upsell: {
29
+ hasDeeperTiers: boolean;
30
+ cheapestTierName?: string;
31
+ } | null;
32
+ roster?: {
33
+ users: PublicTeaserUser[];
34
+ totalVisible: number;
35
+ hasMore: boolean;
36
+ cursor?: string;
37
+ };
38
+ viewer: {
39
+ rosterDepth: GuestListDepth;
40
+ isHost: boolean;
41
+ };
42
+ policy: {
43
+ effectiveMode: AttendeeDisplayMode;
44
+ };
45
+ /** Host-only: user IDs awaiting spotlight approval (guest-initiated) */
46
+ pendingFeaturedUserIds?: string[];
47
+ /** Host-only: user IDs with host-initiated featured invite pending accept */
48
+ pendingFeaturedInviteUserIds?: string[];
49
+ /** Viewer-only: pending featured invite for the authenticated viewer */
50
+ viewerFeaturedInvite?: {
51
+ bashEventId: string;
52
+ bashTitle: string;
53
+ hostName?: string;
54
+ } | null;
55
+ /** Host-only: per-guest visibility for roster management */
56
+ attendeeVisibilityByUserId?: Record<string, AttendeeVisibility>;
57
+ /** Event has public guest list enabled on bash detail */
58
+ attendeeListPublic?: boolean;
59
+ };
60
+ export type AttendeeRosterMeta = {
61
+ depth: GuestListDepth;
62
+ totalVisible?: number;
63
+ hasMore?: boolean;
64
+ cursor?: string;
65
+ };
66
+ export type EventModeInput = {
67
+ attendeeDisplayMode?: string | null;
68
+ showAttendees?: boolean | null;
69
+ };
70
+ export type GuestSurfacePolicyInput = {
71
+ eventMode: AttendeeDisplayMode;
72
+ isHost: boolean;
73
+ isAuthenticated: boolean;
74
+ viewerRosterDepth: GuestListDepth;
75
+ };
76
+ export type GuestSurfacePolicy = {
77
+ showCount: boolean;
78
+ showPreviewAvatars: boolean;
79
+ showFeatured: boolean;
80
+ showNetworkSlice: boolean;
81
+ rosterDepth: GuestListDepth;
82
+ previewLimit: number;
83
+ apiPreviewLimit: number;
84
+ effectiveMode: AttendeeDisplayMode;
85
+ };
86
+ /** Legacy showAttendees=false → Hidden; otherwise honour attendeeDisplayMode string. */
87
+ export declare function resolveEffectiveEventMode(event: EventModeInput): AttendeeDisplayMode;
88
+ export declare function compareGuestListDepth(a: GuestListDepth, b: GuestListDepth): number;
89
+ export declare function maxGuestListDepth(...depths: GuestListDepth[]): GuestListDepth;
90
+ /** Cap viewer tier depth by event mode for non-hosts. */
91
+ export declare function capRosterDepthForEventMode(viewerDepth: GuestListDepth, eventMode: AttendeeDisplayMode, isHost: boolean): GuestListDepth;
92
+ /** Whether the viewer may fetch the full host-style roster endpoint. */
93
+ export declare function viewerMayFetchFullRoster(input: {
94
+ isHost: boolean;
95
+ viewerRosterDepth: GuestListDepth;
96
+ }): boolean;
97
+ /** Public bash-detail teaser policy (Layer 1 + viewer depth cap). */
98
+ export declare function resolveGuestSurfacePolicy(input: GuestSurfacePolicyInput): GuestSurfacePolicy;
99
+ export type PreviewAttendeeRow = {
100
+ userId: string;
101
+ paidOn?: Date | string | null;
102
+ checkedInAt?: Date | string | null;
103
+ };
104
+ /** Featured first, then most recent activity, then stable userId. */
105
+ export declare function orderPreviewAttendeeIds(rows: PreviewAttendeeRow[], featuredUserIds: string[], limit: number): string[];
106
+ export declare function filterHiddenVisibilityUserIds(userIds: string[], visibilityByUserId: Map<string, AttendeeVisibility>, isHost: boolean): string[];
107
+ export declare function filterBlockedUserIds(userIds: string[], blockedIds: Set<string>): string[];
108
+ export declare function guestListDepthFromTierField(value: string | null | undefined): GuestListDepth;
109
+ export declare function computeUpsellFromTiers(tiers: Array<{
110
+ guestListDepth?: string | null;
111
+ title?: string | null;
112
+ price?: number | null;
113
+ }>, viewerDepth: GuestListDepth): GuestSurfacePayload["upsell"];
114
+ //# sourceMappingURL=guestSurface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guestSurface.d.ts","sourceRoot":"","sources":["../../src/utils/guestSurface.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,164 @@
1
+ /**
2
+ * Curated guest visibility — shared policy resolver for API + bash-app.
3
+ * Three layers compose: event teaser policy, per-guest visibility, viewer roster depth.
4
+ */
5
+ const DEPTH_RANK = {
6
+ None: 0,
7
+ Partial: 1,
8
+ Full: 2,
9
+ };
10
+ /** Legacy showAttendees=false → Hidden; otherwise honour attendeeDisplayMode string. */
11
+ export function resolveEffectiveEventMode(event) {
12
+ const raw = event.attendeeDisplayMode;
13
+ if (raw === "CountOnly")
14
+ return "CountOnly";
15
+ if (raw === "NetworkOnly")
16
+ return "NetworkOnly";
17
+ if (raw === "Hidden")
18
+ return "Hidden";
19
+ if (event.showAttendees === false)
20
+ return "Hidden";
21
+ return "All";
22
+ }
23
+ export function compareGuestListDepth(a, b) {
24
+ return DEPTH_RANK[a] - DEPTH_RANK[b];
25
+ }
26
+ export function maxGuestListDepth(...depths) {
27
+ if (depths.length === 0)
28
+ return "None";
29
+ return depths.reduce((max, d) => compareGuestListDepth(d, max) > 0 ? d : max);
30
+ }
31
+ /** Cap viewer tier depth by event mode for non-hosts. */
32
+ export function capRosterDepthForEventMode(viewerDepth, eventMode, isHost) {
33
+ if (isHost)
34
+ return "Full";
35
+ if (eventMode === "Hidden")
36
+ return "None";
37
+ if (eventMode === "NetworkOnly")
38
+ return "None";
39
+ return viewerDepth;
40
+ }
41
+ /** Whether the viewer may fetch the full host-style roster endpoint. */
42
+ export function viewerMayFetchFullRoster(input) {
43
+ if (input.isHost)
44
+ return true;
45
+ return compareGuestListDepth(input.viewerRosterDepth, "Partial") >= 0;
46
+ }
47
+ /** Public bash-detail teaser policy (Layer 1 + viewer depth cap). */
48
+ export function resolveGuestSurfacePolicy(input) {
49
+ const { eventMode, isHost, isAuthenticated, viewerRosterDepth } = input;
50
+ const effectiveDepth = capRosterDepthForEventMode(viewerRosterDepth, eventMode, isHost);
51
+ if (eventMode === "Hidden" && !isHost) {
52
+ return {
53
+ showCount: false,
54
+ showPreviewAvatars: false,
55
+ showFeatured: false,
56
+ showNetworkSlice: false,
57
+ rosterDepth: "None",
58
+ previewLimit: 4,
59
+ apiPreviewLimit: 10,
60
+ effectiveMode: eventMode,
61
+ };
62
+ }
63
+ if (eventMode === "CountOnly" && !isHost) {
64
+ return {
65
+ showCount: true,
66
+ showPreviewAvatars: false,
67
+ showFeatured: false,
68
+ showNetworkSlice: isAuthenticated,
69
+ rosterDepth: effectiveDepth,
70
+ previewLimit: 4,
71
+ apiPreviewLimit: 10,
72
+ effectiveMode: eventMode,
73
+ };
74
+ }
75
+ const showCount = true;
76
+ const showPreviewAvatars = eventMode === "All" && !isHost
77
+ ? true
78
+ : eventMode === "All" && isHost
79
+ ? true
80
+ : false;
81
+ const showFeatured = (eventMode === "All" || isHost) && eventMode !== "CountOnly";
82
+ const showNetworkSlice = isAuthenticated &&
83
+ (eventMode === "All" ||
84
+ eventMode === "CountOnly" ||
85
+ eventMode === "NetworkOnly" ||
86
+ isHost);
87
+ return {
88
+ showCount,
89
+ showPreviewAvatars: showPreviewAvatars &&
90
+ eventMode !== "CountOnly" &&
91
+ eventMode !== "NetworkOnly",
92
+ showFeatured: showFeatured && eventMode !== "NetworkOnly",
93
+ showNetworkSlice,
94
+ rosterDepth: effectiveDepth,
95
+ previewLimit: 4,
96
+ apiPreviewLimit: 10,
97
+ effectiveMode: eventMode,
98
+ };
99
+ }
100
+ /** Featured first, then most recent activity, then stable userId. */
101
+ export function orderPreviewAttendeeIds(rows, featuredUserIds, limit) {
102
+ const featuredSet = new Set(featuredUserIds);
103
+ const byUser = new Map();
104
+ for (const row of rows) {
105
+ if (!row.userId)
106
+ continue;
107
+ const existing = byUser.get(row.userId);
108
+ if (!existing) {
109
+ byUser.set(row.userId, row);
110
+ continue;
111
+ }
112
+ const existingTs = activityTimestamp(existing);
113
+ const rowTs = activityTimestamp(row);
114
+ if (rowTs > existingTs)
115
+ byUser.set(row.userId, row);
116
+ }
117
+ const featuredOrdered = featuredUserIds.filter((id) => byUser.has(id));
118
+ const rest = [...byUser.entries()]
119
+ .filter(([id]) => !featuredSet.has(id))
120
+ .sort(([, a], [, b]) => {
121
+ const diff = activityTimestamp(b) - activityTimestamp(a);
122
+ if (diff !== 0)
123
+ return diff;
124
+ return a.userId.localeCompare(b.userId);
125
+ })
126
+ .map(([id]) => id);
127
+ return [...featuredOrdered, ...rest].slice(0, limit);
128
+ }
129
+ function activityTimestamp(row) {
130
+ const paid = row.paidOn != null ? new Date(row.paidOn).getTime() : 0;
131
+ const checked = row.checkedInAt != null
132
+ ? new Date(row.checkedInAt).getTime()
133
+ : 0;
134
+ return Math.max(paid, checked);
135
+ }
136
+ export function filterHiddenVisibilityUserIds(userIds, visibilityByUserId, isHost) {
137
+ if (isHost)
138
+ return userIds;
139
+ return userIds.filter((id) => {
140
+ const v = visibilityByUserId.get(id) ?? "Visible";
141
+ return v === "Visible" || v === "FeaturedPending";
142
+ // FeaturedInvited is hidden until the guest accepts
143
+ });
144
+ }
145
+ export function filterBlockedUserIds(userIds, blockedIds) {
146
+ return userIds.filter((id) => !blockedIds.has(id));
147
+ }
148
+ export function guestListDepthFromTierField(value) {
149
+ if (value === "Partial" || value === "Full")
150
+ return value;
151
+ return "None";
152
+ }
153
+ export function computeUpsellFromTiers(tiers, viewerDepth) {
154
+ const deeper = tiers.filter((t) => compareGuestListDepth(guestListDepthFromTierField(t.guestListDepth), "None") > 0);
155
+ if (deeper.length === 0 || compareGuestListDepth(viewerDepth, "Partial") >= 0) {
156
+ return null;
157
+ }
158
+ const sorted = [...deeper].sort((a, b) => (a.price ?? 0) - (b.price ?? 0));
159
+ return {
160
+ hasDeeperTiers: true,
161
+ cheapestTierName: sorted[0]?.title ?? undefined,
162
+ };
163
+ }
164
+ //# sourceMappingURL=guestSurface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guestSurface.js","sourceRoot":"","sources":["../../src/utils/guestSurface.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Promotion Blast — on-site partner promos (time-boxed + geofence).
3
+ */
4
+ export type PromotionBlastPackageTierId = "starter" | "standard" | "premium";
5
+ export type PromotionBlastTriggerTypeId = "TIME_BOXED" | "GEOFENCE";
6
+ export interface PromotionBlastPackageTerms {
7
+ tierId: PromotionBlastPackageTierId;
8
+ maxBlasts: number;
9
+ maxPushRecipients?: number | null;
10
+ maxRadiusFeet: number;
11
+ allowedTriggerTypes: PromotionBlastTriggerTypeId[];
12
+ hostAccessFeeCents: number;
13
+ bashPlatformFeeCents: number;
14
+ templateId?: string | null;
15
+ }
16
+ /** Minutes before event start when partners may activate blasts. */
17
+ export declare const PROMOTION_BLAST_EVENT_WINDOW_BEFORE_MINUTES = 30;
18
+ /** Minutes after event end when partners may still activate. */
19
+ export declare const PROMOTION_BLAST_EVENT_WINDOW_AFTER_MINUTES = 30;
20
+ /** Max concurrently live partner promos per event. */
21
+ export declare const PROMOTION_BLAST_MAX_LIVE_PER_EVENT = 5;
22
+ /** Max promotional pushes per attendee per event (all partners). */
23
+ export declare const PROMOTION_BLAST_MAX_PUSHES_PER_USER_PER_EVENT = 3;
24
+ /** Min minutes between promo pushes to same user at same event. */
25
+ export declare const PROMOTION_BLAST_MIN_PUSH_INTERVAL_MINUTES = 15;
26
+ export declare const PROMOTION_BLAST_HEADLINE_MAX_LENGTH = 80;
27
+ export declare const PROMOTION_BLAST_BODY_MAX_LENGTH = 280;
28
+ export declare const PROMOTION_BLAST_CTA_MAX_LENGTH = 40;
29
+ export declare const PROMOTION_BLAST_DURATION_PRESETS_MINUTES: readonly [15, 30, 60];
30
+ export declare const PROMOTION_BLAST_RADIUS_PRESETS_FEET: readonly [100, 200, 500];
31
+ export declare const PROMOTION_BLAST_PACKAGES: Record<PromotionBlastPackageTierId, Omit<PromotionBlastPackageTerms, "hostAccessFeeCents" | "templateId">>;
32
+ export declare function promotionBlastPackageForTier(tierId: PromotionBlastPackageTierId, hostAccessFeeCents: number, templateId?: string | null): PromotionBlastPackageTerms;
33
+ export declare function promotionBlastPackageTotalCents(pkg: PromotionBlastPackageTerms): number;
34
+ export declare function promotionBlastPackageLabel(tierId: PromotionBlastPackageTierId): string;
35
+ export declare function isWithinPromotionBlastEventWindow(eventStart: Date, eventEnd: Date | null | undefined, now?: Date): boolean;
36
+ export declare function generatePromotionBlastConfirmationCode(): string;
37
+ export declare function promotionBlastDeepLinkPath(bashEventId: string, blastId: string): string;
38
+ //# sourceMappingURL=promotionBlastUtils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promotionBlastUtils.d.ts","sourceRoot":"","sources":["../../src/utils/promotionBlastUtils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,MAAM,2BAA2B,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,CAAC;AAE7E,MAAM,MAAM,2BAA2B,GAAG,YAAY,GAAG,UAAU,CAAC;AAEpE,MAAM,WAAW,0BAA0B;IACzC,MAAM,EAAE,2BAA2B,CAAC;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,aAAa,EAAE,MAAM,CAAC;IACtB,mBAAmB,EAAE,2BAA2B,EAAE,CAAC;IACnD,kBAAkB,EAAE,MAAM,CAAC;IAC3B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,oEAAoE;AACpE,eAAO,MAAM,2CAA2C,KAAK,CAAC;AAE9D,gEAAgE;AAChE,eAAO,MAAM,0CAA0C,KAAK,CAAC;AAE7D,sDAAsD;AACtD,eAAO,MAAM,kCAAkC,IAAI,CAAC;AAEpD,oEAAoE;AACpE,eAAO,MAAM,6CAA6C,IAAI,CAAC;AAE/D,mEAAmE;AACnE,eAAO,MAAM,yCAAyC,KAAK,CAAC;AAE5D,eAAO,MAAM,mCAAmC,KAAK,CAAC;AACtD,eAAO,MAAM,+BAA+B,MAAM,CAAC;AACnD,eAAO,MAAM,8BAA8B,KAAK,CAAC;AAEjD,eAAO,MAAM,wCAAwC,uBAAwB,CAAC;AAC9E,eAAO,MAAM,mCAAmC,0BAA2B,CAAC;AAE5E,eAAO,MAAM,wBAAwB,EAAE,MAAM,CAC3C,2BAA2B,EAC3B,IAAI,CAAC,0BAA0B,EAAE,oBAAoB,GAAG,YAAY,CAAC,CA0BtE,CAAC;AAEF,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,2BAA2B,EACnC,kBAAkB,EAAE,MAAM,EAC1B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,GACzB,0BAA0B,CAO5B;AAED,wBAAgB,+BAA+B,CAAC,GAAG,EAAE,0BAA0B,GAAG,MAAM,CAEvF;AAED,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,2BAA2B,GAAG,MAAM,CAWtF;AAED,wBAAgB,iCAAiC,CAC/C,UAAU,EAAE,IAAI,EAChB,QAAQ,EAAE,IAAI,GAAG,IAAI,GAAG,SAAS,EACjC,GAAG,GAAE,IAAiB,GACrB,OAAO,CAQT;AAED,wBAAgB,sCAAsC,IAAI,MAAM,CAO/D;AAED,wBAAgB,0BAA0B,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAEvF"}
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Promotion Blast — on-site partner promos (time-boxed + geofence).
3
+ */
4
+ /** Minutes before event start when partners may activate blasts. */
5
+ export const PROMOTION_BLAST_EVENT_WINDOW_BEFORE_MINUTES = 30;
6
+ /** Minutes after event end when partners may still activate. */
7
+ export const PROMOTION_BLAST_EVENT_WINDOW_AFTER_MINUTES = 30;
8
+ /** Max concurrently live partner promos per event. */
9
+ export const PROMOTION_BLAST_MAX_LIVE_PER_EVENT = 5;
10
+ /** Max promotional pushes per attendee per event (all partners). */
11
+ export const PROMOTION_BLAST_MAX_PUSHES_PER_USER_PER_EVENT = 3;
12
+ /** Min minutes between promo pushes to same user at same event. */
13
+ export const PROMOTION_BLAST_MIN_PUSH_INTERVAL_MINUTES = 15;
14
+ export const PROMOTION_BLAST_HEADLINE_MAX_LENGTH = 80;
15
+ export const PROMOTION_BLAST_BODY_MAX_LENGTH = 280;
16
+ export const PROMOTION_BLAST_CTA_MAX_LENGTH = 40;
17
+ export const PROMOTION_BLAST_DURATION_PRESETS_MINUTES = [15, 30, 60];
18
+ export const PROMOTION_BLAST_RADIUS_PRESETS_FEET = [100, 200, 500];
19
+ export const PROMOTION_BLAST_PACKAGES = {
20
+ starter: {
21
+ tierId: "starter",
22
+ maxBlasts: 1,
23
+ maxPushRecipients: null,
24
+ maxRadiusFeet: 200,
25
+ allowedTriggerTypes: ["TIME_BOXED"],
26
+ bashPlatformFeeCents: 500,
27
+ },
28
+ standard: {
29
+ tierId: "standard",
30
+ maxBlasts: 3,
31
+ maxPushRecipients: null,
32
+ maxRadiusFeet: 500,
33
+ allowedTriggerTypes: ["TIME_BOXED", "GEOFENCE"],
34
+ bashPlatformFeeCents: 1200,
35
+ },
36
+ premium: {
37
+ tierId: "premium",
38
+ maxBlasts: 999,
39
+ maxPushRecipients: null,
40
+ maxRadiusFeet: 500,
41
+ allowedTriggerTypes: ["TIME_BOXED", "GEOFENCE"],
42
+ bashPlatformFeeCents: 2500,
43
+ },
44
+ };
45
+ export function promotionBlastPackageForTier(tierId, hostAccessFeeCents, templateId) {
46
+ const base = PROMOTION_BLAST_PACKAGES[tierId];
47
+ return {
48
+ ...base,
49
+ hostAccessFeeCents,
50
+ templateId: templateId ?? null,
51
+ };
52
+ }
53
+ export function promotionBlastPackageTotalCents(pkg) {
54
+ return pkg.hostAccessFeeCents + pkg.bashPlatformFeeCents;
55
+ }
56
+ export function promotionBlastPackageLabel(tierId) {
57
+ switch (tierId) {
58
+ case "starter":
59
+ return "Starter — 1 time-boxed blast";
60
+ case "standard":
61
+ return "Standard — 3 blasts + geofence";
62
+ case "premium":
63
+ return "Premium — unlimited blasts + geofence";
64
+ default:
65
+ return tierId;
66
+ }
67
+ }
68
+ export function isWithinPromotionBlastEventWindow(eventStart, eventEnd, now = new Date()) {
69
+ const windowStart = new Date(eventStart);
70
+ windowStart.setMinutes(windowStart.getMinutes() - PROMOTION_BLAST_EVENT_WINDOW_BEFORE_MINUTES);
71
+ const windowEnd = eventEnd
72
+ ? new Date(eventEnd)
73
+ : new Date(eventStart.getTime() + 4 * 60 * 60 * 1000);
74
+ windowEnd.setMinutes(windowEnd.getMinutes() + PROMOTION_BLAST_EVENT_WINDOW_AFTER_MINUTES);
75
+ return now >= windowStart && now <= windowEnd;
76
+ }
77
+ export function generatePromotionBlastConfirmationCode() {
78
+ const chars = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789";
79
+ let code = "";
80
+ for (let i = 0; i < 6; i++) {
81
+ code += chars[Math.floor(Math.random() * chars.length)];
82
+ }
83
+ return code;
84
+ }
85
+ export function promotionBlastDeepLinkPath(bashEventId, blastId) {
86
+ return `/bash/${encodeURIComponent(bashEventId)}?tab=promotions&blast=${encodeURIComponent(blastId)}`;
87
+ }
88
+ //# sourceMappingURL=promotionBlastUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promotionBlastUtils.js","sourceRoot":"","sources":["../../src/utils/promotionBlastUtils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=defaultOfferAmountUtils.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defaultOfferAmountUtils.test.d.ts","sourceRoot":"","sources":["../../../../src/utils/service/__tests__/defaultOfferAmountUtils.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,65 @@
1
+ import { calcLegacyRateEstimateCents, computeBashEventDurationHours, getDefaultOfferAmountCents, isBulkHostOfferEligible, } from "../defaultOfferAmountUtils.js";
2
+ describe("calcLegacyRateEstimateCents", () => {
3
+ it("uses flat rate when set", () => {
4
+ expect(calcLegacyRateEstimateCents({ flatRateCents: 50_000 }, 4)).toBe(50_000);
5
+ });
6
+ it("uses daily rate for 8+ hour events", () => {
7
+ expect(calcLegacyRateEstimateCents({ hourlyRateCents: 15_000, dailyRateCents: 50_000 }, 8)).toBe(50_000);
8
+ });
9
+ it("uses hourly × duration for shorter events", () => {
10
+ expect(calcLegacyRateEstimateCents({ hourlyRateCents: 15_000, dailyRateCents: 50_000 }, 4)).toBe(60_000);
11
+ });
12
+ });
13
+ describe("computeBashEventDurationHours", () => {
14
+ it("returns hours between start and end", () => {
15
+ expect(computeBashEventDurationHours("2026-06-01T18:00:00.000Z", "2026-06-01T22:00:00.000Z")).toBe(4);
16
+ });
17
+ it("defaults to 1 when dates missing", () => {
18
+ expect(computeBashEventDurationHours(null, null)).toBe(1);
19
+ });
20
+ });
21
+ describe("getDefaultOfferAmountCents", () => {
22
+ it("prefers unified HOURLY model with duration", () => {
23
+ expect(getDefaultOfferAmountCents({
24
+ service: {
25
+ entertainmentService: {
26
+ pricingModel: "HOURLY",
27
+ baseRateCents: 20_000,
28
+ },
29
+ },
30
+ durationHours: 3,
31
+ })).toBe(60_000);
32
+ });
33
+ it("falls back to legacy general rates", () => {
34
+ expect(getDefaultOfferAmountCents({
35
+ service: {
36
+ serviceRatesAssociation: {
37
+ serviceGeneralRates: { dailyRateCents: 75_000 },
38
+ },
39
+ },
40
+ durationHours: 10,
41
+ })).toBe(75_000);
42
+ });
43
+ it("computes PER_ATTENDEE from expected guests", () => {
44
+ expect(getDefaultOfferAmountCents({
45
+ service: {
46
+ eventService: {
47
+ pricingModel: "PER_ATTENDEE",
48
+ baseRateCents: 500,
49
+ },
50
+ },
51
+ durationHours: 4,
52
+ expectedAttendees: 100,
53
+ })).toBe(50_000);
54
+ });
55
+ });
56
+ describe("isBulkHostOfferEligible", () => {
57
+ it("rejects participation-fee services", () => {
58
+ expect(isBulkHostOfferEligible(50_000, true)).toBe(false);
59
+ });
60
+ it("requires a positive amount", () => {
61
+ expect(isBulkHostOfferEligible(0, false)).toBe(false);
62
+ expect(isBulkHostOfferEligible(25_000, false)).toBe(true);
63
+ });
64
+ });
65
+ //# sourceMappingURL=defaultOfferAmountUtils.test.js.map