@bash-app/bash-common 30.236.0 → 30.238.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 (180) hide show
  1. package/dist/__tests__/statusEnums.test.js +88 -7
  2. package/dist/__tests__/statusEnums.test.js.map +1 -1
  3. package/dist/definitions.d.ts +39 -8
  4. package/dist/definitions.d.ts.map +1 -1
  5. package/dist/definitions.js +31 -10
  6. package/dist/definitions.js.map +1 -1
  7. package/dist/extendedSchemas.d.ts +6 -0
  8. package/dist/extendedSchemas.d.ts.map +1 -1
  9. package/dist/extendedSchemas.js.map +1 -1
  10. package/dist/index.d.ts +13 -1
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +16 -4
  13. package/dist/index.js.map +1 -1
  14. package/dist/mirroredPrismaEnums.d.ts +145 -0
  15. package/dist/mirroredPrismaEnums.d.ts.map +1 -0
  16. package/dist/mirroredPrismaEnums.js +136 -0
  17. package/dist/mirroredPrismaEnums.js.map +1 -0
  18. package/dist/utils/__tests__/nonprofitUtils.test.d.ts +2 -0
  19. package/dist/utils/__tests__/nonprofitUtils.test.d.ts.map +1 -0
  20. package/dist/utils/__tests__/nonprofitUtils.test.js +84 -0
  21. package/dist/utils/__tests__/nonprofitUtils.test.js.map +1 -0
  22. package/dist/utils/__tests__/paymentUtils.test.js +87 -0
  23. package/dist/utils/__tests__/paymentUtils.test.js.map +1 -1
  24. package/dist/utils/nonprofitUtils.d.ts +21 -0
  25. package/dist/utils/nonprofitUtils.d.ts.map +1 -0
  26. package/dist/utils/nonprofitUtils.js +29 -0
  27. package/dist/utils/nonprofitUtils.js.map +1 -0
  28. package/dist/utils/paymentUtils.d.ts +23 -0
  29. package/dist/utils/paymentUtils.d.ts.map +1 -1
  30. package/dist/utils/paymentUtils.js +24 -7
  31. package/dist/utils/paymentUtils.js.map +1 -1
  32. package/dist/utils/service/__tests__/billingCapUtils.test.d.ts +2 -0
  33. package/dist/utils/service/__tests__/billingCapUtils.test.d.ts.map +1 -0
  34. package/dist/utils/service/__tests__/billingCapUtils.test.js +120 -0
  35. package/dist/utils/service/__tests__/billingCapUtils.test.js.map +1 -0
  36. package/dist/utils/service/__tests__/cancellationPolicyRefundResolver.test.js +1 -1
  37. package/dist/utils/service/__tests__/cancellationPolicyRefundResolver.test.js.map +1 -1
  38. package/dist/utils/service/__tests__/eventPromoterPhase3.test.d.ts +2 -0
  39. package/dist/utils/service/__tests__/eventPromoterPhase3.test.d.ts.map +1 -0
  40. package/dist/utils/service/__tests__/eventPromoterPhase3.test.js +243 -0
  41. package/dist/utils/service/__tests__/eventPromoterPhase3.test.js.map +1 -0
  42. package/dist/utils/service/__tests__/eventPromoterUtils.test.d.ts +2 -0
  43. package/dist/utils/service/__tests__/eventPromoterUtils.test.d.ts.map +1 -0
  44. package/dist/utils/service/__tests__/eventPromoterUtils.test.js +333 -0
  45. package/dist/utils/service/__tests__/eventPromoterUtils.test.js.map +1 -0
  46. package/dist/utils/service/__tests__/offerAllowListUtils.test.d.ts +2 -0
  47. package/dist/utils/service/__tests__/offerAllowListUtils.test.d.ts.map +1 -0
  48. package/dist/utils/service/__tests__/offerAllowListUtils.test.js +52 -0
  49. package/dist/utils/service/__tests__/offerAllowListUtils.test.js.map +1 -0
  50. package/dist/utils/service/__tests__/offerComparisonUtils.test.d.ts +2 -0
  51. package/dist/utils/service/__tests__/offerComparisonUtils.test.d.ts.map +1 -0
  52. package/dist/utils/service/__tests__/offerComparisonUtils.test.js +111 -0
  53. package/dist/utils/service/__tests__/offerComparisonUtils.test.js.map +1 -0
  54. package/dist/utils/service/__tests__/serviceBookingExposureUtils.test.d.ts +2 -0
  55. package/dist/utils/service/__tests__/serviceBookingExposureUtils.test.d.ts.map +1 -0
  56. package/dist/utils/service/__tests__/serviceBookingExposureUtils.test.js +155 -0
  57. package/dist/utils/service/__tests__/serviceBookingExposureUtils.test.js.map +1 -0
  58. package/dist/utils/service/__tests__/unifiedPricingResolver.test.d.ts +2 -0
  59. package/dist/utils/service/__tests__/unifiedPricingResolver.test.d.ts.map +1 -0
  60. package/dist/utils/service/__tests__/unifiedPricingResolver.test.js +77 -0
  61. package/dist/utils/service/__tests__/unifiedPricingResolver.test.js.map +1 -0
  62. package/dist/utils/service/__tests__/venueFBSettlementUtils.test.d.ts +2 -0
  63. package/dist/utils/service/__tests__/venueFBSettlementUtils.test.d.ts.map +1 -0
  64. package/dist/utils/service/__tests__/venueFBSettlementUtils.test.js +157 -0
  65. package/dist/utils/service/__tests__/venueFBSettlementUtils.test.js.map +1 -0
  66. package/dist/utils/service/__tests__/venueSettlementUtils.test.d.ts +2 -0
  67. package/dist/utils/service/__tests__/venueSettlementUtils.test.d.ts.map +1 -0
  68. package/dist/utils/service/__tests__/venueSettlementUtils.test.js +175 -0
  69. package/dist/utils/service/__tests__/venueSettlementUtils.test.js.map +1 -0
  70. package/dist/utils/service/__tests__/volunteerCompensationUtils.test.d.ts +2 -0
  71. package/dist/utils/service/__tests__/volunteerCompensationUtils.test.d.ts.map +1 -0
  72. package/dist/utils/service/__tests__/volunteerCompensationUtils.test.js +118 -0
  73. package/dist/utils/service/__tests__/volunteerCompensationUtils.test.js.map +1 -0
  74. package/dist/utils/service/apiServiceBookingApiUtils.d.ts.map +1 -1
  75. package/dist/utils/service/apiServiceBookingApiUtils.js +4 -0
  76. package/dist/utils/service/apiServiceBookingApiUtils.js.map +1 -1
  77. package/dist/utils/service/billingCapUtils.d.ts +86 -0
  78. package/dist/utils/service/billingCapUtils.d.ts.map +1 -0
  79. package/dist/utils/service/billingCapUtils.js +96 -0
  80. package/dist/utils/service/billingCapUtils.js.map +1 -0
  81. package/dist/utils/service/cancellationPolicyRefundResolver.d.ts +1 -1
  82. package/dist/utils/service/cancellationPolicyRefundResolver.d.ts.map +1 -1
  83. package/dist/utils/service/cancellationPolicyRefundResolver.js +1 -1
  84. package/dist/utils/service/cancellationPolicyRefundResolver.js.map +1 -1
  85. package/dist/utils/service/eventPromoterUtils.d.ts +319 -0
  86. package/dist/utils/service/eventPromoterUtils.d.ts.map +1 -0
  87. package/dist/utils/service/eventPromoterUtils.js +372 -0
  88. package/dist/utils/service/eventPromoterUtils.js.map +1 -0
  89. package/dist/utils/service/offerAllowListUtils.d.ts +42 -0
  90. package/dist/utils/service/offerAllowListUtils.d.ts.map +1 -0
  91. package/dist/utils/service/offerAllowListUtils.js +49 -0
  92. package/dist/utils/service/offerAllowListUtils.js.map +1 -0
  93. package/dist/utils/service/offerComparisonUtils.d.ts +69 -0
  94. package/dist/utils/service/offerComparisonUtils.d.ts.map +1 -0
  95. package/dist/utils/service/offerComparisonUtils.js +110 -0
  96. package/dist/utils/service/offerComparisonUtils.js.map +1 -0
  97. package/dist/utils/service/serviceBookingExposureUtils.d.ts +111 -0
  98. package/dist/utils/service/serviceBookingExposureUtils.d.ts.map +1 -0
  99. package/dist/utils/service/serviceBookingExposureUtils.js +133 -0
  100. package/dist/utils/service/serviceBookingExposureUtils.js.map +1 -0
  101. package/dist/utils/service/serviceBookingTypes.d.ts +1 -1
  102. package/dist/utils/service/serviceBookingTypes.d.ts.map +1 -1
  103. package/dist/utils/service/serviceUtils.d.ts +2 -1
  104. package/dist/utils/service/serviceUtils.d.ts.map +1 -1
  105. package/dist/utils/service/serviceUtils.js +17 -16
  106. package/dist/utils/service/serviceUtils.js.map +1 -1
  107. package/dist/utils/service/unifiedPricingResolver.d.ts +67 -0
  108. package/dist/utils/service/unifiedPricingResolver.d.ts.map +1 -0
  109. package/dist/utils/service/unifiedPricingResolver.js +75 -0
  110. package/dist/utils/service/unifiedPricingResolver.js.map +1 -0
  111. package/dist/utils/service/venueFBSettlementUtils.d.ts +122 -0
  112. package/dist/utils/service/venueFBSettlementUtils.d.ts.map +1 -0
  113. package/dist/utils/service/venueFBSettlementUtils.js +106 -0
  114. package/dist/utils/service/venueFBSettlementUtils.js.map +1 -0
  115. package/dist/utils/service/venueSettlementUtils.d.ts +107 -0
  116. package/dist/utils/service/venueSettlementUtils.d.ts.map +1 -0
  117. package/dist/utils/service/venueSettlementUtils.js +117 -0
  118. package/dist/utils/service/venueSettlementUtils.js.map +1 -0
  119. package/dist/utils/service/volunteerCompensationUtils.d.ts +75 -0
  120. package/dist/utils/service/volunteerCompensationUtils.d.ts.map +1 -0
  121. package/dist/utils/service/volunteerCompensationUtils.js +88 -0
  122. package/dist/utils/service/volunteerCompensationUtils.js.map +1 -0
  123. package/dist/utils/venueLoyalty/__tests__/eligibilityUtils.test.d.ts +2 -0
  124. package/dist/utils/venueLoyalty/__tests__/eligibilityUtils.test.d.ts.map +1 -0
  125. package/dist/utils/venueLoyalty/__tests__/eligibilityUtils.test.js +67 -0
  126. package/dist/utils/venueLoyalty/__tests__/eligibilityUtils.test.js.map +1 -0
  127. package/dist/utils/venueLoyalty/__tests__/redemptionCodeUtils.test.d.ts +2 -0
  128. package/dist/utils/venueLoyalty/__tests__/redemptionCodeUtils.test.d.ts.map +1 -0
  129. package/dist/utils/venueLoyalty/__tests__/redemptionCodeUtils.test.js +71 -0
  130. package/dist/utils/venueLoyalty/__tests__/redemptionCodeUtils.test.js.map +1 -0
  131. package/dist/utils/venueLoyalty/eligibilityUtils.d.ts +33 -0
  132. package/dist/utils/venueLoyalty/eligibilityUtils.d.ts.map +1 -0
  133. package/dist/utils/venueLoyalty/eligibilityUtils.js +49 -0
  134. package/dist/utils/venueLoyalty/eligibilityUtils.js.map +1 -0
  135. package/dist/utils/venueLoyalty/redemptionCodeUtils.d.ts +35 -0
  136. package/dist/utils/venueLoyalty/redemptionCodeUtils.d.ts.map +1 -0
  137. package/dist/utils/venueLoyalty/redemptionCodeUtils.js +74 -0
  138. package/dist/utils/venueLoyalty/redemptionCodeUtils.js.map +1 -0
  139. package/dist/venueLoyaltyRedemption.d.ts +146 -1
  140. package/dist/venueLoyaltyRedemption.d.ts.map +1 -1
  141. package/dist/venueLoyaltyRedemption.js +18 -2
  142. package/dist/venueLoyaltyRedemption.js.map +1 -1
  143. package/package.json +1 -1
  144. package/prisma/schema.prisma +609 -214
  145. package/src/__tests__/statusEnums.test.ts +119 -11
  146. package/src/definitions.ts +57 -14
  147. package/src/extendedSchemas.ts +6 -0
  148. package/src/index.ts +16 -6
  149. package/src/mirroredPrismaEnums.ts +181 -0
  150. package/src/utils/__tests__/nonprofitUtils.test.ts +117 -0
  151. package/src/utils/__tests__/paymentUtils.test.ts +93 -0
  152. package/src/utils/nonprofitUtils.ts +44 -0
  153. package/src/utils/paymentUtils.ts +33 -7
  154. package/src/utils/service/__tests__/billingCapUtils.test.ts +175 -0
  155. package/src/utils/service/__tests__/cancellationPolicyRefundResolver.test.ts +1 -1
  156. package/src/utils/service/__tests__/eventPromoterPhase3.test.ts +296 -0
  157. package/src/utils/service/__tests__/eventPromoterUtils.test.ts +396 -0
  158. package/src/utils/service/__tests__/offerAllowListUtils.test.ts +76 -0
  159. package/src/utils/service/__tests__/offerComparisonUtils.test.ts +124 -0
  160. package/src/utils/service/__tests__/serviceBookingExposureUtils.test.ts +171 -0
  161. package/src/utils/service/__tests__/unifiedPricingResolver.test.ts +83 -0
  162. package/src/utils/service/__tests__/venueSettlementUtils.test.ts +219 -0
  163. package/src/utils/service/__tests__/volunteerCompensationUtils.test.ts +172 -0
  164. package/src/utils/service/apiServiceBookingApiUtils.ts +4 -0
  165. package/src/utils/service/billingCapUtils.ts +145 -0
  166. package/src/utils/service/cancellationPolicyRefundResolver.ts +1 -1
  167. package/src/utils/service/eventPromoterUtils.ts +644 -0
  168. package/src/utils/service/offerAllowListUtils.ts +81 -0
  169. package/src/utils/service/offerComparisonUtils.ts +197 -0
  170. package/src/utils/service/serviceBookingExposureUtils.ts +218 -0
  171. package/src/utils/service/serviceBookingTypes.ts +4 -0
  172. package/src/utils/service/serviceUtils.ts +18 -21
  173. package/src/utils/service/unifiedPricingResolver.ts +149 -0
  174. package/src/utils/service/venueSettlementUtils.ts +198 -0
  175. package/src/utils/service/volunteerCompensationUtils.ts +145 -0
  176. package/src/utils/venueLoyalty/__tests__/eligibilityUtils.test.ts +103 -0
  177. package/src/utils/venueLoyalty/__tests__/redemptionCodeUtils.test.ts +92 -0
  178. package/src/utils/venueLoyalty/eligibilityUtils.ts +84 -0
  179. package/src/utils/venueLoyalty/redemptionCodeUtils.ts +94 -0
  180. package/src/venueLoyaltyRedemption.ts +177 -2
