@bash-app/bash-common 30.225.0 → 30.227.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 (142) hide show
  1. package/dist/__tests__/agePolicy.test.d.ts +2 -0
  2. package/dist/__tests__/agePolicy.test.d.ts.map +1 -0
  3. package/dist/__tests__/agePolicy.test.js +203 -0
  4. package/dist/__tests__/agePolicy.test.js.map +1 -0
  5. package/dist/__tests__/getDisplayGender.test.d.ts +2 -0
  6. package/dist/__tests__/getDisplayGender.test.d.ts.map +1 -0
  7. package/dist/__tests__/getDisplayGender.test.js +34 -0
  8. package/dist/__tests__/getDisplayGender.test.js.map +1 -0
  9. package/dist/__tests__/statusEnums.test.d.ts +2 -0
  10. package/dist/__tests__/statusEnums.test.d.ts.map +1 -0
  11. package/dist/__tests__/statusEnums.test.js +24 -0
  12. package/dist/__tests__/statusEnums.test.js.map +1 -0
  13. package/dist/aiApproval.d.ts +89 -0
  14. package/dist/aiApproval.d.ts.map +1 -0
  15. package/dist/aiApproval.js +82 -0
  16. package/dist/aiApproval.js.map +1 -0
  17. package/dist/definitions.d.ts +44 -2
  18. package/dist/definitions.d.ts.map +1 -1
  19. package/dist/definitions.js +106 -2
  20. package/dist/definitions.js.map +1 -1
  21. package/dist/extendedSchemas.d.ts +280 -105
  22. package/dist/extendedSchemas.d.ts.map +1 -1
  23. package/dist/extendedSchemas.js +34 -2
  24. package/dist/extendedSchemas.js.map +1 -1
  25. package/dist/index.d.ts +5 -2
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +4 -1
  28. package/dist/index.js.map +1 -1
  29. package/dist/legalTemplates.d.ts +1 -1
  30. package/dist/legalTemplates.js +1 -1
  31. package/dist/utils/__tests__/badgeUtils.test.d.ts +2 -0
  32. package/dist/utils/__tests__/badgeUtils.test.d.ts.map +1 -0
  33. package/dist/utils/__tests__/badgeUtils.test.js +157 -0
  34. package/dist/utils/__tests__/badgeUtils.test.js.map +1 -0
  35. package/dist/utils/__tests__/bashPointsPaymentUtils.test.d.ts +2 -0
  36. package/dist/utils/__tests__/bashPointsPaymentUtils.test.d.ts.map +1 -0
  37. package/dist/utils/__tests__/bashPointsPaymentUtils.test.js +114 -0
  38. package/dist/utils/__tests__/bashPointsPaymentUtils.test.js.map +1 -0
  39. package/dist/utils/__tests__/contentFilterUtils.test.d.ts +2 -0
  40. package/dist/utils/__tests__/contentFilterUtils.test.d.ts.map +1 -0
  41. package/dist/utils/__tests__/contentFilterUtils.test.js +443 -0
  42. package/dist/utils/__tests__/contentFilterUtils.test.js.map +1 -0
  43. package/dist/utils/__tests__/displayDateUtils.test.d.ts +2 -0
  44. package/dist/utils/__tests__/displayDateUtils.test.d.ts.map +1 -0
  45. package/dist/utils/__tests__/displayDateUtils.test.js +105 -0
  46. package/dist/utils/__tests__/displayDateUtils.test.js.map +1 -0
  47. package/dist/utils/__tests__/flyerUtils.test.d.ts +2 -0
  48. package/dist/utils/__tests__/flyerUtils.test.d.ts.map +1 -0
  49. package/dist/utils/__tests__/flyerUtils.test.js +49 -0
  50. package/dist/utils/__tests__/flyerUtils.test.js.map +1 -0
  51. package/dist/utils/__tests__/getBackendHost.test.d.ts +2 -0
  52. package/dist/utils/__tests__/getBackendHost.test.d.ts.map +1 -0
  53. package/dist/utils/__tests__/getBackendHost.test.js +104 -0
  54. package/dist/utils/__tests__/getBackendHost.test.js.map +1 -0
  55. package/dist/utils/__tests__/getFrontendHost.test.d.ts +2 -0
  56. package/dist/utils/__tests__/getFrontendHost.test.d.ts.map +1 -0
  57. package/dist/utils/__tests__/getFrontendHost.test.js +207 -0
  58. package/dist/utils/__tests__/getFrontendHost.test.js.map +1 -0
  59. package/dist/utils/__tests__/promoCodesUtils.test.d.ts +2 -0
  60. package/dist/utils/__tests__/promoCodesUtils.test.d.ts.map +1 -0
  61. package/dist/utils/__tests__/promoCodesUtils.test.js +183 -0
  62. package/dist/utils/__tests__/promoCodesUtils.test.js.map +1 -0
  63. package/dist/utils/__tests__/qrCodeUtils.test.d.ts +2 -0
  64. package/dist/utils/__tests__/qrCodeUtils.test.d.ts.map +1 -0
  65. package/dist/utils/__tests__/qrCodeUtils.test.js +99 -0
  66. package/dist/utils/__tests__/qrCodeUtils.test.js.map +1 -0
  67. package/dist/utils/__tests__/stripeAccountUtils.test.d.ts +2 -0
  68. package/dist/utils/__tests__/stripeAccountUtils.test.d.ts.map +1 -0
  69. package/dist/utils/__tests__/stripeAccountUtils.test.js +75 -0
  70. package/dist/utils/__tests__/stripeAccountUtils.test.js.map +1 -0
  71. package/dist/utils/blog/__tests__/getRelatedBlogPosts.test.d.ts +2 -0
  72. package/dist/utils/blog/__tests__/getRelatedBlogPosts.test.d.ts.map +1 -0
  73. package/dist/utils/blog/__tests__/getRelatedBlogPosts.test.js +233 -0
  74. package/dist/utils/blog/__tests__/getRelatedBlogPosts.test.js.map +1 -0
  75. package/dist/utils/blog/blogCommentDbUtils.d.ts +161 -0
  76. package/dist/utils/blog/blogCommentDbUtils.d.ts.map +1 -0
  77. package/dist/utils/blog/blogCommentDbUtils.js +111 -0
  78. package/dist/utils/blog/blogCommentDbUtils.js.map +1 -0
  79. package/dist/utils/blog/blogDbUtils.d.ts +10 -0
  80. package/dist/utils/blog/blogDbUtils.d.ts.map +1 -1
  81. package/dist/utils/blog/blogDbUtils.js +71 -0
  82. package/dist/utils/blog/blogDbUtils.js.map +1 -1
  83. package/dist/utils/flyerUtils.d.ts +42 -0
  84. package/dist/utils/flyerUtils.d.ts.map +1 -0
  85. package/dist/utils/flyerUtils.js +104 -0
  86. package/dist/utils/flyerUtils.js.map +1 -0
  87. package/dist/utils/urlUtils.d.ts +10 -0
  88. package/dist/utils/urlUtils.d.ts.map +1 -1
  89. package/dist/utils/urlUtils.js +24 -5
  90. package/dist/utils/urlUtils.js.map +1 -1
  91. package/dist/utils/userUtils.d.ts +32 -0
  92. package/dist/utils/userUtils.d.ts.map +1 -1
  93. package/dist/utils/userUtils.js +27 -0
  94. package/dist/utils/userUtils.js.map +1 -1
  95. package/package.json +1 -1
  96. package/prisma/schema.prisma +1196 -845
  97. package/src/__tests__/agePolicy.test.ts +257 -0
  98. package/src/__tests__/getDisplayGender.test.ts +50 -0
  99. package/src/__tests__/statusEnums.test.ts +36 -0
  100. package/src/aiApproval.ts +118 -0
  101. package/src/definitions.ts +138 -1
  102. package/src/extendedSchemas.ts +86 -3
  103. package/src/index.ts +15 -0
  104. package/src/legalTemplates.ts +1 -1
  105. package/src/utils/__tests__/badgeUtils.test.ts +191 -0
  106. package/src/utils/__tests__/bashPointsPaymentUtils.test.ts +153 -0
  107. package/src/utils/__tests__/contentFilterUtils.test.ts +547 -0
  108. package/src/utils/__tests__/displayDateUtils.test.ts +113 -0
  109. package/src/utils/__tests__/flyerUtils.test.ts +70 -0
  110. package/src/utils/__tests__/getBackendHost.test.ts +128 -0
  111. package/src/utils/__tests__/getFrontendHost.test.ts +232 -0
  112. package/src/utils/__tests__/promoCodesUtils.test.ts +237 -0
  113. package/src/utils/__tests__/qrCodeUtils.test.ts +143 -0
  114. package/src/utils/__tests__/stripeAccountUtils.test.ts +93 -0
  115. package/src/utils/blog/__tests__/getRelatedBlogPosts.test.ts +271 -0
  116. package/src/utils/blog/blogCommentDbUtils.ts +161 -0
  117. package/src/utils/blog/blogDbUtils.ts +95 -1
  118. package/src/utils/flyerUtils.ts +137 -0
  119. package/src/utils/urlUtils.ts +27 -5
  120. package/src/utils/userUtils.ts +40 -0
  121. package/dist/utils/__tests__/cancellationPolicyRefundResolver.test.d.ts +0 -6
  122. package/dist/utils/__tests__/cancellationPolicyRefundResolver.test.d.ts.map +0 -1
  123. package/dist/utils/__tests__/cancellationPolicyRefundResolver.test.js +0 -104
  124. package/dist/utils/__tests__/cancellationPolicyRefundResolver.test.js.map +0 -1
  125. package/dist/utils/service/serviceRateDBUtils.d.ts +0 -1
  126. package/dist/utils/service/serviceRateDBUtils.d.ts.map +0 -1
  127. package/dist/utils/service/serviceRateDBUtils.js +0 -159
  128. package/dist/utils/service/serviceRateDBUtils.js.map +0 -1
  129. package/prisma/migrations/add_bash_availability.sql +0 -53
  130. package/prisma/migrations/add_bashcash_pricing_to_ticket_tier.sql +0 -15
  131. package/prisma/migrations/add_bashpoints_purchase_tracking.sql +0 -33
  132. package/prisma/migrations/add_event_group_allow_auto_join.sql +0 -17
  133. package/prisma/migrations/add_group_member_status_not_going_maybe.sql +0 -5
  134. package/prisma/migrations/add_groups_and_momentum.sql +0 -135
  135. package/prisma/migrations/add_groups_momentum_phase0_4.sql +0 -200
  136. package/prisma/migrations/add_new_feature_tables.sql +0 -140
  137. package/prisma/migrations/add_pricing_type_enum.sql +0 -88
  138. package/prisma/migrations/add_tier_privacy_and_fee_handling.sql +0 -29
  139. package/prisma/migrations/diagnostic_bashcash_columns.sql +0 -157
  140. package/prisma/migrations/fix_bashcash_referral_code_schema_mismatch.sql +0 -81
  141. package/prisma/migrations/rename_bashcash_to_bashpoints.sql +0 -183
  142. package/prisma/migrations/rename_bashcredits_to_bashpoints.sql +0 -96
