@bash-app/bash-common 30.371.0 → 30.374.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 (37) hide show
  1. package/dist/definitions.d.ts +6 -0
  2. package/dist/definitions.d.ts.map +1 -1
  3. package/dist/definitions.js.map +1 -1
  4. package/dist/utils/__tests__/organizationEntitlements.test.js +66 -27
  5. package/dist/utils/__tests__/organizationEntitlements.test.js.map +1 -1
  6. package/dist/utils/luxonUtils.d.ts +7 -7
  7. package/dist/utils/luxonUtils.d.ts.map +1 -1
  8. package/dist/utils/organizationEntitlements.d.ts +23 -18
  9. package/dist/utils/organizationEntitlements.d.ts.map +1 -1
  10. package/dist/utils/organizationEntitlements.js +37 -22
  11. package/dist/utils/organizationEntitlements.js.map +1 -1
  12. package/dist/utils/service/__tests__/apiServiceBookingApiUtils.test.js +66 -1
  13. package/dist/utils/service/__tests__/apiServiceBookingApiUtils.test.js.map +1 -1
  14. package/dist/utils/service/__tests__/frontendServiceBookingUtils.test.d.ts +2 -0
  15. package/dist/utils/service/__tests__/frontendServiceBookingUtils.test.d.ts.map +1 -0
  16. package/dist/utils/service/__tests__/frontendServiceBookingUtils.test.js +165 -0
  17. package/dist/utils/service/__tests__/frontendServiceBookingUtils.test.js.map +1 -0
  18. package/dist/utils/service/apiServiceBookingApiUtils.d.ts +5 -3
  19. package/dist/utils/service/apiServiceBookingApiUtils.d.ts.map +1 -1
  20. package/dist/utils/service/apiServiceBookingApiUtils.js +30 -1
  21. package/dist/utils/service/apiServiceBookingApiUtils.js.map +1 -1
  22. package/dist/utils/service/frontendServiceBookingUtils.d.ts +10 -4
  23. package/dist/utils/service/frontendServiceBookingUtils.d.ts.map +1 -1
  24. package/dist/utils/service/frontendServiceBookingUtils.js +16 -3
  25. package/dist/utils/service/frontendServiceBookingUtils.js.map +1 -1
  26. package/dist/utils/service/serviceBookingTypes.d.ts +2 -2
  27. package/dist/utils/service/serviceBookingTypes.d.ts.map +1 -1
  28. package/package.json +1 -1
  29. package/prisma/schema.prisma +10 -7
  30. package/src/definitions.ts +7 -0
  31. package/src/utils/__tests__/organizationEntitlements.test.ts +79 -30
  32. package/src/utils/organizationEntitlements.ts +44 -27
  33. package/src/utils/service/__tests__/apiServiceBookingApiUtils.test.ts +102 -2
  34. package/src/utils/service/__tests__/frontendServiceBookingUtils.test.ts +217 -0
  35. package/src/utils/service/apiServiceBookingApiUtils.ts +53 -1
  36. package/src/utils/service/frontendServiceBookingUtils.ts +33 -2
  37. package/src/utils/service/serviceBookingTypes.ts +2 -1
@@ -1,12 +1,15 @@
1
1
  import { ServiceAddon, ServiceBookingRateOption } from "@prisma/client";
2
- import { ServiceRatesAssociationExt } from "../../extendedSchemas.js";
2
+ import { ServicePackageExt, ServiceRatesAssociationExt } from "../../extendedSchemas.js";
3
3
  import { ServiceAttendeeOption } from "./attendeeOptionUtils.js";
4
4
  import { ServiceRatesLuxon } from "./serviceRateUtils.js";
5
5
  import { LuxonDateRange } from "../luxonUtils.js";
6
- import { ServiceBookingFeeBase, ServiceBookingPriceBreakdownBaseT, ServiceBookingAddOnBase } from "./serviceBookingTypes.js";
6
+ import { ServiceBookingFeeBase, ServiceBookingPriceBreakdownBaseT, ServiceBookingAddOnBase, ServiceBookingPackageBase } from "./serviceBookingTypes.js";
7
7
  export interface ServiceAddonInput extends ServiceAddon {
8
8
  chosenQuantity?: number;
9
9
  }