@@ -1,19 +1,31 @@
1
1
  /**
2
- * Pin the value sets of the three status enums introduced as part of the
2
+ * Pin the value sets of the status enums introduced as part of the
3
3
  * "stringly-typed status" cleanup. These enums are the contract between
4
- * - api endpoints (uploadIdApi, serviceApi, adminDashboardSummaryApi)
5
- * - bash-app UI components (IdRequirementGate, IdVerificationSection,
6
- * CustomScopeRequestsAdminPage, ServicesRatesAndPricing)
4
+ * - api endpoints (uploadIdApi, adminDashboardSummaryApi)
5
+ * - bash-app UI components (IdRequirementGate, IdVerificationSection)
7
6
  * - the database (Postgres ENUM columns)
8
7
  *
9
8
  * Adding/removing/renaming a member without intentionally updating the
10
9
  * migration + all callers should fail this test loudly.
10
+ *
11
+ * ServiceBookingOfferStatus and ServiceBookingOfferDirection are tested via
12
+ * the browser-safe mirrors exported from definitions.ts because Prisma's
13
+ * index-browser bundle omits them as runtime values (they crash on first
14
+ * property access in the browser otherwise).
11
15
  */
16
+ import { GovIdRetentionPolicy, SchoolNameSource } from "@prisma/client";
17
+ import {
18
+ ServiceBookingOfferDirection,
19
+ ServiceBookingOfferStatus,
20
+ } from "../definitions.js";
12
21
  import {
13
- CustomScopeStatus,
14
- GovIdRetentionPolicy,
15
- SchoolNameSource,
16
- } from "@prisma/client";
22
+ BashPointsPayoutSource,
23
+ CreditSourceType,
24
+ FBShortfallResolution,
25
+ PricingModel,
26
+ ServiceBookingSettlementBasis,
27
+ VolunteerCompensationType,
28
+ } from "../mirroredPrismaEnums.js";
17
29
 