@@ -0,0 +1,114 @@
1
+ /**
2
+ * bashPointsPaymentUtils — earning math + display + deprecated stubs.
3
+ *
4
+ * BashPoints are loyalty cashback. The active code paths are:
5
+ * - calculateBashPointsCashback(amountCents, rate) → integer points
6
+ * - formatBashPoints(n) → "1,000 points"
7
+ *
8
+ * The "service booking" overloads were intentionally deprecated because
9
+ * BashPoints have no fixed dollar value and cannot pay for services. We pin
10
+ * the deprecated stubs here so they stay benign (return safe defaults, log a
11
+ * warning) — accidentally re-enabling them would cause real money loss.
12
+ */
13
+ import { formatBashPoints, calculateBashPointsCashback, centsToBashPoints, bashPointsToCents, calculateMaxBashPointsForBooking, calculateSplitPayment, validateBashPointsPayment, } from "../bashPointsPaymentUtils.js";
14
+ describe("formatBashPoints", () => {
15
+ it("uses singular 'point' for exactly 1", () => {
16
+ expect(formatBashPoints(1)).toBe("1 point");
17
+ });
18
+ it("uses plural 'points' for 0", () => {
19
+ expect(formatBashPoints(0)).toBe("0 points");
20
+ });
21
+ it("uses plural for >1", () => {
22
+ expect(formatBashPoints(2)).toBe("2 points");
23
+ });
24
+ it("inserts en-US thousands separators", () => {
25
+ expect(formatBashPoints(1000)).toBe("1,000 points");
26
+ expect(formatBashPoints(28750)).toBe("28,750 points");
27
+ expect(formatBashPoints(1_000_000)).toBe("1,000,000 points");
28
+ });
29
+ it("formats negative values (defensive — should never happen but no throw)", () => {
30
+ // -1 !== 1 so it gets the plural suffix
31
+ expect(formatBashPoints(-5)).toBe("-5 points");
32
+ });
33
+ });
34
+ describe("calculateBashPointsCashback", () => {
35
+ it("awards 5% on a $10.00 (1000¢) purchase → 50 points", () => {
36
+ expect(calculateBashPointsCashback(1000, 0.05)).toBe(50);
37
+ });
38
+ it("awards 0 points on a $0 purchase", () => {
39
+ expect(calculateBashPointsCashback(0, 0.05)).toBe(0);
40
+ });
41
+ it("awards 0 points when the rate is 0", () => {
42
+ expect(calculateBashPointsCashback(10_000, 0)).toBe(0);
43
+ });
44
+ it("FLOORS fractional results (never over-awards)", () => {
45
+ // 333 * 0.05 = 16.65 → floor → 16
46
+ expect(calculateBashPointsCashback(333, 0.05)).toBe(16);
47
+ });
48
+ it("handles a 100% rebate rate", () => {
49
+ expect(calculateBashPointsCashback(2500, 1)).toBe(2500);
50
+ });
51
+ it("rate > 1 still floors (host can configure bonuses; trust input)", () => {
52
+ expect(calculateBashPointsCashback(100, 1.5)).toBe(150);
53
+ });
54
+ it("returns 0 (not negative) for negative amounts after floor", () => {
55
+ // Math.floor(-1) = -1; we don't bound the result to >=0 in source,
56
+ // so this pins the actual contract: negative inputs flow through as-is.
57
+ expect(calculateBashPointsCashback(-100, 0.05)).toBe(-5);
58
+ });
59
+ });
60
+ describe("DEPRECATED stubs — must remain safe defaults", () => {
61
+ let warnSpy;
62
+ beforeEach(() => {
63
+ warnSpy = jest.spyOn(console, "warn").mockImplementation(() => { });
64
+ });
65
+ afterEach(() => {
66
+ warnSpy.mockRestore();
67
+ });
68
+ describe("centsToBashPoints", () => {
69
+ it("returns the input as-is and warns", () => {
70
+ expect(centsToBashPoints(1234)).toBe(1234);
71
+ expect(warnSpy).toHaveBeenCalledWith(expect.stringContaining("DEPRECATED: centsToBashPoints"));
72
+ });
73
+ });
74
+ describe("bashPointsToCents", () => {
75
+ it("returns the input as-is and warns", () => {
76
+ expect(bashPointsToCents(500)).toBe(500);
77
+ expect(warnSpy).toHaveBeenCalledWith(expect.stringContaining("DEPRECATED: bashPointsToCents"));
78
+ });
79
+ });
80
+ describe("calculateMaxBashPointsForBooking", () => {
81
+ it("returns 0 (no BashPoints can be applied to a service booking) and warns", () => {
82
+ expect(calculateMaxBashPointsForBooking(10_000, 5_000)).toBe(0);
83
+ expect(warnSpy).toHaveBeenCalledWith(expect.stringContaining("DEPRECATED: calculateMaxBashPointsForBooking"));
84
+ });
85
+ });
86
+ describe("calculateSplitPayment", () => {
87
+ it("forces the full amount onto Stripe (BashPoints contribution = 0) and warns", () => {
88
+ const result = calculateSplitPayment(10_000, 9_999);
89
+ expect(result).toEqual({
90
+ bashPointsCents: 0,
91
+ stripeCents: 10_000,
92
+ bashPointsCredits: 0,
93
+ });
94
+ expect(warnSpy).toHaveBeenCalledWith(expect.stringContaining("DEPRECATED: calculateSplitPayment"));
95
+ });
96
+ it("preserves the original total on stripeCents even when called with 0", () => {
97
+ const result = calculateSplitPayment(0, 100);
98
+ expect(result.stripeCents).toBe(0);
99
+ });
100
+ });
101
+ describe("validateBashPointsPayment", () => {
102
+ it("ALWAYS returns invalid with a clear redirect-to-Stripe message", () => {
103
+ const result = validateBashPointsPayment(100, 1_000, 500);
104
+ expect(result.valid).toBe(false);
105
+ expect(result.errorMessage).toMatch(/credit card/i);
106
+ expect(result.errorMessage).toMatch(/BashPoints-priced tickets/i);
107
+ });
108
+ it("rejects even when the user has enough balance (no special-case bypass)", () => {
109
+ // 1_000_000 balance, 100 needed → still rejected because services can't take BashPoints.
110
+ expect(validateBashPointsPayment(100, 1_000_000, 100).valid).toBe(false);
111
+ });
112
+ });
113
+ });
114
+ //# sourceMappingURL=bashPointsPaymentUtils.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bashPointsPaymentUtils.test.js","sourceRoot":"","sources":["../../../src/utils/__tests__/bashPointsPaymentUtils.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EACL,gBAAgB,EAChB,2BAA2B,EAC3B,iBAAiB,EACjB,iBAAiB,EACjB,gCAAgC,EAChC,qBAAqB,EACrB,yBAAyB,GAC1B,MAAM,8BAA8B,CAAC;AAEtC,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IAChC,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;QAC7C,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4BAA4B,EAAE,GAAG,EAAE;QACpC,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oBAAoB,EAAE,GAAG,EAAE;QAC5B,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;QAC5C,MAAM,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QACpD,MAAM,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QACtD,MAAM,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;IAC/D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wEAAwE,EAAE,GAAG,EAAE;QAChF,wCAAwC;QACxC,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,6BAA6B,EAAE,GAAG,EAAE;IAC3C,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;QAC5D,MAAM,CAAC,2BAA2B,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC3D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;QAC1C,MAAM,CAAC,2BAA2B,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACvD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;QAC5C,MAAM,CAAC,2BAA2B,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,kCAAkC;QAClC,MAAM,CAAC,2BAA2B,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4BAA4B,EAAE,GAAG,EAAE;QACpC,MAAM,CAAC,2BAA2B,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iEAAiE,EAAE,GAAG,EAAE;QACzE,MAAM,CAAC,2BAA2B,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2DAA2D,EAAE,GAAG,EAAE;QACnE,mEAAmE;QACnE,wEAAwE;QACxE,MAAM,CAAC,2BAA2B,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,8CAA8C,EAAE,GAAG,EAAE;IAC5D,IAAI,OAAyB,CAAC;IAE9B,UAAU,CAAC,GAAG,EAAE;QACd,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,kBAAkB,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IACrE,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,OAAO,CAAC,WAAW,EAAE,CAAC;IACxB,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;QACjC,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;YAC3C,MAAM,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC3C,MAAM,CAAC,OAAO,CAAC,CAAC,oBAAoB,CAClC,MAAM,CAAC,gBAAgB,CAAC,+BAA+B,CAAC,CACzD,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;QACjC,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;YAC3C,MAAM,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACzC,MAAM,CAAC,OAAO,CAAC,CAAC,oBAAoB,CAClC,MAAM,CAAC,gBAAgB,CAAC,+BAA+B,CAAC,CACzD,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,kCAAkC,EAAE,GAAG,EAAE;QAChD,EAAE,CAAC,yEAAyE,EAAE,GAAG,EAAE;YACjF,MAAM,CAAC,gCAAgC,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAChE,MAAM,CAAC,OAAO,CAAC,CAAC,oBAAoB,CAClC,MAAM,CAAC,gBAAgB,CAAC,8CAA8C,CAAC,CACxE,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;QACrC,EAAE,CAAC,4EAA4E,EAAE,GAAG,EAAE;YACpF,MAAM,MAAM,GAAG,qBAAqB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;YACpD,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC;gBACrB,eAAe,EAAE,CAAC;gBAClB,WAAW,EAAE,MAAM;gBACnB,iBAAiB,EAAE,CAAC;aACrB,CAAC,CAAC;YACH,MAAM,CAAC,OAAO,CAAC,CAAC,oBAAoB,CAClC,MAAM,CAAC,gBAAgB,CAAC,mCAAmC,CAAC,CAC7D,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,qEAAqE,EAAE,GAAG,EAAE;YAC7E,MAAM,MAAM,GAAG,qBAAqB,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;YAC7C,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACrC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,2BAA2B,EAAE,GAAG,EAAE;QACzC,EAAE,CAAC,gEAAgE,EAAE,GAAG,EAAE;YACxE,MAAM,MAAM,GAAG,yBAAyB,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC;YAC1D,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACjC,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;YACpD,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC,4BAA4B,CAAC,CAAC;QACpE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,wEAAwE,EAAE,GAAG,EAAE;YAChF,yFAAyF;YACzF,MAAM,CACJ,yBAAyB,CAAC,GAAG,EAAE,SAAS,EAAE,GAAG,CAAC,CAAC,KAAK,CACrD,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAChB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=contentFilterUtils.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contentFilterUtils.test.d.ts","sourceRoot":"","sources":["../../../src/utils/__tests__/contentFilterUtils.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,443 @@
1
+ /**
2
+ * contentFilterUtils — anti-fee-evasion content moderation.
3
+ *
4
+ * Strategic context: hosts can lose Bash money (and break ToS) by telling
5
+ * attendees "DM me on Venmo to pay" instead of using the platform's payment
6
+ * pipeline. This module is the single source of truth for detecting that
7
+ * pattern across event titles, descriptions, organizer messages, etc.
8
+ *
9
+ * The contract that downstream code (contentValidationApi) relies on:
10
+ *
11
+ * filterContent("clean text") → { isClean: true, violations: [], severity: 'low' }
12
+ * filterContent("text with @venmoUser") → { isClean: false, violations: [...], severity: 'high', cleanedContent: "text with **********" }
13
+ * isContentClean("text with venmo") → false // quick path; matches a smaller pattern set
14
+ * shouldWarnUser(violations, "Basic") → { action: 'reject', message }
15
+ * shouldWarnUser(violations, "Premium") → { action: 'warn', message }
16
+ *
17
+ * Bugs in severity, action mapping, or pattern matching directly affect host
18
+ * trust + platform revenue. Locking these in is high-leverage.
19
+ */
20
+ import { filterContent, isContentClean, filterMultipleFields, getViolationMessage, shouldWarnUser, } from "../contentFilterUtils.js";
21
+ // ============================================================================
22
+ // filterContent — defensive input handling
23
+ // ============================================================================
24
+ describe("filterContent — defensive input handling", () => {
25
+ it("returns clean for empty / null / non-string input without throwing", () => {
26
+ expect(filterContent("")).toEqual({
27
+ isClean: true,
28
+ violations: [],
29
+ severity: "low",
30
+ });
31
+ expect(filterContent(null)).toEqual({
32
+ isClean: true,
33
+ violations: [],
34
+ severity: "low",
35
+ });
36
+ expect(filterContent(undefined)).toEqual({
37
+ isClean: true,
38
+ violations: [],
39
+ severity: "low",
40
+ });
41
+ expect(filterContent(123)).toEqual({
42
+ isClean: true,
43
+ violations: [],
44
+ severity: "low",
45
+ });
46
+ });
47
+ it("does NOT include cleanedContent when the input is clean (downstream relies on this)", () => {
48
+ const result = filterContent("Join us for a great party!");
49
+ expect(result.isClean).toBe(true);
50
+ expect(result.cleanedContent).toBeUndefined();
51
+ });
52
+ it("ALWAYS includes cleanedContent when violations are detected", () => {
53
+ const result = filterContent("Pay me on venmo");
54
+ expect(result.isClean).toBe(false);
55
+ expect(typeof result.cleanedContent).toBe("string");
56
+ expect(result.cleanedContent).not.toBe("Pay me on venmo");
57
+ });
58
+ });
59
+ // ============================================================================
60
+ // filterContent — P2P payment service detection (the core money use case)
61
+ // ============================================================================
62
+ describe("filterContent — direct P2P payment service mentions", () => {
63
+ it.each([
64
+ ["venmo", "Venmo"],
65
+ ["zelle", "Zelle"],
66
+ ["paypal", "PayPal"],
67
+ ["cashapp", "Cash App (one word)"],
68
+ ["cash app", "Cash App (with space)"],
69
+ ])("detects %s (%s)", (mention) => {
70
+ const result = filterContent(`Just ${mention} me later!`);
71
+ expect(result.isClean).toBe(false);
72
+ expect(result.violations.length).toBeGreaterThan(0);
73
+ expect(result.violations.some((v) => v.match.toLowerCase().includes(mention.toLowerCase().includes(" ") ? "cash" : mention.toLowerCase()))).toBe(true);
74
+ });
75
+ it("classifies the literal 'venmo' brand match itself as low severity (the brand-only entry)", () => {
76
+ // Note: the SAME word "venmo" also matches the phonetic /v[e3][n][m][o0]/ pattern,
77
+ // which is recorded separately as a high-severity bypass_attempt. We isolate the
78
+ // brand-only entry here (type === 'p2p_payment').
79
+ const result = filterContent("We accept venmo");
80
+ const brandOnly = result.violations.find((v) => v.type === "p2p_payment" && v.match.toLowerCase() === "venmo");
81
+ expect(brandOnly?.severity).toBe("low");
82
+ });
83
+ it("uses a generic-platform suggestion for paypal", () => {
84
+ const result = filterContent("paypal");
85
+ const paypalViolation = result.violations.find((v) => v.match.toLowerCase().includes("paypal"));
86
+ expect(paypalViolation?.suggestion).toMatch(/Stripe/i);
87
+ });
88
+ });
89
+ // ============================================================================
90
+ // filterContent — leetspeak / dot-separator bypass attempts
91
+ // ============================================================================
92
+ describe("filterContent — bypass attempts (leetspeak, dot-separators)", () => {
93
+ it("catches dot-separated 'v.e.n.m.o'", () => {
94
+ const result = filterContent("Send to v.e.n.m.o please");
95
+ expect(result.isClean).toBe(false);
96
+ expect(result.violations.some((v) => v.match.toLowerCase() === "v.e.n.m.o")).toBe(true);
97
+ });
98
+ it("catches dash-separated 'z-e-l-l-e'", () => {
99
+ const result = filterContent("z-e-l-l-e me $50");
100
+ expect(result.isClean).toBe(false);
101
+ expect(result.violations.some((v) => v.match.toLowerCase() === "z-e-l-l-e")).toBe(true);
102
+ });
103
+ it("catches leetspeak 'v3nm0' as a high-severity bypass attempt (under the phonetic pattern)", () => {
104
+ const result = filterContent("hit me on v3nm0");
105
+ expect(result.isClean).toBe(false);
106
+ // 'v3nm0' matches both the literal P2P pattern (recorded as p2p_payment / low)
107
+ // AND the phonetic pattern (recorded as bypass_attempt / high). We assert the
108
+ // phonetic / high entry exists — that's the one that drives enforcement.
109
+ const phoneticHigh = result.violations.find((v) => v.match === "v3nm0" &&
110
+ v.type === "bypass_attempt" &&
111
+ v.severity === "high");
112
+ expect(phoneticHigh).toBeDefined();
113
+ });
114
+ it("catches leetspeak 'p@yp@l' as a high-severity bypass attempt", () => {
115
+ const result = filterContent("just send via p@yp@l");
116
+ expect(result.violations.some((v) => v.type === "bypass_attempt" && v.severity === "high")).toBe(true);
117
+ });
118
+ });
119
+ // ============================================================================
120
+ // filterContent — high-severity contact info (handles, phones, emails)
121
+ // ============================================================================
122
+ describe("filterContent — high-severity contact info patterns", () => {
123
+ it("flags '@handle' style mentions as high severity (Venmo handle)", () => {
124
+ const result = filterContent("DM @cooluser123");
125
+ const handleMatch = result.violations.find((v) => v.match.startsWith("@"));
126
+ expect(handleMatch).toBeDefined();
127
+ expect(handleMatch?.severity).toBe("high");
128
+ expect(handleMatch?.match).toBe("@cooluser123");
129
+ });
130
+ it("flags '$handle' style mentions as high severity (Cash App)", () => {
131
+ const result = filterContent("send to $rentcollector");
132
+ const handleMatch = result.violations.find((v) => v.match.startsWith("$"));
133
+ expect(handleMatch).toBeDefined();
134
+ expect(handleMatch?.severity).toBe("high");
135
+ });
136
+ it("flags US-style phone numbers (xxx-xxx-xxxx) as high severity", () => {
137
+ const result = filterContent("Reach me at 555-867-5309 to pay");
138
+ const phoneMatch = result.violations.find((v) => v.match === "555-867-5309");
139
+ expect(phoneMatch).toBeDefined();
140
+ expect(phoneMatch?.severity).toBe("high");
141
+ });
142
+ it("flags US-style phone numbers (xxx.xxx.xxxx) as high severity", () => {
143
+ const result = filterContent("Phone: 415.555.0123");
144
+ expect(result.violations.some((v) => v.match === "415.555.0123" && v.severity === "high")).toBe(true);
145
+ });
146
+ it("DOES detect parenthesized US phone numbers, but classifies them as 'low' (known gap in getSeverity)", () => {
147
+ // The pattern /\(\d{3}\)\s*\d{3}[-.]?\d{4}/ matches "(415) 555-0123",
148
+ // but getSeverity's high-severity heuristic uses /\d{3}[-.]?\d{3}[-.]?\d{4}/
149
+ // which doesn't allow ')' between the area code and prefix — so this gets 'low'.
150
+ // This test pins that behavior so a future tightening of getSeverity is intentional.
151
+ const result = filterContent("(415) 555-0123");
152
+ const phoneViolation = result.violations.find((v) => v.match.includes("415"));
153
+ expect(phoneViolation).toBeDefined();
154
+ expect(phoneViolation?.severity).toBe("low");
155
+ });
156
+ it("flags email addresses as high severity (Zelle bypass)", () => {
157
+ const result = filterContent("zelle me at host@example.com to pay");
158
+ const emailMatch = result.violations.find((v) => v.match === "host@example.com");
159
+ expect(emailMatch).toBeDefined();
160
+ expect(emailMatch?.severity).toBe("high");
161
+ });
162
+ it("flags 'paypal.me/foo' as high severity", () => {
163
+ const result = filterContent("paypal.me/host123");
164
+ expect(result.violations.some((v) => v.severity === "high")).toBe(true);
165
+ });
166
+ });
167
+ // ============================================================================
168
+ // filterContent — bypass phrasing (DM me, contact me directly, etc.)
169
+ // ============================================================================
170
+ describe("filterContent — bypass phrasing", () => {
171
+ it.each([
172
+ "dm me for payment",
173
+ "message me to pay",
174
+ "text me for details",
175
+ "contact me directly",
176
+ "pay me directly",
177
+ "send money to john",
178
+ "payment outside platform",
179
+ "skip the fees",
180
+ "avoid fees",
181
+ "no fees if",
182
+ ])("flags '%s' as a violation", (phrase) => {
183
+ const result = filterContent(phrase);
184
+ expect(result.isClean).toBe(false);
185
+ expect(result.violations.length).toBeGreaterThan(0);
186
+ });
187
+ it("classifies 'contact me directly' as MEDIUM severity (intent without explicit handle)", () => {
188
+ const result = filterContent("contact me directly");
189
+ const phraseViolation = result.violations.find((v) => v.match.toLowerCase().includes("contact me"));
190
+ expect(phraseViolation?.severity).toBe("medium");
191
+ });
192
+ it("classifies 'dm me for payment' as MEDIUM severity", () => {
193
+ const result = filterContent("dm me for payment");
194
+ const phraseViolation = result.violations.find((v) => v.match.toLowerCase().includes("dm me"));
195
+ expect(phraseViolation?.severity).toBe("medium");
196
+ });
197
+ });
198
+ // ============================================================================
199
+ // filterContent — overall severity bubbling
200
+ // ============================================================================
201
+ describe("filterContent — overall severity rollup", () => {
202
+ it("returns 'low' overall severity for clean content", () => {
203
+ expect(filterContent("Have a great party").severity).toBe("low");
204
+ });
205
+ it("returns 'high' overall when ANY violation is high", () => {
206
+ // Mix: low (venmo brand) + medium (dm me) + high (@handle)
207
+ const result = filterContent("venmo, dm me directly, @handle");
208
+ expect(result.severity).toBe("high");
209
+ });
210
+ it("returns 'medium' overall when the worst violation is medium", () => {
211
+ const result = filterContent("contact me directly");
212
+ expect(result.severity).toBe("medium");
213
+ });
214
+ it("escalates to 'high' overall when a brand mention also trips the phonetic pattern", () => {
215
+ // 'venmo' is matched by BOTH /venmo/gi (low p2p_payment)
216
+ // AND /v[e3][n][m][o0]/gi (high bypass_attempt) — so the rollup is high.
217
+ // This documents that even a casual "we accept venmo" is treated as high.
218
+ const result = filterContent("we accept venmo");
219
+ expect(result.severity).toBe("high");
220
+ });
221
+ });
222
+ // ============================================================================
223
+ // filterContent — cleanedContent masking
224
+ // ============================================================================
225
+ describe("filterContent — cleanedContent masking", () => {
226
+ it("replaces every matched substring with the same number of asterisks", () => {
227
+ const result = filterContent("Hit me on venmo");
228
+ expect(result.cleanedContent).toBe("Hit me on *****");
229
+ });
230
+ it("masks an @handle by length", () => {
231
+ const result = filterContent("DM @cool to pay");
232
+ // "@cool" is 5 chars
233
+ expect(result.cleanedContent).toBe("DM ***** to pay");
234
+ });
235
+ it("masks multiple violations independently", () => {
236
+ const result = filterContent("@one and @two");
237
+ expect(result.cleanedContent).toBe("**** and ****");
238
+ });
239
+ });
240
+ // ============================================================================
241
+ // isContentClean — fast-path predicate
242
+ // ============================================================================
243
+ describe("isContentClean", () => {
244
+ it("returns true for empty / non-string input", () => {
245
+ expect(isContentClean("")).toBe(true);
246
+ expect(isContentClean(null)).toBe(true);
247
+ expect(isContentClean(undefined)).toBe(true);
248
+ });
249
+ it("returns true for clearly clean content", () => {
250
+ expect(isContentClean("Welcome to our launch party!")).toBe(true);
251
+ });
252
+ it.each([
253
+ "venmo me",
254
+ "send via zelle",
255
+ "@handle me",
256
+ "$cashtag me",
257
+ "paypal.me/host",
258
+ "555-123-4567",
259
+ ])("returns false for '%s'", (input) => {
260
+ expect(isContentClean(input)).toBe(false);
261
+ });
262
+ it("does NOT trip on phone-number-shaped strings inside larger numbers (regex uses word boundary)", () => {
263
+ // 12-digit number like an order ID should not match the 10-digit phone pattern.
264
+ expect(isContentClean("Order 1234567890123")).toBe(true);
265
+ });
266
+ });
267
+ // ============================================================================
268
+ // filterMultipleFields — bulk validation
269
+ // ============================================================================
270
+ describe("filterMultipleFields", () => {
271
+ it("returns isClean=true and overallSeverity='low' when every field is clean", () => {
272
+ const result = filterMultipleFields({
273
+ title: "Birthday Bash",
274
+ description: "Bring a friend",
275
+ organizerNotes: "Doors at 8",
276
+ });
277
+ expect(result.isClean).toBe(true);
278
+ expect(result.overallSeverity).toBe("low");
279
+ expect(Object.keys(result.results)).toEqual([
280
+ "title",
281
+ "description",
282
+ "organizerNotes",
283
+ ]);
284
+ });
285
+ it("flips isClean=false when ANY field is dirty and reports per-field results", () => {
286
+ const result = filterMultipleFields({
287
+ title: "Clean title",
288
+ description: "DM me on @venmoHandle",
289
+ });
290
+ expect(result.isClean).toBe(false);
291
+ expect(result.results.title.isClean).toBe(true);
292
+ expect(result.results.description.isClean).toBe(false);
293
+ });
294
+ it("bubbles the worst severity across fields", () => {
295
+ const result = filterMultipleFields({
296
+ mild: "we accept venmo", // low
297
+ bad: "@cooluser", // high
298
+ });
299
+ expect(result.overallSeverity).toBe("high");
300
+ });
301
+ it("does not downgrade a 'high' finding when later fields are 'low'", () => {
302
+ const result = filterMultipleFields({
303
+ a: "@first", // high
304
+ b: "venmo", // low
305
+ });
306
+ expect(result.overallSeverity).toBe("high");
307
+ });
308
+ });
309
+ // ============================================================================
310
+ // getViolationMessage — user-facing copy
311
+ // ============================================================================
312
+ describe("getViolationMessage", () => {
313
+ it("returns empty string when there are no violations", () => {
314
+ expect(getViolationMessage([])).toBe("");
315
+ });
316
+ it("returns the strict 'violates terms' message when ANY violation is high severity", () => {
317
+ const violations = [
318
+ {
319
+ type: "p2p_payment",
320
+ pattern: "venmo",
321
+ match: "@user",
322
+ position: 0,
323
+ severity: "high",
324
+ },
325
+ {
326
+ type: "bypass_attempt",
327
+ pattern: "low",
328
+ match: "venmo",
329
+ position: 10,
330
+ severity: "low",
331
+ },
332
+ ];
333
+ const msg = getViolationMessage(violations);
334
+ expect(msg).toMatch(/violates our terms/i);
335
+ expect(msg).toMatch(/account suspension/i);
336
+ });
337
+ it("returns the medium-severity caution copy when the worst is medium", () => {
338
+ const violations = [
339
+ {
340
+ type: "p2p_payment",
341
+ pattern: "dm",
342
+ match: "dm me",
343
+ position: 0,
344
+ severity: "medium",
345
+ },
346
+ ];
347
+ expect(getViolationMessage(violations)).toMatch(/may contain payment-related/i);
348
+ });
349
+ it("returns the gentle low-severity copy when there are only low findings", () => {
350
+ const violations = [
351
+ {
352
+ type: "p2p_payment",
353
+ pattern: "venmo",
354
+ match: "venmo",
355
+ position: 0,
356
+ severity: "low",
357
+ },
358
+ ];
359
+ const msg = getViolationMessage(violations);
360
+ expect(msg).toMatch(/avoid mentioning external payment/i);
361
+ expect(msg).not.toMatch(/account suspension/i);
362
+ });
363
+ });
364
+ // ============================================================================
365
+ // shouldWarnUser — tier-aware action mapping (the actual gate)
366
+ // ============================================================================
367
+ describe("shouldWarnUser — tier-aware enforcement", () => {
368
+ it("returns 'allow' with empty message when there are no violations", () => {
369
+ expect(shouldWarnUser([], "Basic")).toEqual({
370
+ action: "allow",
371
+ message: "",
372
+ });
373
+ });
374
+ it("REJECTS Basic users on high-severity violations (the gate)", () => {
375
+ const violations = [
376
+ {
377
+ type: "p2p_payment",
378
+ pattern: "@",
379
+ match: "@host",
380
+ position: 0,
381
+ severity: "high",
382
+ },
383
+ ];
384
+ const r = shouldWarnUser(violations, "Basic");
385
+ expect(r.action).toBe("reject");
386
+ expect(r.message).toMatch(/Upgrade to Creator tier/i);
387
+ });
388
+ it("WARNS (not rejects) Basic users on low / medium violations", () => {
389
+ const violations = [
390
+ {
391
+ type: "p2p_payment",
392
+ pattern: "venmo",
393
+ match: "venmo",
394
+ position: 0,
395
+ severity: "low",
396
+ },
397
+ ];
398
+ const r = shouldWarnUser(violations, "Basic");
399
+ expect(r.action).toBe("warn");
400
+ expect(r.message).toMatch(/avoid mentioning external/i);
401
+ });
402
+ it.each(["Premium", "Pro", "Elite", "Legend"])("%s users get WARN (never REJECT), even on high-severity violations", (tier) => {
403
+ const violations = [
404
+ {
405
+ type: "p2p_payment",
406
+ pattern: "@",
407
+ match: "@host",
408
+ position: 0,
409
+ severity: "high",
410
+ },
411
+ ];
412
+ const r = shouldWarnUser(violations, tier);
413
+ expect(r.action).toBe("warn");
414
+ expect(r.message).toMatch(/Creator\+/i);
415
+ });
416
+ it("Premium users with NO high-severity violations are allowed (no nag)", () => {
417
+ const violations = [
418
+ {
419
+ type: "p2p_payment",
420
+ pattern: "venmo",
421
+ match: "venmo",
422
+ position: 0,
423
+ severity: "low",
424
+ },
425
+ ];
426
+ const r = shouldWarnUser(violations, "Premium");
427
+ expect(r.action).toBe("allow");
428
+ });
429
+ it("treats unknown tiers as Basic (defensive default)", () => {
430
+ const violations = [
431
+ {
432
+ type: "p2p_payment",
433
+ pattern: "@",
434
+ match: "@host",
435
+ position: 0,
436
+ severity: "high",
437
+ },
438
+ ];
439
+ const r = shouldWarnUser(violations, "Guest");
440
+ expect(r.action).toBe("reject");
441
+ });
442
+ });
443
+ //# sourceMappingURL=contentFilterUtils.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contentFilterUtils.test.js","sourceRoot":"","sources":["../../../src/utils/__tests__/contentFilterUtils.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=displayDateUtils.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"displayDateUtils.test.d.ts","sourceRoot":"","sources":["../../../src/utils/__tests__/displayDateUtils.test.ts"],"names":[],"mappings":""}