10
+ export interface ServicePackageInput extends ServicePackageExt {
11
+ chosenQuantity?: number;
12
+ }
10
13
  export interface FrontendServiceBookingDayInfoParams {
11
14
  dateTimeRange: LuxonDateRange;
12
15
  fees: ServiceBookingFeeBase[];
@@ -28,6 +31,7 @@ export interface FrontendServiceGetPriceToBookResult {
28
31
  rateOption: ServiceBookingRateOption;
29
32
  flatRateCents?: number;
30
33
  addOns: ServiceBookingAddOnBase[];
34
+ packages: ServiceBookingPackageBase[];
31
35
  daysTotalBeforeTaxesCents: number;
32
36
  subtotalBeforeTaxesCents: number;
33
37
  totalBeforeTaxesCents: number;
@@ -46,15 +50,17 @@ export interface FrontendServiceGetPriceToBookFeesParams {
46
50
  selectedAttendeeOption: ServiceAttendeeOption;
47
51
  additionalFees: ServiceBookingFeeBase[];
48
52
  addOns: ServiceAddonInput[];
53
+ packages?: ServicePackageInput[];
49
54
  timezone: string | null | undefined;
50
55
  }
51
- export declare function frontendServiceGetPriceToBookFees(serviceRatesAssociation: ServiceRatesAssociationExt | null | undefined, { daysToBookParams, selectedAttendeeOption, addOns, additionalFees, timezone, }: FrontendServiceGetPriceToBookFeesParams): FrontendServiceGetPriceToBookResult;
56
+ export declare function frontendServiceGetPriceToBookFees(serviceRatesAssociation: ServiceRatesAssociationExt | null | undefined, { daysToBookParams, selectedAttendeeOption, addOns, packages, additionalFees, timezone, }: FrontendServiceGetPriceToBookFeesParams): FrontendServiceGetPriceToBookResult;
52
57
  export interface FrontendServiceGetPriceToBookParams {
53
58
  addOns: ServiceAddonInput[];
59
+ packages?: ServicePackageInput[];
54
60
  selectedAttendeeOption: ServiceAttendeeOption;
55
61
  bookingDateTimeRanges: LuxonDateRange[];
56
62
  timezone: string | null | undefined;
57
63
  }
58
- export declare function frontendServiceGetPriceToBook(serviceRatesAssociation: ServiceRatesAssociationExt | null | undefined, { addOns, selectedAttendeeOption, bookingDateTimeRanges, //list of dateTime ranges to book
64
+ export declare function frontendServiceGetPriceToBook(serviceRatesAssociation: ServiceRatesAssociationExt | null | undefined, { addOns, packages, selectedAttendeeOption, bookingDateTimeRanges, //list of dateTime ranges to book
59
65
  timezone, }: FrontendServiceGetPriceToBookParams): FrontendServiceGetPriceToBookResult;
60
66
  //# sourceMappingURL=frontendServiceBookingUtils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"frontendServiceBookingUtils.d.ts","sourceRoot":"","sources":["../../../src/utils/service/frontendServiceBookingUtils.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"frontendServiceBookingUtils.d.ts","sourceRoot":"","sources":["../../../src/utils/service/frontendServiceBookingUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EAGZ,wBAAwB,EACzB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAML,iBAAiB,EACjB,0BAA0B,EAE3B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EAML,iBAAiB,EAClB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAGL,cAAc,EACf,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,qBAAqB,EACrB,iCAAiC,EACjC,uBAAuB,EACvB,yBAAyB,EAC1B,MAAM,0BAA0B,CAAC;AAKlC,MAAM,WAAW,iBAAkB,SAAQ,YAAY;IACrD,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,mBAAoB,SAAQ,iBAAiB;IAC5D,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,mCAAmC;IAClD,aAAa,EAAE,cAAc,CAAC;IAC9B,IAAI,EAAE,qBAAqB,EAAE,CAAC;IAC9B,MAAM,EAAE,iBAAiB,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,6BAA6B;IAC5C,cAAc,EAAE,iCAAiC,EAAE,CAAC;IACpD,MAAM,EAAE,uBAAuB,EAAE,CAAC;IAClC,IAAI,EAAE,qBAAqB,EAAE,CAAC;IAG9B,aAAa,EAAE,cAAc,CAAC;IAC9B,QAAQ,EAAE,MAAM,CAAC;IAEjB,wBAAwB,EAAE,MAAM,CAAC;IACjC,qBAAqB,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,mCAAmC;IAClD,SAAS,EAAE,MAAM,CAAC;IAElB,UAAU,EAAE,6BAA6B,EAAE,CAAC;IAC5C,cAAc,EAAE,qBAAqB,EAAE,CAAC;IAExC,UAAU,EAAE,wBAAwB,CAAC;IACrC,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,MAAM,EAAE,uBAAuB,EAAE,CAAC;IAClC,QAAQ,EAAE,yBAAyB,EAAE,CAAC;IAEtC,yBAAyB,EAAE,MAAM,CAAC;IAClC,wBAAwB,EAAE,MAAM,CAAC;IACjC,qBAAqB,EAAE,MAAM,CAAC;IAC9B,aAAa,EAAE,MAAM,CAAC;IAEtB,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,2CAA2C;IAC1D,UAAU,EAAE,wBAAwB,CAAC;IACrC,aAAa,EAAE,iBAAiB,CAAC;IAGjC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACpC,gBAAgB,EAAE,mCAAmC,EAAE,CAAC;CACzD;AAED,wBAAgB,gCAAgC,CAAC,EAC/C,UAAU,EACV,aAAa,EACb,gBAAgB,EAEhB,QAAQ,GACT,EAAE,2CAA2C,GAAG,6BAA6B,EAAE,CA+F/E;AAED,MAAM,WAAW,uCAAuC;IACtD,gBAAgB,EAAE,mCAAmC,EAAE,CAAC;IACxD,sBAAsB,EAAE,qBAAqB,CAAC;IAE9C,cAAc,EAAE,qBAAqB,EAAE,CAAC;IACxC,MAAM,EAAE,iBAAiB,EAAE,CAAC;IAC5B,QAAQ,CAAC,EAAE,mBAAmB,EAAE,CAAC;IAGjC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;CACrC;AAED,wBAAgB,iCAAiC,CAC/C,uBAAuB,EAAE,0BAA0B,GAAG,IAAI,GAAG,SAAS,EACtE,EACE,gBAAgB,EAChB,sBAAsB,EACtB,MAAM,EACN,QAAa,EACb,cAAc,EAEd,QAAQ,GACT,EAAE,uCAAuC,GACzC,mCAAmC,CAsIrC;AAED,MAAM,WAAW,mCAAmC;IAClD,MAAM,EAAE,iBAAiB,EAAE,CAAC;IAC5B,QAAQ,CAAC,EAAE,mBAAmB,EAAE,CAAC;IAEjC,sBAAsB,EAAE,qBAAqB,CAAC;IAE9C,qBAAqB,EAAE,cAAc,EAAE,CAAC;IAGxC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;CACrC;AAED,wBAAgB,6BAA6B,CAC3C,uBAAuB,EAAE,0BAA0B,GAAG,IAAI,GAAG,SAAS,EACtE,EACE,MAAM,EACN,QAAa,EACb,sBAAsB,EACtB,qBAAqB,EAAE,iCAAiC;AAExD,QAAQ,GACT,EAAE,mCAAmC,GACrC,mCAAmC,CAmCrC"}
@@ -72,7 +72,7 @@ timezone, }) {
72
72
  });
73
73
  return bookingDayResults;
74
74
  }