18
30
  describe("status enum value sets", () => {
19
31
  test("GovIdRetentionPolicy", () => {
@@ -28,9 +40,105 @@ describe("status enum value sets", () => {
28
40
  );
29
41
  });
30
42
 
31
- test("CustomScopeStatus", () => {
32
- expect(Object.values(CustomScopeStatus).sort()).toEqual(
33
- ["Approved", "None", "Pending", "Rejected"].sort(),
43
+ test("ServiceBookingOfferStatus mirror values match schema", () => {
44
+ expect(Object.values(ServiceBookingOfferStatus).sort()).toEqual(
45
+ ["Accepted", "Countered", "Declined", "Expired", "Pending"].sort(),
46
+ );
47
+ });
48
+
49
+ test("ServiceBookingOfferDirection mirror values match schema", () => {
50
+ expect(Object.values(ServiceBookingOfferDirection).sort()).toEqual(
51
+ ["HostToProvider", "ProviderToHost"].sort(),
52
+ );
53
+ });
54
+
55
+ test("PricingModel mirror values match schema (Phase 1 adds PER_PAID_ATTENDEE + PER_BASHPOINTS_ATTENDEE)", () => {
56
+ expect(Object.values(PricingModel).sort()).toEqual(
57
+ [
58
+ "FLAT_FEE",
59
+ "PER_ATTENDEE",
60
+ "PER_PAID_ATTENDEE",
61
+ "PER_BASHPOINTS_ATTENDEE",
62
+ "HOURLY",
63
+ "PER_DAY",
64
+ "TIERED",
65
+ "CUSTOM",
66
+ "TICKET_REVENUE_PERCENTAGE",
67
+ "PRODUCT_SALES_PERCENTAGE",
68
+ ].sort(),
69
+ );
70
+ });
71
+
72
+ test("BashPointsPayoutSource mirror values match schema", () => {
73
+ expect(Object.values(BashPointsPayoutSource).sort()).toEqual(
74
+ ["BashBpPool", "HostWallet"].sort(),
75
+ );
76
+ });
77
+
78
+ test("ServiceBookingSettlementBasis mirror values match schema (Phase 2 adds FBMinimumShortfall + RevenueShare)", () => {
79
+ expect(Object.values(ServiceBookingSettlementBasis).sort()).toEqual(
80
+ [
81
+ "TicketRevenue",
82
+ "ProductSales",
83
+ "AttendeeCount",
84
+ "FBMinimumShortfall",
85
+ "RevenueShare",
86
+ ].sort(),
87
+ );
88
+ });
89
+
90
+ test("FBShortfallResolution mirror values match schema", () => {
91
+ expect(Object.values(FBShortfallResolution).sort()).toEqual(
92
+ ["ChargeDelta", "CreditFutureBooking", "Forgiven"].sort(),
93
+ );
94
+ });
95
+
96
+ test("VolunteerCompensationType mirror values match schema (narrower than PricingModel by design)", () => {
97
+ expect(Object.values(VolunteerCompensationType).sort()).toEqual(
98
+ [
99
+ "None",
100
+ "BashPointsStipend",
101
+ "PerksOnly",
102
+ "BashPointsAndPerks",
103
+ ].sort(),
104
+ );
105
+ });
106
+
107
+ test("CreditSourceType mirror values match schema (adds VenueLoyaltyRedemption for venue loyalty BP flow)", () => {
108
+ expect(Object.values(CreditSourceType).sort()).toEqual(
109
+ [
110
+ "MembershipReward",
111
+ "TicketPurchase",
112
+ "TicketSale",
113
+ "ServiceBooking",
114
+ "ReferralBonus",
115
+ "SignupBonus",
116
+ "AdminAdjustment",
117
+ "PromotionalBonus",
118
+ "PromoterCommission",
119
+ "GiftedPoints",
120
+ "AmbashadorAchievement",
121
+ "ScoutAchievement",
122
+ "InsiderAchievement",
123
+ "AgentAchievement",
124
+ "ReferralSignupBonus",
125
+ "FirstServiceProfile",
126
+ "FirstBashCreated",
127
+ "FirstTaskTaken",
128
+ "FirstTaskAssigned",
129
+ "FirstFavoriteBash",
130
+ "FirstShareBash",
131
+ "FirstInviteToBash",
132
+ "BirthdayReward",
133
+ "EventReferralReward",
134
+ "RsvpBonus",
135
+ "TicketCheckout",
136
+ "AttendanceBonus",
137
+ "PostBeforeEvent",
138
+ "PostAfterEvent",
139
+ "ReferralCodeUsed",
140
+ "VenueLoyaltyRedemption",
141
+ ].sort(),
34
142
  );
35
143
  });
36
144
  });
@@ -5,7 +5,6 @@ import {
5
5
  BracketType,
6
6
  CompetitionType,
7
7
  Contact,
8
- CustomScopeStatus,
9
8
  EntertainmentServiceType,
10
9
  GovIdRetentionPolicy,
11
10
  JudgingType,
@@ -17,9 +16,14 @@ import {
17
16
  Ticket,
18
17
  TicketTier,
19
18
  User,
20
- YearsOfExperience,
21
19
  } from "@prisma/client";
22
- import type { BashEventDressTags, BashEventVibeTags } from "@prisma/client";
20
+ import type {
21
+ BashEventDressTags,
22
+ BashEventVibeTags,
23
+ ServiceBookingOfferDirection as ServiceBookingOfferDirectionEnum,
24
+ ServiceBookingOfferStatus as ServiceBookingOfferStatusEnum,
25
+ YearsOfExperience as YearsOfExperienceEnum,
26
+ } from "@prisma/client";
23
27
  import {
24
28
  CheckoutExt,
25
29
  PublicUser,
@@ -33,6 +37,37 @@ import { FrontendServiceGetPriceToBookResult } from "./utils/service/frontendSer
33
37
  import { ServiceSubscriptionTier } from "./utils/userSubscriptionUtils.js";
34
38
  import type { UtmFields } from "./utmAttribution.js";
35
39
 
40
+ /**
41
+ * Prisma's `index-browser` bundle (used by Vite in bash-app) omits some enums as runtime
42
+ * values — importing them from `@prisma/client` yields `undefined` and crashes on first
43
+ * property access. These mirrors match the Prisma schema / full client enum strings.
44
+ */
45
+ export const ServiceBookingOfferDirection = {
46
+ HostToProvider: "HostToProvider",
47
+ ProviderToHost: "ProviderToHost",
48
+ } as const satisfies Record<
49
+ ServiceBookingOfferDirectionEnum,
50
+ ServiceBookingOfferDirectionEnum
51
+ >;
52
+
53
+ export const ServiceBookingOfferStatus = {
54
+ Pending: "Pending",
55
+ Accepted: "Accepted",
56
+ Declined: "Declined",
57
+ Countered: "Countered",
58
+ Expired: "Expired",
59
+ } as const satisfies Record<ServiceBookingOfferStatusEnum, ServiceBookingOfferStatusEnum>;
60
+
61
+ /** Mirrors Prisma YearsOfExperience — `@prisma/client` browser/Jest bundles may omit runtime enum keys. */
62
+ export const YearsOfExperience = {
63
+ LessThanOneYear: "LessThanOneYear",
64
+ OneToThreeYears: "OneToThreeYears",
65
+ ThreeToFiveYears: "ThreeToFiveYears",
66
+ FivePlusYears: "FivePlusYears",
67
+ } as const satisfies Record<YearsOfExperienceEnum, YearsOfExperienceEnum>;
68
+
69
+ export type YearsOfExperience = YearsOfExperienceEnum;
70
+
36
71
  export const PASSWORD_MIN_LENGTH = 8 as const;
37
72
  export const PASSWORD_REQUIREMENTS_REGEX = new RegExp(
38
73
  String.raw`^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&^#])[A-Za-z\d@$!%*?&^#]{${PASSWORD_MIN_LENGTH},}$`
@@ -71,6 +106,18 @@ export const BASH_PASS_PRICE_ENV_KEYS: Record<BashPassTier, string> = {
71
106
  [BashPassTier.UNLIMITED]: "STRIPE_BASH_PASS_UNLIMITED_PRICE_ID",
72
107
  };
73
108
 
109
+ /** Per-tier pricing info returned by GET /api/user/bash-pass/pricing. */
110
+ export type BashPassTierPricing = {
111
+ /** Human-readable price string, e.g. "$9.99/mo". */
112
+ displayPrice: string;
113
+ };
114
+
115
+ /** Response shape for GET /api/user/bash-pass/pricing. */
116
+ export type BashPassPricingResponse = {
117
+ /** Map of tier → pricing info. A tier is absent when its Stripe price is unconfigured. */
118
+ tiers: Partial<Record<BashPassTier, BashPassTierPricing>>;
119
+ };
120
+
74
121
  // ─── Ticket.purchaseType values (string column; keep in sync with API writers) ───
75
122
 
76
123
  export const TICKET_PURCHASE_TYPE_USD = "USD" as const;
@@ -991,7 +1038,7 @@ export const DressTagsToString: { [key in BashEventDressTags]: string } = {
991
1038
  // [ServicesTags.AwardRecipient]: "Award recipient"
992
1039
  // }
993
1040
 
994
- export const YearsOfExperienceToString: { [key in YearsOfExperience]: string } =
1041
+ export const YearsOfExperienceToString: { [key in YearsOfExperienceEnum]: string } =
995
1042
  {
996
1043
  [YearsOfExperience.LessThanOneYear]: "Less than one year",
997
1044
  [YearsOfExperience.OneToThreeYears]: "One to three years",
@@ -1004,14 +1051,12 @@ export {
1004
1051
  AgePolicy,
1005
1052
  BracketType,
1006
1053
  CompetitionType,
1007
- CustomScopeStatus,
1008
1054
  EntertainmentServiceType,
1009
1055
  GovIdRetentionPolicy,
1010
1056
  JudgingType,
1011
1057
  MusicGenreType,
1012
1058
  SchoolNameSource,
1013
1059
  ServiceTypes,
1014
- YearsOfExperience,
1015
1060
  };
1016
1061
 
1017
1062
  /**
@@ -1027,14 +1072,12 @@ export const GovIdRetentionPolicyLabel: Record<GovIdRetentionPolicy, string> = {
1027
1072
  [GovIdRetentionPolicy.Indefinite]: "Keep on file (indefinite)",
1028
1073
  };
1029
1074
 
1030
- /**
1031
- * Display labels for `Service.customScopeStatus` (admin dashboard, provider pricing UI).
1032
- */
1033
- export const CustomScopeStatusLabel: Record<CustomScopeStatus, string> = {
1034
- [CustomScopeStatus.None]: "None",
1035
- [CustomScopeStatus.Pending]: "Pending Review",
1036
- [CustomScopeStatus.Approved]: "Approved",
1037
- [CustomScopeStatus.Rejected]: "Rejected",
1075
+ export const ServiceBookingOfferStatusLabel: Record<ServiceBookingOfferStatusEnum, string> = {
1076
+ [ServiceBookingOfferStatus.Pending]: "Pending",
1077
+ [ServiceBookingOfferStatus.Accepted]: "Accepted",
1078
+ [ServiceBookingOfferStatus.Declined]: "Declined",
1079
+ [ServiceBookingOfferStatus.Countered]: "Countered",
1080
+ [ServiceBookingOfferStatus.Expired]: "Expired",
1038
1081
  };
1039
1082
 
1040
1083
  /** Display label for an event's age policy (BashCard pill, filter UI, wizard). */
@@ -365,6 +365,12 @@ export interface BashEventExt extends Omit<
365
365
  // Event page visual customisation (stored as scalar columns on BashEvent)
366
366
  backgroundImage: string | null;
367
367
  themeColor: string | null;
368
+ /**
369
+ * Computed at request time from the host Organization's nonprofit verification.
370
+ * Drives the buyer-facing fee breakdown ("Nonprofit — no Bash platform fee").
371
+ * Optional because not every endpoint that returns BashEventExt resolves the host org.
372
+ */
373
+ isVerifiedNonprofitHost?: boolean;
368
374
  }
369
375
 
370
376
  /**
package/src/index.ts CHANGED
@@ -10,11 +10,12 @@ export * from "./membershipDefinitions.js";
10
10
  export * from "./onSaleCapabilityRecommendations.js";
11
11
  export * from "./aiApproval.js";
12
12
  export * from "./userReportTypes.js";
13
+ export * from "./mirroredPrismaEnums.js";
13
14
 
14
15
  // Re-export ALL Prisma enums as values (usable as runtime constants, e.g. ServiceTypes.Entertainment)
15
- // Excludes enums already re-exported by definitions.ts and membershipDefinitions.ts:
16
- // definitions.ts: YearsOfExperience, EntertainmentServiceType, MusicGenreType, ServiceTypes,
17
- // CompetitionType, JudgingType, BracketType
16
+ // Excludes enums already re-exported by definitions.ts, mirroredPrismaEnums.ts, and membershipDefinitions.ts:
17
+ // mirroredPrismaEnums.ts: ServiceCancellationPolicy
18
+ // definitions.ts: YearsOfExperience, EntertainmentServiceType, MusicGenreType, ServiceTypes,
18
19
  // membershipDefinitions.ts: MembershipTier, ReferralTier, CreditTransactionType
19
20
  export {
20
21
  $Enums,
@@ -63,7 +64,6 @@ export {
63
64
  ConnectionStatus,
64
65
  ConsentType,
65
66
  ConsultantFormat,
66
- CreditSourceType,
67
67
  CreditTransactionStatus,
68
68
  CrewHandFormat,
69
69
  CustomSignageFormat,
@@ -137,7 +137,6 @@ export {
137
137
  ParkingManagementFormat,
138
138
  ParticipantStatus,
139
139
  PartyBusFormat,
140
- PendingGiftStatus,
141
140
  PhotoBoothFormat,
142
141
  PhotographerFormat,
143
142
  PredictionSource,
@@ -171,7 +170,6 @@ export {
171
170
  ServiceBookingRateOption,
172
171
  ServiceBookingStatus,
173
172
  ServiceBookingType,
174
- ServiceCancellationPolicy,
175
173
  ServiceCategoryRequestStatus,
176
174
  ServiceCondition,
177
175
  ServiceIncludeResponse,
@@ -192,6 +190,7 @@ export {
192
190
  StaffingSubType,
193
191
  StageTechFormat,
194
192
  StagingFormat,
193
+ StripeNonprofitPricingStatus,
195
194
  TableStylingFormat,
196
195
  TablesFormat,
197
196
  TaskStatus,
@@ -295,15 +294,26 @@ export type {
295
294
  export * from "./utils/displayDateUtils.js";
296
295
  export * from "./utils/discountEngine/bestPriceResolver.js";
297
296
  export * from "./utils/discountEngine/eligibilityValidator.js";
297
+ export * from "./utils/nonprofitUtils.js";
298
298
  export * from "./utils/objUtils.js";
299
299
  export * from "./utils/paymentUtils.js";
300
300
  export * from "./utils/promoCodesUtils.js";
301
301
  export * from "./utils/qrCodeUtils.js";
302
302
  export * from "./utils/recurrenceUtils.js";
303
303
  export * from "./utils/service/attendeeOptionUtils.js";
304
+ export * from "./utils/service/billingCapUtils.js";
305
+ export * from "./utils/service/eventPromoterUtils.js";
304
306
  export * from "./utils/service/regexUtils.js";
307
+ export * from "./utils/service/serviceBookingExposureUtils.js";
305
308
  export * from "./utils/service/serviceUtils.js";
309
+ export * from "./utils/service/venueSettlementUtils.js";
310
+ export * from "./utils/service/offerAllowListUtils.js";
311
+ export * from "./utils/service/offerComparisonUtils.js";
312
+ export * from "./utils/service/unifiedPricingResolver.js";
313
+ export * from "./utils/service/volunteerCompensationUtils.js";
306
314
  export * from "./utils/service/cancellationPolicyRefundResolver.js";
315
+ export * from "./utils/venueLoyalty/eligibilityUtils.js";
316
+ export * from "./utils/venueLoyalty/redemptionCodeUtils.js";
307
317
  // Venue utils moved to paymentUtils.ts for better organization
308
318
  export * from "./utils/slugUtils.js";
309
319
  export * from "./utils/sortUtils.js";
@@ -0,0 +1,181 @@
1
+ import type {
2
+ BashPointsPayoutSource as BashPointsPayoutSourceEnum,
3
+ CreditSourceType as CreditSourceTypeEnum,
4
+ FBShortfallResolution as FBShortfallResolutionEnum,
5
+ PricingModel as PricingModelEnum,
6
+ ServiceBookingSettlementBasis as ServiceBookingSettlementBasisEnum,
7
+ ServiceBookingSettlementStatus as ServiceBookingSettlementStatusEnum,
8
+ ServiceCancellationPolicy as ServiceCancellationPolicyEnum,
9
+ VolunteerCompensationType as VolunteerCompensationTypeEnum,
10
+ } from "@prisma/client";
11
+
12
+ /**
13
+ * Mirrors Prisma `ServiceCancellationPolicy` — `@prisma/client` browser/Jest bundles may omit
14
+ * runtime enum objects (see `definitions.ts` comment on `index-browser`).
15
+ *
16
+ * Kept dependency-free besides Prisma types so modules like `serviceUtils.ts` can import it without
17
+ * loading `definitions.ts` (which participates in circular imports during index/init).
18
+ */
19
+ export const ServiceCancellationPolicy = {
20
+ None: "None",
21
+ VeryFlexible: "VeryFlexible",
22
+ Flexible: "Flexible",
23
+ Standard90Day: "Standard90Day",
24
+ Standard30Day: "Standard30Day",
25
+ VendorFlexible: "VendorFlexible",
26
+ VendorStandard: "VendorStandard",
27
+ VendorStrict: "VendorStrict",
28
+ ExhibitorFlexible: "ExhibitorFlexible",
29
+ ExhibitorStandard: "ExhibitorStandard",
30
+ ExhibitorStrict: "ExhibitorStrict",
31
+ SponsorFlexible: "SponsorFlexible",
32
+ SponsorStandard: "SponsorStandard",
33
+ SponsorStrict: "SponsorStrict",
34
+ } as const satisfies Record<
35
+ ServiceCancellationPolicyEnum,
36
+ ServiceCancellationPolicyEnum
37
+ >;
38
+
39
+ export type ServiceCancellationPolicy = ServiceCancellationPolicyEnum;
40
+
41
+ /**
42
+ * Mirrors Prisma `ServiceBookingSettlementBasis`. Includes the new
43
+ * `AttendeeCount` basis used by Event Promoter bookings.
44
+ */
45
+ export const ServiceBookingSettlementBasis = {
46
+ TicketRevenue: "TicketRevenue",
47
+ ProductSales: "ProductSales",
48
+ AttendeeCount: "AttendeeCount",
49
+ FBMinimumShortfall: "FBMinimumShortfall",
50
+ RevenueShare: "RevenueShare",
51
+ } as const satisfies Record<
52
+ ServiceBookingSettlementBasisEnum,
53
+ ServiceBookingSettlementBasisEnum
54
+ >;
55
+
56
+ export type ServiceBookingSettlementBasis = ServiceBookingSettlementBasisEnum;
57
+
58
+ /**
59
+ * Mirrors Prisma `FBShortfallResolution`. Describes how a venue F&B minimum
60
+ * shortfall was resolved at settlement — Phase 2 of the unified-pricing
61
+ * roadmap.
62
+ */
63
+ export const FBShortfallResolution = {
64
+ ChargeDelta: "ChargeDelta",
65
+ CreditFutureBooking: "CreditFutureBooking",
66
+ Forgiven: "Forgiven",
67
+ } as const satisfies Record<FBShortfallResolutionEnum, FBShortfallResolutionEnum>;
68
+
69
+ export type FBShortfallResolution = FBShortfallResolutionEnum;
70
+
71
+ /**
72
+ * Mirrors Prisma `ServiceBookingSettlementStatus`. Used to drive Stripe
73
+ * webhook handlers, dunning UI, dispute window, and retry logic on Event
74
+ * Promoter bookings.
75
+ */
76
+ export const ServiceBookingSettlementStatus = {
77
+ Pending: "Pending",
78
+ Settled: "Settled",
79
+ SettlementPaymentFailed: "SettlementPaymentFailed",
80
+ SettlementHeld: "SettlementHeld",
81
+ SettlementDisputed: "SettlementDisputed",
82
+ } as const satisfies Record<
83
+ ServiceBookingSettlementStatusEnum,
84
+ ServiceBookingSettlementStatusEnum
85
+ >;
86
+
87
+ export type ServiceBookingSettlementStatus = ServiceBookingSettlementStatusEnum;
88
+
89
+ /**
90
+ * Mirrors Prisma `PricingModel`. Includes the Phase 1 additions
91
+ * `PER_PAID_ATTENDEE` and `PER_BASHPOINTS_ATTENDEE` introduced by the
92
+ * unified-pricing roadmap.
93
+ */
94
+ export const PricingModel = {
95
+ FLAT_FEE: "FLAT_FEE",
96
+ PER_ATTENDEE: "PER_ATTENDEE",
97
+ PER_PAID_ATTENDEE: "PER_PAID_ATTENDEE",
98
+ PER_BASHPOINTS_ATTENDEE: "PER_BASHPOINTS_ATTENDEE",
99
+ HOURLY: "HOURLY",
100
+ PER_DAY: "PER_DAY",
101
+ TIERED: "TIERED",
102
+ CUSTOM: "CUSTOM",
103
+ TICKET_REVENUE_PERCENTAGE: "TICKET_REVENUE_PERCENTAGE",
104
+ PRODUCT_SALES_PERCENTAGE: "PRODUCT_SALES_PERCENTAGE",
105
+ } as const satisfies Record<PricingModelEnum, PricingModelEnum>;
106
+
107
+ export type PricingModel = PricingModelEnum;
108
+
109
+ /**
110
+ * Mirrors Prisma `BashPointsPayoutSource`. Drives where the BashPoints for a
111
+ * PER_BASHPOINTS_ATTENDEE settlement are paid from — host wallet (default) or
112
+ * the per-bash BashPoints pool that ticket sales fund.
113
+ */
114
+ export const BashPointsPayoutSource = {
115
+ HostWallet: "HostWallet",
116
+ BashBpPool: "BashBpPool",
117
+ } as const satisfies Record<BashPointsPayoutSourceEnum, BashPointsPayoutSourceEnum>;
118
+
119
+ export type BashPointsPayoutSource = BashPointsPayoutSourceEnum;
120
+
121
+ /**
122
+ * Mirrors Prisma `VolunteerCompensationType`. Intentionally NARROWER than
123
+ * `PricingModel` because volunteers are not employees or contractors — see
124
+ * `bash-common/src/utils/service/volunteerCompensationUtils.ts` and the
125
+ * matching help-center page for the policy story.
126
+ */
127
+ export const VolunteerCompensationType = {
128
+ None: "None",
129
+ BashPointsStipend: "BashPointsStipend",
130
+ PerksOnly: "PerksOnly",
131
+ BashPointsAndPerks: "BashPointsAndPerks",
132
+ } as const satisfies Record<
133
+ VolunteerCompensationTypeEnum,
134
+ VolunteerCompensationTypeEnum
135
+ >;
136
+
137
+ export type VolunteerCompensationType = VolunteerCompensationTypeEnum;
138
+
139
+ /**
140
+ * Mirrors Prisma `CreditSourceType`. Includes
141
+ * `VenueLoyaltyRedemption` introduced for the venue loyalty redemption
142
+ * BashPoints flow (claim escrow / decline + expire refund / redeem credit).
143
+ *
144
+ * Centralizing the mirror keeps the BashPoints ledger writers, the host
145
+ * earnings UI, and any analytics views aligned on a single source of truth.
146
+ */
147
+ export const CreditSourceType = {
148
+ MembershipReward: "MembershipReward",
149
+ TicketPurchase: "TicketPurchase",
150
+ TicketSale: "TicketSale",
151
+ ServiceBooking: "ServiceBooking",
152
+ ReferralBonus: "ReferralBonus",
153
+ SignupBonus: "SignupBonus",
154
+ AdminAdjustment: "AdminAdjustment",
155
+ PromotionalBonus: "PromotionalBonus",
156
+ PromoterCommission: "PromoterCommission",
157
+ GiftedPoints: "GiftedPoints",
158
+ AmbashadorAchievement: "AmbashadorAchievement",
159
+ ScoutAchievement: "ScoutAchievement",
160
+ InsiderAchievement: "InsiderAchievement",
161
+ AgentAchievement: "AgentAchievement",
162
+ ReferralSignupBonus: "ReferralSignupBonus",
163
+ FirstServiceProfile: "FirstServiceProfile",
164
+ FirstBashCreated: "FirstBashCreated",
165
+ FirstTaskTaken: "FirstTaskTaken",
166
+ FirstTaskAssigned: "FirstTaskAssigned",
167
+ FirstFavoriteBash: "FirstFavoriteBash",
168
+ FirstShareBash: "FirstShareBash",
169
+ FirstInviteToBash: "FirstInviteToBash",
170
+ BirthdayReward: "BirthdayReward",
171
+ EventReferralReward: "EventReferralReward",
172
+ RsvpBonus: "RsvpBonus",
173
+ TicketCheckout: "TicketCheckout",
174
+ AttendanceBonus: "AttendanceBonus",
175
+ PostBeforeEvent: "PostBeforeEvent",
176
+ PostAfterEvent: "PostAfterEvent",
177
+ ReferralCodeUsed: "ReferralCodeUsed",
178
+ VenueLoyaltyRedemption: "VenueLoyaltyRedemption",
179
+ } as const satisfies Record<CreditSourceTypeEnum, CreditSourceTypeEnum>;
180
+
181
+ export type CreditSourceType = CreditSourceTypeEnum;
@@ -0,0 +1,117 @@
1
+ import { describe, expect, test } from "@jest/globals";
2
+ import {
3
+ isVerifiedNonprofitOrganization,
4
+ type NonprofitVerificationFields,
5
+ } from "../nonprofitUtils.js";
6
+
7
+ const fullyVerified: NonprofitVerificationFields = {
8
+ nonprofitCountry: "US",
9
+ nonprofitRegistrationNumber: "12-3456789",
10
+ nonprofitVerifiedAt: new Date("2025-01-15T00:00:00Z"),
11
+ stripeNonprofitPricingStatus: "NotApplied",
12
+ };
13
+
14
+ describe("isVerifiedNonprofitOrganization", () => {
15
+ test("null returns false", () => {
16
+ expect(isVerifiedNonprofitOrganization(null)).toBe(false);
17
+ });
18
+
19
+ test("undefined returns false", () => {
20
+ expect(isVerifiedNonprofitOrganization(undefined)).toBe(false);
21
+ });
22
+
23
+ test("missing nonprofitVerifiedAt returns false even with country + EIN", () => {
24
+ expect(
25
+ isVerifiedNonprofitOrganization({
26
+ ...fullyVerified,
27
+ nonprofitVerifiedAt: null,
28
+ })
29
+ ).toBe(false);
30
+ });
31
+
32
+ test("missing nonprofitRegistrationNumber returns false", () => {
33
+ expect(
34
+ isVerifiedNonprofitOrganization({
35
+ ...fullyVerified,
36
+ nonprofitRegistrationNumber: null,
37
+ })
38
+ ).toBe(false);
39
+ });
40
+
41
+ test("blank/whitespace nonprofitRegistrationNumber returns false", () => {
42
+ expect(
43
+ isVerifiedNonprofitOrganization({
44
+ ...fullyVerified,
45
+ nonprofitRegistrationNumber: " ",
46
+ })
47
+ ).toBe(false);
48
+ });
49
+
50
+ test("missing nonprofitCountry returns false", () => {
51
+ expect(
52
+ isVerifiedNonprofitOrganization({
53
+ ...fullyVerified,
54
+ nonprofitCountry: null,
55
+ })
56
+ ).toBe(false);
57
+ });
58
+
59
+ test("blank/whitespace nonprofitCountry returns false", () => {
60
+ expect(
61
+ isVerifiedNonprofitOrganization({
62
+ ...fullyVerified,
63
+ nonprofitCountry: " ",
64
+ })
65
+ ).toBe(false);
66
+ });
67
+
68
+ test("all required fields set returns true", () => {
69
+ expect(isVerifiedNonprofitOrganization(fullyVerified)).toBe(true);
70
+ });
71
+
72
+ test("non-US verified charity (e.g. UK) returns true", () => {
73
+ expect(
74
+ isVerifiedNonprofitOrganization({
75
+ ...fullyVerified,
76
+ nonprofitCountry: "GB",
77
+ nonprofitRegistrationNumber: "1234567",
78
+ })
79
+ ).toBe(true);
80
+ });
81
+
82
+ test("Stripe nonprofit-pricing status does NOT affect verification truthiness", () => {
83
+ const statuses: NonprofitVerificationFields["stripeNonprofitPricingStatus"][] = [
84
+ "NotApplied",
85
+ "Pending",
86
+ "Approved",
87
+ "Declined",
88
+ ];
89
+ for (const status of statuses) {
90
+ expect(
91
+ isVerifiedNonprofitOrganization({
92
+ ...fullyVerified,
93
+ stripeNonprofitPricingStatus: status,
94
+ })
95
+ ).toBe(true);
96
+ }
97
+ });
98
+
99
+ test("Declined Stripe status with no Bash verification stamp is still NOT verified", () => {
100
+ expect(
101
+ isVerifiedNonprofitOrganization({
102
+ ...fullyVerified,
103
+ nonprofitVerifiedAt: null,
104
+ stripeNonprofitPricingStatus: "Declined",
105
+ })
106
+ ).toBe(false);
107
+ });
108
+
109
+ test("future nonprofitVerifiedAt is NOT yet verified", () => {
110
+ expect(
111
+ isVerifiedNonprofitOrganization({
112
+ ...fullyVerified,
113
+ nonprofitVerifiedAt: new Date(Date.now() + 60_000),
114
+ })
115
+ ).toBe(false);
116
+ });
117
+ });