@bash-app/bash-common 30.431.0 → 30.433.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.
- package/dist/__tests__/bashSectionTitleForBashType.test.js +2 -0
- package/dist/__tests__/bashSectionTitleForBashType.test.js.map +1 -1
- package/dist/__tests__/discoveryScope.test.js +9 -1
- package/dist/__tests__/discoveryScope.test.js.map +1 -1
- package/dist/__tests__/promoCartEngine.test.d.ts +2 -0
- package/dist/__tests__/promoCartEngine.test.d.ts.map +1 -0
- package/dist/__tests__/promoCartEngine.test.js +174 -0
- package/dist/__tests__/promoCartEngine.test.js.map +1 -0
- package/dist/__tests__/promoCodeRedemption.test.d.ts +2 -0
- package/dist/__tests__/promoCodeRedemption.test.d.ts.map +1 -0
- package/dist/__tests__/promoCodeRedemption.test.js +103 -0
- package/dist/__tests__/promoCodeRedemption.test.js.map +1 -0
- package/dist/__tests__/promoCodeScope.test.d.ts +2 -0
- package/dist/__tests__/promoCodeScope.test.d.ts.map +1 -0
- package/dist/__tests__/promoCodeScope.test.js +77 -0
- package/dist/__tests__/promoCodeScope.test.js.map +1 -0
- package/dist/definitions.d.ts +3 -1
- package/dist/definitions.d.ts.map +1 -1
- package/dist/definitions.js +4 -2
- package/dist/definitions.js.map +1 -1
- package/dist/discoveryScope.d.ts +6 -6
- package/dist/discoveryScope.d.ts.map +1 -1
- package/dist/discoveryScope.js +25 -16
- package/dist/discoveryScope.js.map +1 -1
- package/dist/extendedSchemas.d.ts +1 -0
- package/dist/extendedSchemas.d.ts.map +1 -1
- package/dist/extendedSchemas.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/promoCartEngine.d.ts +55 -0
- package/dist/promoCartEngine.d.ts.map +1 -0
- package/dist/promoCartEngine.js +135 -0
- package/dist/promoCartEngine.js.map +1 -0
- package/dist/promoCodeRedemption.d.ts +44 -0
- package/dist/promoCodeRedemption.d.ts.map +1 -0
- package/dist/promoCodeRedemption.js +81 -0
- package/dist/promoCodeRedemption.js.map +1 -0
- package/dist/promoCodeScope.d.ts +85 -0
- package/dist/promoCodeScope.d.ts.map +1 -0
- package/dist/promoCodeScope.js +93 -0
- package/dist/promoCodeScope.js.map +1 -0
- package/dist/utils/__tests__/discountEngine/discountCalculator.test.js +8 -1
- package/dist/utils/__tests__/discountEngine/discountCalculator.test.js.map +1 -1
- package/dist/utils/__tests__/paymentUtils.test.js +87 -4
- package/dist/utils/__tests__/paymentUtils.test.js.map +1 -1
- package/dist/utils/paymentUtils.d.ts +30 -5
- package/dist/utils/paymentUtils.d.ts.map +1 -1
- package/dist/utils/paymentUtils.js +43 -11
- package/dist/utils/paymentUtils.js.map +1 -1
- package/package.json +7 -3
- package/prisma/schema.prisma +106 -4
- package/src/__tests__/bashSectionTitleForBashType.test.ts +4 -0
- package/src/__tests__/discoveryScope.test.ts +22 -1
- package/src/__tests__/promoCartEngine.test.ts +201 -0
- package/src/__tests__/promoCodeRedemption.test.ts +134 -0
- package/src/__tests__/promoCodeScope.test.ts +106 -0
- package/src/definitions.ts +4 -2
- package/src/discoveryScope.ts +30 -20
- package/src/extendedSchemas.ts +1 -0
- package/src/index.ts +3 -0
- package/src/promoCartEngine.ts +193 -0
- package/src/promoCodeRedemption.ts +123 -0
- package/src/promoCodeScope.ts +164 -0
- package/src/utils/__tests__/discountEngine/discountCalculator.test.ts +8 -0
- package/src/utils/__tests__/paymentUtils.test.ts +100 -6
- package/src/utils/paymentUtils.ts +56 -13
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Promo code redemption rules shared by the API and the app.
|
|
3
|
+
* The API owns the ledger; these helpers are pure.
|
|
4
|
+
*/
|
|
5
|
+
export declare const PROMO_CODE_REJECT_REASONS: readonly ["expired", "exhausted", "already_used", "disabled", "invalid", "host_review_required"];
|
|
6
|
+
export type PromoCodeRejectReason = (typeof PROMO_CODE_REJECT_REASONS)[number];
|
|
7
|
+
/** Guest-facing copy. Plain and specific: this is about money. */
|
|
8
|
+
export declare const PROMO_CODE_REJECT_MESSAGES: Record<PromoCodeRejectReason, string>;
|
|
9
|
+
export declare function isPromoCodeRejectReason(value: unknown): value is PromoCodeRejectReason;
|
|
10
|
+
export type PromoRedeemabilityInput = {
|
|
11
|
+
redeemBy: Date | null | undefined;
|
|
12
|
+
disabledAt?: Date | null;
|
|
13
|
+
maxRedemptions: number | null | undefined;
|
|
14
|
+
maxUsesPerAccount?: number | null;
|
|
15
|
+
/** Consumed plus unexpired Reserved orders for the code. */
|
|
16
|
+
activeOrderCount: number;
|
|
17
|
+
/** Same count for the buyer's account (user id, else normalized email). */
|
|
18
|
+
accountOrderCount: number;
|
|
19
|
+
now: Date;
|
|
20
|
+
};
|
|
21
|
+
/** First failing rule, or null when the code can be used for one more order. */
|
|
22
|
+
export declare function evaluatePromoRedeemability(input: PromoRedeemabilityInput): PromoCodeRejectReason | null;
|
|
23
|
+
export type PromoCodeDuplicateCandidate = {
|
|
24
|
+
id: string;
|
|
25
|
+
ticketTierId: string | null;
|
|
26
|
+
promoterId: string | null;
|
|
27
|
+
discountAmountInCents: number | null;
|
|
28
|
+
discountAmountPercentage: number | null;
|
|
29
|
+
redeemBy: Date | null;
|
|
30
|
+
maxRedemptions: number | null;
|
|
31
|
+
bashPointsRewardPerTicket: number | null;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Legacy codes are unique per tier, so one bash can hold several rows with the
|
|
35
|
+
* same code. Identical rows resolve to the oldest id, preferring a row whose tier
|
|
36
|
+
* is in the cart. Rows that differ need the host to review them.
|
|
37
|
+
*/
|
|
38
|
+
export declare function pickPromoCodeAmongDuplicates<T extends PromoCodeDuplicateCandidate>(rows: readonly T[], cartTierIds?: readonly string[]): {
|
|
39
|
+
row: T;
|
|
40
|
+
} | {
|
|
41
|
+
reason: "host_review_required";
|
|
42
|
+
};
|
|
43
|
+
export declare function normalizePromoRedemptionEmail(email: string | null | undefined): string | null;
|
|
44
|
+
//# sourceMappingURL=promoCodeRedemption.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"promoCodeRedemption.d.ts","sourceRoot":"","sources":["../src/promoCodeRedemption.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,eAAO,MAAM,yBAAyB,kGAO5B,CAAC;AAEX,MAAM,MAAM,qBAAqB,GAAG,CAAC,OAAO,yBAAyB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE/E,kEAAkE;AAClE,eAAO,MAAM,0BAA0B,EAAE,MAAM,CAAC,qBAAqB,EAAE,MAAM,CAO5E,CAAC;AAEF,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,qBAAqB,CAKtF;AAED,MAAM,MAAM,uBAAuB,GAAG;IACpC,QAAQ,EAAE,IAAI,GAAG,IAAI,GAAG,SAAS,CAAC;IAClC,UAAU,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACzB,cAAc,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC1C,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,4DAA4D;IAC5D,gBAAgB,EAAE,MAAM,CAAC;IACzB,2EAA2E;IAC3E,iBAAiB,EAAE,MAAM,CAAC;IAC1B,GAAG,EAAE,IAAI,CAAC;CACX,CAAC;AAEF,gFAAgF;AAChF,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,uBAAuB,GAC7B,qBAAqB,GAAG,IAAI,CAoB9B;AAED,MAAM,MAAM,2BAA2B,GAAG;IACxC,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,qBAAqB,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,wBAAwB,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,QAAQ,EAAE,IAAI,GAAG,IAAI,CAAC;IACtB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,yBAAyB,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1C,CAAC;AAaF;;;;GAIG;AACH,wBAAgB,4BAA4B,CAAC,CAAC,SAAS,2BAA2B,EAChF,IAAI,EAAE,SAAS,CAAC,EAAE,EAClB,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,GAC9B;IAAE,GAAG,EAAE,CAAC,CAAA;CAAE,GAAG;IAAE,MAAM,EAAE,sBAAsB,CAAA;CAAE,CAejD;AAED,wBAAgB,6BAA6B,CAC3C,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAC/B,MAAM,GAAG,IAAI,CAGf"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Promo code redemption rules shared by the API and the app.
|
|
3
|
+
* The API owns the ledger; these helpers are pure.
|
|
4
|
+
*/
|
|
5
|
+
export const PROMO_CODE_REJECT_REASONS = [
|
|
6
|
+
"expired",
|
|
7
|
+
"exhausted",
|
|
8
|
+
"already_used",
|
|
9
|
+
"disabled",
|
|
10
|
+
"invalid",
|
|
11
|
+
"host_review_required",
|
|
12
|
+
];
|
|
13
|
+
/** Guest-facing copy. Plain and specific: this is about money. */
|
|
14
|
+
export const PROMO_CODE_REJECT_MESSAGES = {
|
|
15
|
+
expired: "This code has expired.",
|
|
16
|
+
exhausted: "This code has reached its order limit.",
|
|
17
|
+
already_used: "You've already used this code as many times as it allows.",
|
|
18
|
+
disabled: "This code is no longer active.",
|
|
19
|
+
invalid: "We couldn't find that code for this bash.",
|
|
20
|
+
host_review_required: "This code needs the host to review it.",
|
|
21
|
+
};
|
|
22
|
+
export function isPromoCodeRejectReason(value) {
|
|
23
|
+
return (typeof value === "string" &&
|
|
24
|
+
PROMO_CODE_REJECT_REASONS.includes(value));
|
|
25
|
+
}
|
|
26
|
+
/** First failing rule, or null when the code can be used for one more order. */
|
|
27
|
+
export function evaluatePromoRedeemability(input) {
|
|
28
|
+
if (input.disabledAt)
|
|
29
|
+
return "disabled";
|
|
30
|
+
if (input.redeemBy && input.redeemBy.getTime() < input.now.getTime()) {
|
|
31
|
+
return "expired";
|
|
32
|
+
}
|
|
33
|
+
if (input.maxRedemptions != null &&
|
|
34
|
+
input.maxRedemptions > 0 &&
|
|
35
|
+
input.activeOrderCount >= input.maxRedemptions) {
|
|
36
|
+
return "exhausted";
|
|
37
|
+
}
|
|
38
|
+
if (input.maxUsesPerAccount != null &&
|
|
39
|
+
input.maxUsesPerAccount > 0 &&
|
|
40
|
+
input.accountOrderCount >= input.maxUsesPerAccount) {
|
|
41
|
+
return "already_used";
|
|
42
|
+
}
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
function duplicateSignature(row) {
|
|
46
|
+
return JSON.stringify([
|
|
47
|
+
row.promoterId ?? null,
|
|
48
|
+
row.discountAmountInCents ?? null,
|
|
49
|
+
row.discountAmountPercentage ?? null,
|
|
50
|
+
row.redeemBy ? new Date(row.redeemBy).getTime() : null,
|
|
51
|
+
row.maxRedemptions ?? null,
|
|
52
|
+
row.bashPointsRewardPerTicket ?? null,
|
|
53
|
+
]);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Legacy codes are unique per tier, so one bash can hold several rows with the
|
|
57
|
+
* same code. Identical rows resolve to the oldest id, preferring a row whose tier
|
|
58
|
+
* is in the cart. Rows that differ need the host to review them.
|
|
59
|
+
*/
|
|
60
|
+
export function pickPromoCodeAmongDuplicates(rows, cartTierIds) {
|
|
61
|
+
if (rows.length === 0) {
|
|
62
|
+
throw new Error("pickPromoCodeAmongDuplicates needs at least one row");
|
|
63
|
+
}
|
|
64
|
+
if (rows.length === 1)
|
|
65
|
+
return { row: rows[0] };
|
|
66
|
+
const signature = duplicateSignature(rows[0]);
|
|
67
|
+
if (rows.some((r) => duplicateSignature(r) !== signature)) {
|
|
68
|
+
return { reason: "host_review_required" };
|
|
69
|
+
}
|
|
70
|
+
const inCart = cartTierIds?.length
|
|
71
|
+
? rows.filter((r) => r.ticketTierId && cartTierIds.includes(r.ticketTierId))
|
|
72
|
+
: [];
|
|
73
|
+
const pool = inCart.length ? inCart : rows;
|
|
74
|
+
const oldest = [...pool].sort((a, b) => (a.id < b.id ? -1 : a.id > b.id ? 1 : 0))[0];
|
|
75
|
+
return { row: oldest };
|
|
76
|
+
}
|
|
77
|
+
export function normalizePromoRedemptionEmail(email) {
|
|
78
|
+
const trimmed = email?.trim().toLowerCase() ?? "";
|
|
79
|
+
return trimmed ? trimmed : null;
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=promoCodeRedemption.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"promoCodeRedemption.js","sourceRoot":"","sources":["../src/promoCodeRedemption.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which bash and tiers a promo code applies to, and what kind of discount it
|
|
3
|
+
* gives, for both legacy single-tier rows and bash-level rows. Every reader goes
|
|
4
|
+
* through these instead of `promo.ticketTier.bashEventId` or `promo.ticketTierId`.
|
|
5
|
+
*/
|
|
6
|
+
export type PromoDiscountKind = "NONE" | "PERCENT" | "FIXED_CASH";
|
|
7
|
+
export type PromoEligibilityMode = "ALL_TIERS" | "SELECTED_TIERS";
|
|
8
|
+
export type PromoScopeFields = {
|
|
9
|
+
ticketTierId?: string | null;
|
|
10
|
+
bashEventId?: string | null;
|
|
11
|
+
eligibilityMode?: PromoEligibilityMode | null;
|
|
12
|
+
discountType?: PromoDiscountKind | null;
|
|
13
|
+
discountAmountInCents?: number | null;
|
|
14
|
+
discountAmountPercentage?: number | null;
|
|
15
|
+
eligibleTiers?: ReadonlyArray<{
|
|
16
|
+
ticketTierId: string;
|
|
17
|
+
}> | null;
|
|
18
|
+
ticketTier?: {
|
|
19
|
+
bashEventId: string;
|
|
20
|
+
} | null;
|
|
21
|
+
};
|
|
22
|
+
/** Explicit type wins; legacy rows derive it from whichever amount is set. */
|
|
23
|
+
export declare function promoCodeDiscountKind(promo: PromoScopeFields): PromoDiscountKind;
|
|
24
|
+
export declare function promoCodeBashEventId(promo: PromoScopeFields): string | null;
|
|
25
|
+
/**
|
|
26
|
+
* "ALL" for an all-tiers code (including tiers added later); otherwise the
|
|
27
|
+
* selected tier ids, falling back to the legacy single tier.
|
|
28
|
+
*/
|
|
29
|
+
export declare function promoCodeEligibleTierIds(promo: PromoScopeFields): "ALL" | string[];
|
|
30
|
+
export declare function promoCodeAppliesToTier(promo: PromoScopeFields, ticketTierId: string): boolean;
|
|
31
|
+
export type PromoCodeStatusReason = "expired" | "exhausted" | "already_used" | "disabled" | "invalid" | "host_review_required";
|
|
32
|
+
/** Public, logged-out view of a code. Never includes a promoter id or email. */
|
|
33
|
+
export type PromoCodeStatus = {
|
|
34
|
+
status: "valid" | PromoCodeStatusReason;
|
|
35
|
+
reason: PromoCodeStatusReason | null;
|
|
36
|
+
code: string;
|
|
37
|
+
discountType: PromoDiscountKind | null;
|
|
38
|
+
/** Percent for PERCENT, cents for FIXED_CASH, 0 for NONE. */
|
|
39
|
+
value: number;
|
|
40
|
+
eligibilityMode: PromoEligibilityMode | null;
|
|
41
|
+
/** Empty for all-tiers codes. */
|
|
42
|
+
eligibleTierIds: string[];
|
|
43
|
+
appliesToBashPoints: boolean;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Promoter share link: `/bash/<active vanity>?promo=CODE`, else the public
|
|
47
|
+
* id-slug path. The code is uppercased and URL-encoded. Legacy `?promocode=`
|
|
48
|
+
* and `?ref=` links keep working on the bash page.
|
|
49
|
+
*/
|
|
50
|
+
export declare function getPromoterShareUrl(args: {
|
|
51
|
+
bashEventId: string;
|
|
52
|
+
slug?: string | null;
|
|
53
|
+
vanityPaths?: ReadonlyArray<{
|
|
54
|
+
segment: string;
|
|
55
|
+
status: string;
|
|
56
|
+
}> | null;
|
|
57
|
+
code: string;
|
|
58
|
+
/** Absolute origin, e.g. "https://bash.community". Omit for a relative path. */
|
|
59
|
+
origin?: string;
|
|
60
|
+
}): string;
|
|
61
|
+
/** Host form payload for a bash-level promoter or promo code. */
|
|
62
|
+
export type PromoterCodeInput = {
|
|
63
|
+
code: string;
|
|
64
|
+
promoterUserId?: string | null;
|
|
65
|
+
promoterEmail?: string | null;
|
|
66
|
+
discountType: PromoDiscountKind;
|
|
67
|
+
/** Percent (1-100) for PERCENT, cents for FIXED_CASH, ignored for NONE. */
|
|
68
|
+
discountValue?: number | null;
|
|
69
|
+
eligibilityMode: PromoEligibilityMode;
|
|
70
|
+
eligibleTierIds?: string[];
|
|
71
|
+
discountAppliesToBashPoints?: boolean;
|
|
72
|
+
redeemBy?: string | null;
|
|
73
|
+
/** Maximum orders. */
|
|
74
|
+
maxRedemptions?: number | null;
|
|
75
|
+
maxUsesPerAccount?: number | null;
|
|
76
|
+
bashPointsRewardPerTicket?: number | null;
|
|
77
|
+
/** The promoter's rate for this bash, 0-10000 bps of eligible net ticket proceeds. */
|
|
78
|
+
promoterCommissionBps?: number | null;
|
|
79
|
+
/** The host opened and confirmed the Promoter reward section. */
|
|
80
|
+
promoterRewardReviewed?: boolean;
|
|
81
|
+
};
|
|
82
|
+
export type PromoterCodeStatusLabel = "active" | "expired" | "exhausted" | "disabled";
|
|
83
|
+
/** Validation shared by the host form and the API. Empty array means valid. */
|
|
84
|
+
export declare function promoterCodeInputErrors(input: PromoterCodeInput, bashTierIds: readonly string[]): string[];
|
|
85
|
+
//# sourceMappingURL=promoCodeScope.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"promoCodeScope.d.ts","sourceRoot":"","sources":["../src/promoCodeScope.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AAEH,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,SAAS,GAAG,YAAY,CAAC;AAClE,MAAM,MAAM,oBAAoB,GAAG,WAAW,GAAG,gBAAgB,CAAC;AAElE,MAAM,MAAM,gBAAgB,GAAG;IAC7B,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,eAAe,CAAC,EAAE,oBAAoB,GAAG,IAAI,CAAC;IAC9C,YAAY,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACxC,qBAAqB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,wBAAwB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzC,aAAa,CAAC,EAAE,aAAa,CAAC;QAAE,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,IAAI,CAAC;IAC/D,UAAU,CAAC,EAAE;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CAC7C,CAAC;AAEF,8EAA8E;AAC9E,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,gBAAgB,GAAG,iBAAiB,CAKhF;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,gBAAgB,GAAG,MAAM,GAAG,IAAI,CAE3E;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,gBAAgB,GAAG,KAAK,GAAG,MAAM,EAAE,CAKlF;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAG7F;AAED,MAAM,MAAM,qBAAqB,GAC7B,SAAS,GACT,WAAW,GACX,cAAc,GACd,UAAU,GACV,SAAS,GACT,sBAAsB,CAAC;AAE3B,gFAAgF;AAChF,MAAM,MAAM,eAAe,GAAG;IAC5B,MAAM,EAAE,OAAO,GAAG,qBAAqB,CAAC;IACxC,MAAM,EAAE,qBAAqB,GAAG,IAAI,CAAC;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACvC,6DAA6D;IAC7D,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,oBAAoB,GAAG,IAAI,CAAC;IAC7C,iCAAiC;IACjC,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,mBAAmB,EAAE,OAAO,CAAC;CAC9B,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE;IACxC,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,WAAW,CAAC,EAAE,aAAa,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,IAAI,CAAC;IACxE,IAAI,EAAE,MAAM,CAAC;IACb,gFAAgF;IAChF,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,MAAM,CAQT;AAED,iEAAiE;AACjE,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,YAAY,EAAE,iBAAiB,CAAC;IAChC,2EAA2E;IAC3E,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,eAAe,EAAE,oBAAoB,CAAC;IACtC,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,2BAA2B,CAAC,EAAE,OAAO,CAAC;IACtC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,sBAAsB;IACtB,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,yBAAyB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1C,sFAAsF;IACtF,qBAAqB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,iEAAiE;IACjE,sBAAsB,CAAC,EAAE,OAAO,CAAC;CAClC,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG,QAAQ,GAAG,SAAS,GAAG,WAAW,GAAG,UAAU,CAAC;AAEtF,+EAA+E;AAC/E,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,iBAAiB,EACxB,WAAW,EAAE,SAAS,MAAM,EAAE,GAC7B,MAAM,EAAE,CAyCV"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { getPublicBashDetailPath } from "./utils/slugUtils.js";
|
|
2
|
+
/** Explicit type wins; legacy rows derive it from whichever amount is set. */
|
|
3
|
+
export function promoCodeDiscountKind(promo) {
|
|
4
|
+
if (promo.discountType)
|
|
5
|
+
return promo.discountType;
|
|
6
|
+
if ((promo.discountAmountPercentage ?? 0) > 0)
|
|
7
|
+
return "PERCENT";
|
|
8
|
+
if ((promo.discountAmountInCents ?? 0) > 0)
|
|
9
|
+
return "FIXED_CASH";
|
|
10
|
+
return "NONE";
|
|
11
|
+
}
|
|
12
|
+
export function promoCodeBashEventId(promo) {
|
|
13
|
+
return promo.bashEventId ?? promo.ticketTier?.bashEventId ?? null;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* "ALL" for an all-tiers code (including tiers added later); otherwise the
|
|
17
|
+
* selected tier ids, falling back to the legacy single tier.
|
|
18
|
+
*/
|
|
19
|
+
export function promoCodeEligibleTierIds(promo) {
|
|
20
|
+
if (promo.eligibilityMode === "ALL_TIERS")
|
|
21
|
+
return "ALL";
|
|
22
|
+
const selected = (promo.eligibleTiers ?? []).map((t) => t.ticketTierId);
|
|
23
|
+
if (selected.length > 0)
|
|
24
|
+
return [...new Set(selected)];
|
|
25
|
+
return promo.ticketTierId ? [promo.ticketTierId] : [];
|
|
26
|
+
}
|
|
27
|
+
export function promoCodeAppliesToTier(promo, ticketTierId) {
|
|
28
|
+
const ids = promoCodeEligibleTierIds(promo);
|
|
29
|
+
return ids === "ALL" || ids.includes(ticketTierId);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Promoter share link: `/bash/<active vanity>?promo=CODE`, else the public
|
|
33
|
+
* id-slug path. The code is uppercased and URL-encoded. Legacy `?promocode=`
|
|
34
|
+
* and `?ref=` links keep working on the bash page.
|
|
35
|
+
*/
|
|
36
|
+
export function getPromoterShareUrl(args) {
|
|
37
|
+
const active = args.vanityPaths?.find((v) => v.status === "Active" && v.segment.trim());
|
|
38
|
+
const path = active
|
|
39
|
+
? `/bash/${encodeURIComponent(active.segment.trim().toLowerCase())}`
|
|
40
|
+
: getPublicBashDetailPath(args.bashEventId, args.slug);
|
|
41
|
+
const query = `?promo=${encodeURIComponent(args.code.trim().toUpperCase())}`;
|
|
42
|
+
const origin = args.origin?.replace(/\/$/, "") ?? "";
|
|
43
|
+
return `${origin}${path}${query}`;
|
|
44
|
+
}
|
|
45
|
+
/** Validation shared by the host form and the API. Empty array means valid. */
|
|
46
|
+
export function promoterCodeInputErrors(input, bashTierIds) {
|
|
47
|
+
const errors = [];
|
|
48
|
+
const code = input.code?.trim() ?? "";
|
|
49
|
+
if (!code)
|
|
50
|
+
errors.push("Enter a code.");
|
|
51
|
+
else if (!/^[A-Za-z0-9_-]{2,32}$/.test(code)) {
|
|
52
|
+
errors.push("Codes use 2-32 letters, numbers, dashes, or underscores.");
|
|
53
|
+
}
|
|
54
|
+
if (input.discountType === "PERCENT") {
|
|
55
|
+
const pct = Number(input.discountValue);
|
|
56
|
+
if (!Number.isInteger(pct) || pct < 1 || pct > 100) {
|
|
57
|
+
errors.push("Guest discount must be between 1% and 100%.");
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
else if (input.discountType === "FIXED_CASH") {
|
|
61
|
+
const cents = Number(input.discountValue);
|
|
62
|
+
if (!Number.isInteger(cents) || cents <= 0)
|
|
63
|
+
errors.push("Enter a fixed discount above $0.");
|
|
64
|
+
}
|
|
65
|
+
if (input.eligibilityMode === "SELECTED_TIERS") {
|
|
66
|
+
const ids = input.eligibleTierIds ?? [];
|
|
67
|
+
if (ids.length === 0)
|
|
68
|
+
errors.push("Pick at least one ticket tier.");
|
|
69
|
+
if (ids.some((id) => !bashTierIds.includes(id)))
|
|
70
|
+
errors.push("A selected tier isn't on this bash.");
|
|
71
|
+
}
|
|
72
|
+
if (input.promoterCommissionBps != null) {
|
|
73
|
+
const bps = input.promoterCommissionBps;
|
|
74
|
+
if (!Number.isInteger(bps) || bps < 0 || bps > 10_000) {
|
|
75
|
+
errors.push("Promoter commission must be between 0% and 100%.");
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
for (const [label, value] of [
|
|
79
|
+
["Maximum orders", input.maxRedemptions],
|
|
80
|
+
["Per-guest limit", input.maxUsesPerAccount],
|
|
81
|
+
["BashPoints per ticket", input.bashPointsRewardPerTicket],
|
|
82
|
+
]) {
|
|
83
|
+
if (value != null && (!Number.isInteger(value) || value < 0)) {
|
|
84
|
+
errors.push(`${label} must be a whole number of 0 or more.`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
const hasPromoter = !!(input.promoterUserId || input.promoterEmail?.trim());
|
|
88
|
+
if (hasPromoter && !input.promoterRewardReviewed) {
|
|
89
|
+
errors.push("Review the promoter reward before saving.");
|
|
90
|
+
}
|
|
91
|
+
return errors;
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=promoCodeScope.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"promoCodeScope.js","sourceRoot":"","sources":["../src/promoCodeScope.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,13 +1,20 @@
|
|
|
1
|
-
import { OfferDiscountType, SpecialOfferType, } from "@prisma/client";
|
|
1
|
+
import { OfferDiscountType, PromoCodeEligibilityMode, SpecialOfferType, } from "@prisma/client";
|
|
2
2
|
import { describe, expect, test } from "@jest/globals";
|
|
3
3
|
import { calculatePromoCodeDiscount, calculateSpecialOfferDiscount, calculateBOGODiscount, calculateGroupDiscount, calculateVolumeDiscount, calculateEarlyBirdDiscount, calculateBundleDiscount, formatDiscountDescription, } from "../../discountEngine/discountCalculator.js";
|
|
4
4
|
const NOW = new Date("2026-01-01T00:00:00Z");
|
|
5
5
|
function basePromoCode(overrides) {
|
|
6
6
|
return {
|
|
7
|
+
bashEventId: null,
|
|
7
8
|
ticketTierId: "tier-1",
|
|
9
|
+
eligibilityMode: PromoCodeEligibilityMode.SELECTED_TIERS,
|
|
10
|
+
discountType: null,
|
|
11
|
+
discountAppliesToBashPoints: false,
|
|
12
|
+
disabledAt: null,
|
|
13
|
+
legacyReviewFlag: null,
|
|
8
14
|
discountAmountInCents: null,
|
|
9
15
|
discountAmountPercentage: null,
|
|
10
16
|
maxRedemptions: null,
|
|
17
|
+
maxUsesPerAccount: null,
|
|
11
18
|
redeemBy: null,
|
|
12
19
|
promoterId: null,
|
|
13
20
|
stripeCouponId: null,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"discountCalculator.test.js","sourceRoot":"","sources":["../../../../src/utils/__tests__/discountEngine/discountCalculator.test.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"discountCalculator.test.js","sourceRoot":"","sources":["../../../../src/utils/__tests__/discountEngine/discountCalculator.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Testing business logic without database dependencies
|
|
4
4
|
*/
|
|
5
5
|
import { BashPassTier, MembershipTier } from "@prisma/client";
|
|
6
|
-
import { calculateDiscountFromPromoCode, convertCentsToDollars, convertDollarsToCents, calculateBashAppFee, calculateBashAppFeeWithMembershipDiscount, calculateStripeFee, calculateStripeProcessingFeeCents, calculateTotalPriceWithoutTax, calculateTotalBashPoints, calculateMixedPricingBashPoints, calculateStripeDonationFee, calculateServiceFeeWithMembershipDiscount, calculatePartnerFeeWithMembershipDiscount, calculateBashPlatformFeeCents, splitBashPlatformFeeForTicketCheckout, computeTicketApplicationFeeAmountCents, computeGuestTicketCheckoutBreakdown, ticketCommissionCents,
|
|
6
|
+
import { calculateDiscountFromPromoCode, convertCentsToDollars, convertDollarsToCents, calculateBashAppFee, calculateBashAppFeeWithMembershipDiscount, calculateStripeFee, calculateStripeProcessingFeeCents, calculateTotalPriceWithoutTax, calculateTotalBashPoints, calculateMixedPricingBashPoints, calculateStripeDonationFee, calculateServiceFeeWithMembershipDiscount, calculatePartnerFeeWithMembershipDiscount, calculateBashPlatformFeeCents, splitBashPlatformFeeForTicketCheckout, computeTicketApplicationFeeAmountCents, computeGuestTicketCheckoutBreakdown, ticketCommissionCents, eligibleNetTicketProceedsCents, ticketCommissionBpsError, TEMPORARY_SETTLEMENT_SAFETY_REMAINDER_CENTS, MAX_TICKET_COMMISSION_BPS, guestAllInUnitPriceCents, guestCheckoutHasNoAddedFees, lowestGuestAllInPriceCents, hostAbsorbsTicketProcessing, userHasActiveBashPass, getEffectiveBashPassTier, getBashPassMonthlyCapRemaining, higherBashPassTier, membershipGrantsBashPassTier, VENUE_PRICING_PLAN_DATA, } from "../paymentUtils.js";
|
|
7
7
|
import { VenuePricingPlan } from "@prisma/client";
|
|
8
8
|
describe("PaymentUtils - Core Functions", () => {
|
|
9
9
|
describe("Currency Conversion", () => {
|
|
@@ -210,11 +210,94 @@ describe("PaymentUtils - Core Functions", () => {
|
|
|
210
210
|
expect(r.bashPlatformTotalCents).toBe(0);
|
|
211
211
|
expect(r.applicationFeeAmountCents).toBe(r.stripeProcessingCents);
|
|
212
212
|
});
|
|
213
|
-
test("ticketCommissionCents floors bps of the
|
|
213
|
+
test("ticketCommissionCents floors bps of the basis and pays up to 100%", () => {
|
|
214
|
+
expect(MAX_TICKET_COMMISSION_BPS).toBe(10000);
|
|
214
215
|
expect(ticketCommissionCents(10000, 1500)).toBe(1500);
|
|
215
216
|
expect(ticketCommissionCents(10000, 0)).toBe(0);
|
|
216
|
-
expect(ticketCommissionCents(
|
|
217
|
-
expect(
|
|
217
|
+
expect(ticketCommissionCents(1912, 10000)).toBe(1912);
|
|
218
|
+
expect(ticketCommissionCents(1912, 5000)).toBe(956);
|
|
219
|
+
expect(ticketCommissionCents(1912, 99999)).toBe(1912);
|
|
220
|
+
expect(ticketCommissionCents(0, 10000)).toBe(0);
|
|
221
|
+
});
|
|
222
|
+
test("ticketCommissionBpsError accepts 0-100% and rejects the rest", () => {
|
|
223
|
+
expect(ticketCommissionBpsError(0)).toBeNull();
|
|
224
|
+
expect(ticketCommissionBpsError(5000)).toBeNull();
|
|
225
|
+
expect(ticketCommissionBpsError(10000)).toBeNull();
|
|
226
|
+
expect(ticketCommissionBpsError(null)).toBeNull();
|
|
227
|
+
expect(ticketCommissionBpsError(10001)).toMatch(/between 0% and 100%/);
|
|
228
|
+
expect(ticketCommissionBpsError(-1)).toMatch(/between 0% and 100%/);
|
|
229
|
+
expect(ticketCommissionBpsError(12.5)).toMatch(/whole number/);
|
|
230
|
+
});
|
|
231
|
+
describe("eligibleNetTicketProceedsCents: $20 sale", () => {
|
|
232
|
+
const fees = (feeHandling, platformFeeEnabled) => computeTicketApplicationFeeAmountCents({
|
|
233
|
+
discountedSubtotalCents: 2000,
|
|
234
|
+
platformFeeEnabled,
|
|
235
|
+
platformFeeRate: 0.03,
|
|
236
|
+
feeHandling,
|
|
237
|
+
bashPassWaivesGuestFee: false,
|
|
238
|
+
});
|
|
239
|
+
const net = (f, eligible = 2000) => eligibleNetTicketProceedsCents({
|
|
240
|
+
eligibleSubtotalCents: eligible,
|
|
241
|
+
discountedSubtotalCents: 2000,
|
|
242
|
+
bashPlatformTotalCents: f.bashPlatformTotalCents,
|
|
243
|
+
guestPlatformLineCents: f.guestPlatformLineCents,
|
|
244
|
+
stripeProcessingCents: f.stripeProcessingCents,
|
|
245
|
+
guestProcessingLineCents: f.guestProcessingLineCents,
|
|
246
|
+
});
|
|
247
|
+
test("host absorbs, platform fee off: 2000 - 88 = 1912; 100% owes 1912, 50% owes 956", () => {
|
|
248
|
+
const f = fees("HostAbsorbs", false);
|
|
249
|
+
expect(f.applicationFeeAmountCents).toBe(88);
|
|
250
|
+
expect(net(f)).toBe(1912);
|
|
251
|
+
expect(ticketCommissionCents(net(f), 10000)).toBe(1912);
|
|
252
|
+
expect(ticketCommissionCents(net(f), 5000)).toBe(956);
|
|
253
|
+
});
|
|
254
|
+
test("host absorbs a 3% platform fee: app fee 148, net 1852", () => {
|
|
255
|
+
const f = fees("HostAbsorbs", true);
|
|
256
|
+
expect(f.applicationFeeAmountCents).toBe(148);
|
|
257
|
+
expect(net(f)).toBe(1852);
|
|
258
|
+
expect(ticketCommissionCents(net(f), 5000)).toBe(926);
|
|
259
|
+
});
|
|
260
|
+
test("guest pays the fees: the guest lines cover them, so the host share is close to the subtotal", () => {
|
|
261
|
+
const f = fees("GuestPays", true);
|
|
262
|
+
const hostShare = Math.max(0, f.bashPlatformTotalCents - f.guestPlatformLineCents) +
|
|
263
|
+
Math.max(0, f.stripeProcessingCents - f.guestProcessingLineCents);
|
|
264
|
+
expect(net(f)).toBe(2000 - hostShare);
|
|
265
|
+
expect(net(f)).toBeGreaterThan(1900);
|
|
266
|
+
});
|
|
267
|
+
test("only the code's tier counts: a $20 eligible line in a $40 cart carries half the fees", () => {
|
|
268
|
+
const both = computeTicketApplicationFeeAmountCents({
|
|
269
|
+
discountedSubtotalCents: 4000,
|
|
270
|
+
platformFeeEnabled: false,
|
|
271
|
+
platformFeeRate: 0.03,
|
|
272
|
+
feeHandling: "HostAbsorbs",
|
|
273
|
+
bashPassWaivesGuestFee: false,
|
|
274
|
+
});
|
|
275
|
+
const eligible = eligibleNetTicketProceedsCents({
|
|
276
|
+
eligibleSubtotalCents: 2000,
|
|
277
|
+
discountedSubtotalCents: 4000,
|
|
278
|
+
bashPlatformTotalCents: both.bashPlatformTotalCents,
|
|
279
|
+
guestPlatformLineCents: both.guestPlatformLineCents,
|
|
280
|
+
stripeProcessingCents: both.stripeProcessingCents,
|
|
281
|
+
guestProcessingLineCents: both.guestProcessingLineCents,
|
|
282
|
+
});
|
|
283
|
+
expect(eligible).toBe(2000 - Math.ceil(both.stripeProcessingCents / 2));
|
|
284
|
+
});
|
|
285
|
+
test("zero eligible proceeds owe nothing", () => {
|
|
286
|
+
expect(net(fees("HostAbsorbs", false), 0)).toBe(0);
|
|
287
|
+
});
|
|
288
|
+
});
|
|
289
|
+
test("withholding can take the full eligible net when the safety remainder is 0", () => {
|
|
290
|
+
expect(TEMPORARY_SETTLEMENT_SAFETY_REMAINDER_CENTS).toBe(0);
|
|
291
|
+
const r = computeTicketApplicationFeeAmountCents({
|
|
292
|
+
discountedSubtotalCents: 2000,
|
|
293
|
+
platformFeeEnabled: false,
|
|
294
|
+
platformFeeRate: 0.03,
|
|
295
|
+
feeHandling: "HostAbsorbs",
|
|
296
|
+
bashPassWaivesGuestFee: false,
|
|
297
|
+
performerCommissionCents: 1912,
|
|
298
|
+
});
|
|
299
|
+
expect(r.performerCommissionCents).toBe(1912);
|
|
300
|
+
expect(r.totalChargedCents - r.applicationFeeAmountCents).toBe(0);
|
|
218
301
|
});
|
|
219
302
|
test("PROMO-002: performer cut is withheld on the application fee, not the guest total", () => {
|
|
220
303
|
const base = computeTicketApplicationFeeAmountCents({
|