75
- export function frontendServiceGetPriceToBookFees(serviceRatesAssociation, { daysToBookParams, selectedAttendeeOption, addOns, additionalFees,
75
+ export function frontendServiceGetPriceToBookFees(serviceRatesAssociation, { daysToBookParams, selectedAttendeeOption, addOns, packages = [], additionalFees,
76
76
  // overlappingBusinessHours,
77
77
  timezone, }) {
78
78
  const bookingDateTimeRanges = daysToBookParams.map((daysToBookParams) => daysToBookParams.dateTimeRange);
@@ -92,6 +92,16 @@ timezone, }) {
92
92
  };
93
93
  })
94
94
  : [];
95
+ // Packages are booking-level bundled line items (e.g. "Gold DJ Package") and apply
96
+ // on top of the booking regardless of hourly/daily/flat rate option.
97
+ const usedPackages = packages.map((pkg) => {
98
+ return {
99
+ package: pkg,
100
+ packageId: pkg.id,
101
+ chosenQuantity: pkg.chosenQuantity ?? 0,
102
+ costPQCents: pkg.priceCents,
103
+ };
104
+ });
95
105
  const bookingDayResults = frontendServiceGetBookingDayInfo({
96
106
  rateOption: rateOption,
97
107
  filteredRates: filteredRates,
@@ -120,7 +130,8 @@ timezone, }) {
120
130
  const hasCustomProcessingFee = additionalFees.some((fee) => fee.feeType == ServiceBookingFeeType.ProcessingFee);
121
131
  allAdditionalFees = allAdditionalFees.filter((fee) => fee.costPQCents > 0);
122
132
  const addOnsTotalCents = usedAddons.reduce((sofar, addOn) => sofar + addOn.costPQCents * addOn.chosenQuantity, 0);
123
- const subtotalBeforeTaxesCents = daysTotalBeforeTaxesCents + addOnsTotalCents;
133
+ const packagesTotalCents = usedPackages.reduce((sofar, pkg) => sofar + pkg.costPQCents * pkg.chosenQuantity, 0);
134
+ const subtotalBeforeTaxesCents = daysTotalBeforeTaxesCents + addOnsTotalCents + packagesTotalCents;
124
135
  if (!hasCustomProcessingFee) {
125
136
  // Same pass-through formula as bash ticket/donation checkout (STRIPE_PROCESSING_FEE).
126
137
  const processingFeeCents = calculateStripeProcessingFeeCents(subtotalBeforeTaxesCents);
@@ -143,6 +154,7 @@ timezone, }) {
143
154
  totalWithFees: totalBeforeTaxesCents, // Same as totalBeforeTaxesCents
144
155
  additionalFees: allAdditionalFees,
145
156
  addOns: usedAddons,
157
+ packages: usedPackages,
146
158
  minimumTimeBlockHours: minimumTimeBlockHours,
147
159
  rateOption: rateOption,
148
160
  flatRateCents: (filteredRates.generalRate?.flatRateCents ?? 0) > 0
@@ -150,7 +162,7 @@ timezone, }) {
150
162
  : undefined,
151
163
  };
152
164
  }
153
- export function frontendServiceGetPriceToBook(serviceRatesAssociation, { addOns, selectedAttendeeOption, bookingDateTimeRanges, //list of dateTime ranges to book
165
+ export function frontendServiceGetPriceToBook(serviceRatesAssociation, { addOns, packages = [], selectedAttendeeOption, bookingDateTimeRanges, //list of dateTime ranges to book
154
166
  // overlappingBusinessHours,
155
167
  timezone, }) {
156
168
  const cleaningFeePerBookingCents = serviceRatesAssociation?.serviceGeneralRates?.cleaningFeePerBookingCents ??
@@ -176,6 +188,7 @@ timezone, }) {
176
188
  selectedAttendeeOption: selectedAttendeeOption,
177
189
  additionalFees: [],
178
190
  addOns: addOns,
191
+ packages: packages,
179
192
  timezone: timezone,
180
193
  });
181
194
  }
@@ -1 +1 @@
1
- {"version":3,"file":"frontendServiceBookingUtils.js","sourceRoot":"","sources":["../../../src/utils/service/frontendServiceBookingUtils.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"frontendServiceBookingUtils.js","sourceRoot":"","sources":["../../../src/utils/service/frontendServiceBookingUtils.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,8 @@
1
- import { ServiceBookingAddOnExt, ServiceBookingFeeExt, ServiceBookingPriceBreakdownExt, ServiceBookingDayExt, ServiceBookingExt } from "../../extendedSchemas.js";
1
+ import { ServiceBookingAddOnExt, ServiceBookingFeeExt, ServiceBookingPackageExt, ServiceBookingPriceBreakdownExt, ServiceBookingDayExt, ServiceBookingExt } from "../../extendedSchemas.js";
2
2
  import { LuxonDateRange } from "../luxonUtils.js";
3
3
  import { MakeNullablePropsOptional, MakeOptional } from "../typeUtils.js";
4
4
  export type ServiceBookingAddOnBase = Omit<ServiceBookingAddOnExt, "id" | "serviceBookingDayId" | "serviceBookingDay" | "serviceBookingId" | "serviceBooking">;
5
- export type ServiceBookingPackageBase = Omit<ServiceBookingAddOnExt, "id" | "serviceBookingDayId" | "serviceBookingDay" | "serviceBookingId" | "serviceBooking">;
5
+ export type ServiceBookingPackageBase = Omit<ServiceBookingPackageExt, "id" | "serviceBookingDayId" | "serviceBookingDay" | "serviceBookingId" | "serviceBooking">;
6
6
  export type ServiceBookingFeeBase = Omit<ServiceBookingFeeExt, "id" | "serviceBookingDayId" | "serviceBookingDay" | "serviceBookingId" | "serviceBooking">;
7
7
  export type ServiceBookingPriceBreakdownBase = Omit<ServiceBookingPriceBreakdownExt, "id" | "serviceBookingDayId" | "serviceBookingDay">;
8
8
  export type ServiceBookingDayBase = Omit<ServiceBookingDayExt, "id" | "serviceBookingRequestId" | "serviceBookingRequest">;
@@ -1 +1 @@
1
- {"version":3,"file":"serviceBookingTypes.d.ts","sourceRoot":"","sources":["../../../src/utils/service/serviceBookingTypes.ts"],"names":[],"mappings":"AACA,OAAO,EACL,sBAAsB,EACtB,oBAAoB,EACpB,+BAA+B,EAC/B,oBAAoB,EAGpB,iBAAiB,EAClB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,OAAO,EAAE,yBAAyB,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE1E,MAAM,MAAM,uBAAuB,GAAG,IAAI,CACxC,sBAAsB,EACpB,IAAI,GACJ,qBAAqB,GACrB,mBAAmB,GACnB,kBAAkB,GAClB,gBAAgB,CACnB,CAAC;AACF,MAAM,MAAM,yBAAyB,GAAG,IAAI,CAC1C,sBAAsB,EACpB,IAAI,GACJ,qBAAqB,GACrB,mBAAmB,GACnB,kBAAkB,GAClB,gBAAgB,CACnB,CAAC;AACF,MAAM,MAAM,qBAAqB,GAAG,IAAI,CACtC,oBAAoB,EAClB,IAAI,GACJ,qBAAqB,GACrB,mBAAmB,GACnB,kBAAkB,GAClB,gBAAgB,CACnB,CAAC;AACF,MAAM,MAAM,gCAAgC,GAAG,IAAI,CACjD,+BAA+B,EAC/B,IAAI,GAAG,qBAAqB,GAAG,mBAAmB,CACnD,CAAC;AACF,MAAM,MAAM,qBAAqB,GAAG,IAAI,CACtC,oBAAoB,EACpB,IAAI,GAAG,yBAAyB,GAAG,uBAAuB,CAC3D,CAAC;AACF,MAAM,MAAM,kBAAkB,GAAG,IAAI,CACnC,iBAAiB,EACjB,YAAY,GAAG,UAAU,GAAG,gBAAgB,CAC7C,CAAC;AAEF,MAAM,MAAM,0BAA0B,GAAG,yBAAyB,CAChE,YAAY,CACV,iBAAiB,EACf,IAAI,GACJ,0BAA0B,GAC1B,aAAa,GACb,oBAAoB,GACpB,WAAW,GACX,SAAS,GACT,WAAW,GACX,SAAS,GACT,WAAW,GACX,SAAS,GACT,UAAU,GAGV,kBAAkB,GAClB,oBAAoB,GAGpB,kBAAkB,CACrB,CACF,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG,uBAAuB,CAAC;AAC/D,MAAM,MAAM,0BAA0B,GAAG,yBAAyB,CAAC;AACnE,MAAM,MAAM,sBAAsB,GAAG,qBAAqB,CAAC;AAC3D,MAAM,MAAM,iCAAiC,GAAG,IAAI,CAClD,gCAAgC,EAChC,WAAW,GAAG,SAAS,CACxB,GAAG;IACF,aAAa,EAAE,cAAc,CAAC;CAC/B,CAAC;AACF,MAAM,MAAM,sBAAsB,GAAG,IAAI,CACvC,qBAAqB,EACrB,WAAW,GAAG,SAAS,CACxB,GAAG;IACF,aAAa,EAAE,cAAc,CAAC;CAC/B,CAAC;AACF,MAAM,MAAM,mBAAmB,GAAG,kBAAkB,CAAC"}
1
+ {"version":3,"file":"serviceBookingTypes.d.ts","sourceRoot":"","sources":["../../../src/utils/service/serviceBookingTypes.ts"],"names":[],"mappings":"AACA,OAAO,EACL,sBAAsB,EACtB,oBAAoB,EACpB,wBAAwB,EACxB,+BAA+B,EAC/B,oBAAoB,EAGpB,iBAAiB,EAClB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,OAAO,EAAE,yBAAyB,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE1E,MAAM,MAAM,uBAAuB,GAAG,IAAI,CACxC,sBAAsB,EACpB,IAAI,GACJ,qBAAqB,GACrB,mBAAmB,GACnB,kBAAkB,GAClB,gBAAgB,CACnB,CAAC;AACF,MAAM,MAAM,yBAAyB,GAAG,IAAI,CAC1C,wBAAwB,EACtB,IAAI,GACJ,qBAAqB,GACrB,mBAAmB,GACnB,kBAAkB,GAClB,gBAAgB,CACnB,CAAC;AACF,MAAM,MAAM,qBAAqB,GAAG,IAAI,CACtC,oBAAoB,EAClB,IAAI,GACJ,qBAAqB,GACrB,mBAAmB,GACnB,kBAAkB,GAClB,gBAAgB,CACnB,CAAC;AACF,MAAM,MAAM,gCAAgC,GAAG,IAAI,CACjD,+BAA+B,EAC/B,IAAI,GAAG,qBAAqB,GAAG,mBAAmB,CACnD,CAAC;AACF,MAAM,MAAM,qBAAqB,GAAG,IAAI,CACtC,oBAAoB,EACpB,IAAI,GAAG,yBAAyB,GAAG,uBAAuB,CAC3D,CAAC;AACF,MAAM,MAAM,kBAAkB,GAAG,IAAI,CACnC,iBAAiB,EACjB,YAAY,GAAG,UAAU,GAAG,gBAAgB,CAC7C,CAAC;AAEF,MAAM,MAAM,0BAA0B,GAAG,yBAAyB,CAChE,YAAY,CACV,iBAAiB,EACf,IAAI,GACJ,0BAA0B,GAC1B,aAAa,GACb,oBAAoB,GACpB,WAAW,GACX,SAAS,GACT,WAAW,GACX,SAAS,GACT,WAAW,GACX,SAAS,GACT,UAAU,GAGV,kBAAkB,GAClB,oBAAoB,GAGpB,kBAAkB,CACrB,CACF,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG,uBAAuB,CAAC;AAC/D,MAAM,MAAM,0BAA0B,GAAG,yBAAyB,CAAC;AACnE,MAAM,MAAM,sBAAsB,GAAG,qBAAqB,CAAC;AAC3D,MAAM,MAAM,iCAAiC,GAAG,IAAI,CAClD,gCAAgC,EAChC,WAAW,GAAG,SAAS,CACxB,GAAG;IACF,aAAa,EAAE,cAAc,CAAC;CAC/B,CAAC;AACF,MAAM,MAAM,sBAAsB,GAAG,IAAI,CACvC,qBAAqB,EACrB,WAAW,GAAG,SAAS,CACxB,GAAG;IACF,aAAa,EAAE,cAAc,CAAC;CAC/B,CAAC;AACF,MAAM,MAAM,mBAAmB,GAAG,kBAAkB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bash-app/bash-common",
3
- "version": "30.371.0",
3
+ "version": "30.374.0",
4
4
  "description": "Common data and scripts to use on the frontend and backend",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -6026,13 +6026,16 @@ model Organization {
6026
6026
  /// "Standard" | "Priority" | "Dedicated" — drives named-AM banner + support routing copy.
6027
6027
  supportTier String @default("Standard")
6028
6028
  /// True only when ops set subscriptionTier="Enterprise" via the admin
6029
- /// enterprise-provisioning endpoint (a signed deal). Self-serve Stripe checkout
6030
- /// (organizationSubscriptionUtils.ts) can also set subscriptionTier="Enterprise"
6031
- /// but never sets this flag. organizationHasEnterprisePlatformAccess() and the
6032
- /// SSO/audit-log/procurement/compliance/API entitlements below require this flag
6033
- /// in addition to the Enterprise tier self-serve Enterprise unlocks white-label
6034
- /// (organizationHasCustomDomainAccess/organizationHasVanitySubdomain do NOT
6035
- /// require this flag) but not the sales-negotiated platform surface.
6029
+ /// enterprise-provisioning endpoint (a signed deal) the only way to reach
6030
+ /// subscriptionTier="Enterprise" today, since self-serve Enterprise checkout
6031
+ /// is blocked (see docs/ENTERPRISE-B2B-SALES-PLAYBOOK.md).
6032
+ /// organizationHasEnterprisePlatformAccess() and the SSO/audit-log/procurement/
6033
+ /// compliance/API entitlements below require this flag in addition to the
6034
+ /// Enterprise tier. organizationHasCustomDomainAccess() (custom domains,
6035
+ /// "Powered by Bash" removal) requires the Enterprise tier but NOT this flag,
6036
+ /// so a fast-follow self-serve Enterprise checkout could unlock white-label
6037
+ /// without the sales-gated platform surface. organizationHasVanitySubdomain()
6038
+ /// is a separate, cheaper perk available to Growth tier and up.
6036
6039
  enterpriseSalesProvisioned Boolean @default(false)
6037
6040
 
6038
6041
  /// SSO / identity (Organization Enterprise only). `ssoEnforced` blocks password
@@ -709,6 +709,11 @@ export type ApiServiceAddonParams = {
709
709
  chosenQuantity: number;
710
710
  };
711
711
 
712
+ export type ApiServicePackageParams = {
713
+ packageId: string;
714
+ chosenQuantity: number;
715
+ };
716
+
712
717
  export type ApiServiceBookedDayParams = {
713
718
  serviceId: string;
714
719
  forUserId: string;
@@ -741,6 +746,8 @@ export type ApiServiceBookingParams = {
741
746
  timezone: string;
742
747
  attendeeOption: ServiceAttendeeOption;
743
748
  bashEventId?: string;
749
+ /** Booking-level bundled packages (e.g. "Gold DJ Package"), independent of hourly/daily rates. */
750
+ packages?: ApiServicePackageParams[];
744
751
  };
745
752
 
746
753
  export type ApiServiceCanBookParams = {} & ApiServiceBookingParams;
@@ -17,8 +17,8 @@ describe("organizationHasVanitySubdomain", () => {
17
17
  expect(organizationHasVanitySubdomain(undefined)).toBe(false);
18
18
  });
19
19
 
20
- test("non-Enterprise tiers are never entitled", () => {
21
- for (const tier of ["Starter", "Growth", "Church", "Legacy", null]) {
20
+ test("below-Growth tiers are never entitled", () => {
21
+ for (const tier of ["Starter", "Church", "Legacy", null]) {
22
22
  expect(
23
23
  organizationHasVanitySubdomain({
24
24
  subscriptionTier: tier,
@@ -28,29 +28,77 @@ describe("organizationHasVanitySubdomain", () => {
28
28
  }
29
29
  });
30
30
 
31
- test("Enterprise with active or trialing status is entitled", () => {
31
+ test("Growth or Enterprise with active or trialing status is entitled", () => {
32
+ for (const tier of ["Growth", "Enterprise"]) {
33
+ expect(
34
+ organizationHasVanitySubdomain({
35
+ subscriptionTier: tier,
36
+ subscriptionStatus: "Active",
37
+ })
38
+ ).toBe(true);
39
+ expect(
40
+ organizationHasVanitySubdomain({
41
+ subscriptionTier: tier,
42
+ subscriptionStatus: "Trialing",
43
+ })
44
+ ).toBe(true);
45
+ }
46
+ });
47
+
48
+ test("Growth or Enterprise with a missing status is treated as active (legacy/ops orgs)", () => {
49
+ for (const tier of ["Growth", "Enterprise"]) {
50
+ expect(organizationHasVanitySubdomain({ subscriptionTier: tier })).toBe(true);
51
+ expect(
52
+ organizationHasVanitySubdomain({
53
+ subscriptionTier: tier,
54
+ subscriptionStatus: null,
55
+ })
56
+ ).toBe(true);
57
+ }
58
+ });
59
+
60
+ test("Growth or Enterprise with a lapsed status is not entitled", () => {
61
+ for (const tier of ["Growth", "Enterprise"]) {
62
+ for (const status of ["Canceled", "PastDue", "Canceling"]) {
63
+ expect(
64
+ organizationHasVanitySubdomain({
65
+ subscriptionTier: tier,
66
+ subscriptionStatus: status,
67
+ })
68
+ ).toBe(false);
69
+ }
70
+ }
71
+ });
72
+ });
73
+
74
+ describe("organizationHasCustomDomainAccess", () => {
75
+ test("null / undefined return false", () => {
76
+ expect(organizationHasCustomDomainAccess(null)).toBe(false);
77
+ expect(organizationHasCustomDomainAccess(undefined)).toBe(false);
78
+ });
79
+
80
+ test("Growth is not entitled — custom domains stay Enterprise-only", () => {
32
81
  expect(
33
- organizationHasVanitySubdomain({
34
- subscriptionTier: "Enterprise",
82
+ organizationHasCustomDomainAccess({
83
+ subscriptionTier: "Growth",
35
84
  subscriptionStatus: "Active",
36
85
  })
37
- ).toBe(true);
38
- expect(
39
- organizationHasVanitySubdomain({
40
- subscriptionTier: "Enterprise",
41
- subscriptionStatus: "Trialing",
42
- })
43
- ).toBe(true);
86
+ ).toBe(false);
44
87
  });
45
88
 
46
- test("Enterprise with a missing status is treated as active (legacy/ops orgs)", () => {
89
+ test("Enterprise with active or trialing status is entitled, regardless of enterpriseSalesProvisioned", () => {
47
90
  expect(
48
- organizationHasVanitySubdomain({ subscriptionTier: "Enterprise" })
91
+ organizationHasCustomDomainAccess({
92
+ subscriptionTier: "Enterprise",
93
+ subscriptionStatus: "Active",
94
+ enterpriseSalesProvisioned: true,
95
+ })
49
96
  ).toBe(true);
50
97
  expect(
51
- organizationHasVanitySubdomain({
98
+ organizationHasCustomDomainAccess({
52
99
  subscriptionTier: "Enterprise",
53
- subscriptionStatus: null,
100
+ subscriptionStatus: "Active",
101
+ enterpriseSalesProvisioned: false,
54
102
  })
55
103
  ).toBe(true);
56
104
  });
@@ -58,7 +106,7 @@ describe("organizationHasVanitySubdomain", () => {
58
106
  test("Enterprise with a lapsed status is not entitled", () => {
59
107
  for (const status of ["Canceled", "PastDue", "Canceling"]) {
60
108
  expect(
61
- organizationHasVanitySubdomain({
109
+ organizationHasCustomDomainAccess({
62
110
  subscriptionTier: "Enterprise",
63
111
  subscriptionStatus: status,
64
112
  })
@@ -75,8 +123,9 @@ describe("enterprise platform gates (audit logs, SSO, procurement, API access)",
75
123
  subscriptionStatus: "Active",
76
124
  enterpriseSalesProvisioned: true,
77
125
  };
78
- // Self-serve: bought via Stripe checkout, never grants the platform surface.
79
- const selfServeEnterprise = {
126
+ // Not sales-provisioned (e.g. legacy data, or ops hasn't flipped the flag
127
+ // yet): Enterprise tier alone never grants the sales-gated platform surface.
128
+ const nonSalesProvisionedEnterprise = {
80
129
  subscriptionTier: "Enterprise",
81
130
  subscriptionStatus: "Active",
82
131
  enterpriseSalesProvisioned: false,
@@ -85,7 +134,7 @@ describe("enterprise platform gates (audit logs, SSO, procurement, API access)",
85
134
 
86
135
  test("organizationHasEnterprisePlatformAccess requires enterpriseSalesProvisioned", () => {
87
136
  expect(organizationHasEnterprisePlatformAccess(salesProvisionedEnterprise)).toBe(true);
88
- expect(organizationHasEnterprisePlatformAccess(selfServeEnterprise)).toBe(false);
137
+ expect(organizationHasEnterprisePlatformAccess(nonSalesProvisionedEnterprise)).toBe(false);
89
138
  expect(organizationHasEnterprisePlatformAccess(growthActive)).toBe(false);
90
139
  expect(organizationHasEnterprisePlatformAccess(null)).toBe(false);
91
140
  expect(organizationHasEnterprisePlatformAccess(undefined)).toBe(false);
@@ -102,45 +151,45 @@ describe("enterprise platform gates (audit logs, SSO, procurement, API access)",
102
151
 
103
152
  test("organizationHasAuditLogAccess follows the shared enterprise gate", () => {
104
153
  expect(organizationHasAuditLogAccess(salesProvisionedEnterprise)).toBe(true);
105
- expect(organizationHasAuditLogAccess(selfServeEnterprise)).toBe(false);
154
+ expect(organizationHasAuditLogAccess(nonSalesProvisionedEnterprise)).toBe(false);
106
155
  expect(organizationHasAuditLogAccess(growthActive)).toBe(false);
107
156
  });
108
157
 
109
158
  test("organizationHasSsoAccess follows the shared enterprise gate", () => {
110
159
  expect(organizationHasSsoAccess(salesProvisionedEnterprise)).toBe(true);
111
- expect(organizationHasSsoAccess(selfServeEnterprise)).toBe(false);
160
+ expect(organizationHasSsoAccess(nonSalesProvisionedEnterprise)).toBe(false);
112
161
  expect(organizationHasSsoAccess(growthActive)).toBe(false);
113
162
  });
114
163
 
115
164
  test("organizationHasProcurementAccess follows the shared enterprise gate", () => {
116
165
  expect(organizationHasProcurementAccess(salesProvisionedEnterprise)).toBe(true);
117
- expect(organizationHasProcurementAccess(selfServeEnterprise)).toBe(false);
166
+ expect(organizationHasProcurementAccess(nonSalesProvisionedEnterprise)).toBe(false);
118
167
  expect(organizationHasProcurementAccess(growthActive)).toBe(false);
119
168
  });
120
169
 
121
170
  test("organizationHasApiAccess follows the shared enterprise gate", () => {
122
171
  expect(organizationHasApiAccess(salesProvisionedEnterprise)).toBe(true);
123
- expect(organizationHasApiAccess(selfServeEnterprise)).toBe(false);
172
+ expect(organizationHasApiAccess(nonSalesProvisionedEnterprise)).toBe(false);
124
173
  expect(organizationHasApiAccess(growthActive)).toBe(false);
125
174
  });
126
175
 
127
176
  test("organizationHasComplianceAccess follows the shared enterprise gate", () => {
128
177
  expect(organizationHasComplianceAccess(salesProvisionedEnterprise)).toBe(true);
129
- expect(organizationHasComplianceAccess(selfServeEnterprise)).toBe(false);
178
+ expect(organizationHasComplianceAccess(nonSalesProvisionedEnterprise)).toBe(false);
130
179
  expect(organizationHasComplianceAccess(growthActive)).toBe(false);
131
180
  });
132
181
 
133
- test("organizationHasCustomDomainAccess (white-label) is self-serve-eligible no sales flag required", () => {
182
+ test("organizationHasCustomDomainAccess does not require the sales flag, but does require Enterprise (not Growth)", () => {
134
183
  expect(organizationHasCustomDomainAccess(salesProvisionedEnterprise)).toBe(true);
135
- expect(organizationHasCustomDomainAccess(selfServeEnterprise)).toBe(true);
184
+ expect(organizationHasCustomDomainAccess(nonSalesProvisionedEnterprise)).toBe(true);
136
185
  expect(organizationHasCustomDomainAccess(growthActive)).toBe(false);
137
186
  expect(organizationHasCustomDomainAccess(null)).toBe(false);
138
187
  expect(organizationHasCustomDomainAccess(undefined)).toBe(false);
139
188
  });
140
189
 
141
- test("organizationHasVanitySubdomain is self-serve-eligible no sales flag required", () => {
190
+ test("organizationHasVanitySubdomain does not require the sales flag, and Growth is entitled too", () => {
142
191
  expect(organizationHasVanitySubdomain(salesProvisionedEnterprise)).toBe(true);
143
- expect(organizationHasVanitySubdomain(selfServeEnterprise)).toBe(true);
144
- expect(organizationHasVanitySubdomain(growthActive)).toBe(false);
192
+ expect(organizationHasVanitySubdomain(nonSalesProvisionedEnterprise)).toBe(true);
193
+ expect(organizationHasVanitySubdomain(growthActive)).toBe(true);
145
194
  });
146
195
  });
@@ -17,47 +17,62 @@ export interface OrganizationEntitlementInput {
17
17
  subscriptionStatus?: string | null;
18
18
  /**
19
19
  * True only when ops provisioned Enterprise via a signed deal (admin
20
- * enterprise-provisioning endpoint). Self-serve Stripe checkout can also set
21
- * subscriptionTier="Enterprise" but never sets this. Optional/undefined is
22
- * treated as false so legacy call sites that don't select this field fail
23
- * closed on the sales-gated surface rather than open.
20
+ * enterprise-provisioning endpoint) the only way to reach
21
+ * subscriptionTier="Enterprise" (see docs/ENTERPRISE-B2B-SALES-PLAYBOOK.md;
22
+ * self-serve checkout rejects Enterprise). Optional/undefined is treated as
23
+ * false so legacy call sites that don't select this field fail closed on the
24
+ * sales-gated surface rather than open.
24
25
  */
25
26
  enterpriseSalesProvisioned?: boolean | null;
26
27
  }
27
28
 
29
+ // Treat a missing status as active: legacy/ops-provisioned orgs may predate
30
+ // subscriptionStatus being populated, and we don't want to silently drop
31
+ // their entitlements.
32
+ function isActiveOrTrialingStatus(status?: string | null): boolean {
33
+ if (status == null) return true;
34
+ return (ACTIVE_ORG_SUBSCRIPTION_STATUSES as readonly string[]).includes(status);
35
+ }
36
+
28
37
  function hasActiveEnterpriseTier(
29
38
  org: OrganizationEntitlementInput | null | undefined
30
39
  ): boolean {
31
40
  if (!org) return false;
32
41
  if (org.subscriptionTier !== "Enterprise") return false;
33
- // Treat a missing status as active: legacy/ops-provisioned Enterprise orgs may
34
- // predate subscriptionStatus being populated, and we don't want to silently
35
- // drop their vanity domain.
36
- if (org.subscriptionStatus == null) return true;
37
- return (ACTIVE_ORG_SUBSCRIPTION_STATUSES as readonly string[]).includes(
38
- org.subscriptionStatus
39
- );
42
+ return isActiveOrTrialingStatus(org.subscriptionStatus);
43
+ }
44
+
45
+ function hasActiveGrowthOrAboveTier(
46
+ org: OrganizationEntitlementInput | null | undefined
47
+ ): boolean {
48
+ if (!org) return false;
49
+ if (org.subscriptionTier !== "Growth" && org.subscriptionTier !== "Enterprise") {
50
+ return false;
51
+ }
52
+ return isActiveOrTrialingStatus(org.subscriptionStatus);
40
53
  }
41
54
 
42
55
  /**
43
- * Vanity subdomains ({slug}.bash.community) and custom domains (white-label)
44
- * are self-serve-eligible Enterprise perks available whether Enterprise was
45
- * bought via self-serve Stripe checkout or a sales-negotiated deal.
56
+ * Vanity subdomains ({slug}.bash.community) are a Growth-tier-and-up perk, not
57
+ * Enterprise-only: unlike custom domains, granting one costs nothing extra
58
+ * (a slug lookup against the existing bash.community CloudFront distribution,
59
+ * no per-org AWS resources) — it's a cheap, visible upgrade incentive to dangle
60
+ * in front of Starter orgs. See {@link organizationHasCustomDomainAccess} for
61
+ * the pricier, Enterprise-only white-label surface.
46
62
  */
47
63
  export function organizationHasVanitySubdomain(
48
64
  org: OrganizationEntitlementInput | null | undefined
49
65
  ): boolean {
50
- return hasActiveEnterpriseTier(org);
66
+ return hasActiveGrowthOrAboveTier(org);
51
67
  }
52
68
 
53
69
  /**
54
70
  * Shared gate for the enterprise platform surface: org-scoped audit logs,
55
71
  * SSO/identity setup, procurement approval policy, API keys, webhooks, and
56
- * third-party integrations (Mailchimp/Salesforce). Unlike the white-label
57
- * perks above, this surface requires a sales-negotiated deal
58
- * (`enterpriseSalesProvisioned`) self-serve $495/mo checkout alone does not
59
- * unlock SSO, compliance, procurement, or API access, since those typically
60
- * involve a security review or contract terms sales owns.
72
+ * third-party integrations (Mailchimp/Salesforce). Requires the explicit
73
+ * `enterpriseSalesProvisioned` flag set by ops after a signed deal, since SSO,
74
+ * compliance, procurement, and API access typically involve a security review
75
+ * or contract terms sales owns.
61
76
  */
62
77
  export function organizationHasEnterprisePlatformAccess(
63
78
  org: OrganizationEntitlementInput | null | undefined
@@ -103,15 +118,17 @@ export function organizationHasComplianceAccess(
103
118
  /**
104
119
  * Custom domains (white-label tier): real DNS (e.g. members.acme.com) provisioned
105
120
  * via AWS CloudFront SaaS Manager Distribution Tenants, plus the "Powered by Bash"
106
- * removal toggle. Same Enterprise + active/trialing gate as
107
- * {@link organizationHasVanitySubdomain} for MVP reuse the existing tier rather
108
- * than invent a new pricing tier now. A dedicated "White-label" tier is a
109
- * fast-follow if sales needs separate pricing. Self-serve-eligible: does NOT
110
- * require {@link organizationHasEnterprisePlatformAccess}'s
111
- * `enterpriseSalesProvisioned` flag.
121
+ * removal toggle. Unlike {@link organizationHasVanitySubdomain}, this needs a real
122
+ * per-org CloudFront Distribution Tenant + managed cert + the org's own DNS work —
123
+ * actual infra cost and complexity per org so it stays Enterprise-only (today
124
+ * always sales-provisioned, since self-serve Enterprise checkout is blocked; see
125
+ * docs/ENTERPRISE-B2B-SALES-PLAYBOOK.md). Does NOT require
126
+ * {@link organizationHasEnterprisePlatformAccess}'s `enterpriseSalesProvisioned`
127
+ * flag, so a fast-follow self-serve Enterprise checkout could unlock this without
128
+ * the sales-gated platform surface (SSO, audit logs, procurement, compliance, API).
112
129
  */
113
130
  export function organizationHasCustomDomainAccess(
114
131
  org: OrganizationEntitlementInput | null | undefined
115
132
  ): boolean {
116
- return organizationHasVanitySubdomain(org);
133
+ return hasActiveEnterpriseTier(org);
117
134
  }