@bash-app/bash-common 30.214.0 → 30.216.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/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,wCAAwC,CAAC;AACvD,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,4BAA4B,CAAC;AAE3C,sGAAsG;AACtG,qFAAqF;AACrF,oGAAoG;AACpG,mEAAmE;AACnE,kFAAkF;AAClF,OAAO,EACL,MAAM,EACN,kBAAkB,EAClB,kBAAkB,EAClB,QAAQ,EACR,2BAA2B,EAC3B,yBAAyB,EACzB,WAAW,EACX,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,cAAc,EACd,eAAe,EACf,mBAAmB,EACnB,sBAAsB,EACtB,kBAAkB,EAClB,eAAe,EACf,aAAa,EACb,iBAAiB,EACjB,oBAAoB,EACpB,UAAU,EACV,kBAAkB,EAClB,oCAAoC,EACpC,wBAAwB,EACxB,4BAA4B,EAC5B,uBAAuB,EACvB,6BAA6B,EAC7B,qBAAqB,EACrB,qBAAqB,EACrB,2BAA2B,EAC3B,wBAAwB,EACxB,uBAAuB,EACvB,iBAAiB,EACjB,UAAU,EACV,cAAc,EACd,yBAAyB,EACzB,kBAAkB,EAClB,YAAY,EACZ,kBAAkB,EAClB,eAAe,EACf,aAAa,EACb,gBAAgB,EAChB,gBAAgB,EAChB,WAAW,EACX,gBAAgB,EAChB,gBAAgB,EAChB,uBAAuB,EACvB,cAAc,EACd,mBAAmB,EACnB,gBAAgB,EAChB,gBAAgB,EAChB,SAAS,EACT,qBAAqB,EACrB,eAAe,EACf,kBAAkB,EAClB,gBAAgB,EAChB,aAAa,EACb,kBAAkB,EAClB,gBAAgB,EAChB,SAAS,EACT,WAAW,EACX,UAAU,EACV,WAAW,EACX,kBAAkB,EAClB,kBAAkB,EAClB,iCAAiC,EACjC,gBAAgB,EAChB,qBAAqB,EACrB,sBAAsB,EACtB,gBAAgB,EAChB,YAAY,EACZ,sBAAsB,EACtB,mBAAmB,EACnB,eAAe,EACf,sBAAsB,EACtB,MAAM,EACN,gBAAgB,EAChB,iBAAiB,EACjB,qBAAqB,EACrB,aAAa,EACb,iBAAiB,EACjB,eAAe,EACf,uBAAuB,EACvB,kBAAkB,EAClB,gBAAgB,EAChB,sBAAsB,EACtB,cAAc,EACd,cAAc,EACd,aAAa,EACb,mBAAmB,EACnB,cAAc,EACd,kBAAkB,EAClB,UAAU,EACV,YAAY,EACZ,kBAAkB,EAClB,iBAAiB,EACjB,iCAAiC,EACjC,SAAS,EACT,sBAAsB,EACtB,oBAAoB,EACpB,gBAAgB,EAChB,UAAU,EACV,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,YAAY,EACZ,cAAc,EACd,uBAAuB,EACvB,iBAAiB,EACjB,cAAc,EACd,iBAAiB,EACjB,gBAAgB,EAChB,kBAAkB,EAClB,gBAAgB,EAChB,cAAc,EACd,YAAY,EACZ,WAAW,EACX,OAAO,EACP,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EAClB,SAAS,EACT,oBAAoB,EACpB,cAAc,EACd,4BAA4B,EAC5B,kBAAkB,EAClB,kBAAkB,EAClB,gBAAgB,EAChB,sBAAsB,EACtB,YAAY,EACZ,eAAe,EACf,kBAAkB,EAClB,SAAS,EACT,cAAc,EACd,uBAAuB,EACvB,yBAAyB,EACzB,kBAAkB,EAClB,qBAAqB,EACrB,qBAAqB,EACrB,wBAAwB,EACxB,oBAAoB,EACpB,kBAAkB,EAClB,yBAAyB,EACzB,4BAA4B,EAC5B,gBAAgB,EAChB,sBAAsB,EACtB,oBAAoB,EACpB,iBAAiB,EACjB,sBAAsB,EACtB,eAAe,EACf,aAAa,EACb,yBAAyB,EACzB,GAAG,EACH,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,gBAAgB,EAChB,oBAAoB,EACpB,WAAW,EACX,WAAW,EACX,eAAe,EACf,eAAe,EACf,aAAa,EACb,kBAAkB,EAClB,YAAY,EACZ,UAAU,EACV,WAAW,EACX,mBAAmB,EACnB,YAAY,EACZ,qBAAqB,EACrB,qBAAqB,EACrB,UAAU,EACV,QAAQ,EACR,UAAU,EACV,sBAAsB,EACtB,WAAW,EACX,kBAAkB,EAClB,iBAAiB,EACjB,eAAe,EACf,mBAAmB,EACnB,iBAAiB,EACjB,gBAAgB,EAChB,kBAAkB,EAClB,sBAAsB,EACtB,oBAAoB,EACpB,sBAAsB,EACtB,QAAQ,EACR,aAAa,EACb,cAAc,EACd,gBAAgB,GACjB,MAAM,gBAAgB,CAAC;AA4CxB,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC;AACtC,cAAc,mCAAmC,CAAC;AAClD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,0BAA0B,CAAC;AACzC,OAAO,EACL,8BAA8B,EAC9B,mBAAmB,EACnB,8BAA8B,EAC9B,sCAAsC,EACtC,sBAAsB,EACtB,kCAAkC,GACnC,MAAM,8BAA8B,CAAC;AAKtC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,6CAA6C,CAAC;AAC5D,cAAc,gDAAgD,CAAC;AAC/D,cAAc,qBAAqB,CAAC;AACpC,cAAc,yBAAyB,CAAC;AACxC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,wBAAwB,CAAC;AACvC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,wCAAwC,CAAC;AACvD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,iCAAiC,CAAC;AAChD,cAAc,qDAAqD,CAAC;AACpE,+DAA+D;AAC/D,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,qBAAqB,CAAC;AACpC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,kCAAkC,CAAC;AACjD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,iCAAiC,CAAC;AAChD,cAAc,uBAAuB,CAAC;AACtC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,sBAAsB,CAAC;AACrC,cAAc,sCAAsC,CAAC;AACrD,cAAc,8CAA8C,CAAC;AAC7D,cAAc,gDAAgD,CAAC;AAC/D,cAAc,8CAA8C,CAAC;AAC7D,cAAc,mCAAmC,CAAC;AAClD,cAAc,qCAAqC,CAAC;AACpD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,sBAAsB,CAAC;AACrC,cAAc,+BAA+B,CAAC;AAE9C,iFAAiF;AACjF,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAM3D,kBAAkB;AAClB,cAAc,+BAA+B,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Default copy for host opt-in photo/video consent at event checkout.
3
+ * When `BashEvent.photoReleaseText` is null and `photoReleaseEnabled` is true, use this text.
4
+ * Not legal advice; hosts may supply custom text via the wizard.
5
+ */
6
+ export declare const DEFAULT_PHOTO_RELEASE_TEXT = "By attending this event, you understand that photography, audio recording, and video recording may occur. You consent to being photographed, filmed, and/or recorded, and you grant the event organizer and its licensees the right to use your name, image, likeness, and voice in any media (including for promotion of this and future events), without payment or other compensation, unless prohibited by law.\n\nIf you do not wish to appear in promotional materials, contact the event organizer before or during the event. For minors, a parent or guardian must agree to this consent.";
7
+ /**
8
+ * Effective photo release text for display (wizard preview, event page, checkout).
9
+ */
10
+ export declare function getPhotoReleaseDisplayText(photoReleaseText: string | null | undefined): string;
11
+ //# sourceMappingURL=legalTemplates.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"legalTemplates.d.ts","sourceRoot":"","sources":["../src/legalTemplates.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,eAAO,MAAM,0BAA0B,ukBAEqI,CAAC;AAE7K;;GAEG;AACH,wBAAgB,0BAA0B,CACxC,gBAAgB,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAC1C,MAAM,CAMR"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Default copy for host opt-in photo/video consent at event checkout.
3
+ * When `BashEvent.photoReleaseText` is null and `photoReleaseEnabled` is true, use this text.
4
+ * Not legal advice; hosts may supply custom text via the wizard.
5
+ */
6
+ export const DEFAULT_PHOTO_RELEASE_TEXT = `By attending this event, you understand that photography, audio recording, and video recording may occur. You consent to being photographed, filmed, and/or recorded, and you grant the event organizer and its licensees the right to use your name, image, likeness, and voice in any media (including for promotion of this and future events), without payment or other compensation, unless prohibited by law.
7
+
8
+ If you do not wish to appear in promotional materials, contact the event organizer before or during the event. For minors, a parent or guardian must agree to this consent.`;
9
+ /**
10
+ * Effective photo release text for display (wizard preview, event page, checkout).
11
+ */
12
+ export function getPhotoReleaseDisplayText(photoReleaseText) {
13
+ const trimmed = photoReleaseText?.trim();
14
+ if (trimmed) {
15
+ return trimmed;
16
+ }
17
+ return DEFAULT_PHOTO_RELEASE_TEXT;
18
+ }
19
+ //# sourceMappingURL=legalTemplates.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"legalTemplates.js","sourceRoot":"","sources":["../src/legalTemplates.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG;;4KAEkI,CAAC;AAE7K;;GAEG;AACH,MAAM,UAAU,0BAA0B,CACxC,gBAA2C;IAE3C,MAAM,OAAO,GAAG,gBAAgB,EAAE,IAAI,EAAE,CAAC;IACzC,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,OAAO,CAAC;IACjB,CAAC;IACD,OAAO,0BAA0B,CAAC;AACpC,CAAC"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * UTM / marketing attribution: first-touch capture in sessionStorage, Stripe metadata keys,
3
+ * and persistence on Ticket rows.
4
+ */
5
+ export interface UtmFields {
6
+ utmSource?: string;
7
+ utmMedium?: string;
8
+ utmCampaign?: string;
9
+ }
10
+ /** Normalize optional UTM strings from API args (Stripe checkout / payment intent body). */
11
+ export declare function utmFieldsFromCheckoutArgs(args: UtmFields): UtmFields | undefined;
12
+ /** Stripe Checkout / PaymentIntent metadata (snake_case keys). */
13
+ export declare function utmFieldsToStripeMetadata(utm: UtmFields | undefined): Record<string, string>;
14
+ /** Prisma `Ticket` columns for persisted UTM (omit empty). */
15
+ export declare function utmFieldsToTicketColumns(utm: UtmFields): {
16
+ utmSource?: string;
17
+ utmMedium?: string;
18
+ utmCampaign?: string;
19
+ };
20
+ /** Read UTM from Stripe object metadata into Prisma Ticket field names. */
21
+ export declare function utmFieldsFromStripeMetadata(md: Record<string, string | undefined> | null | undefined): UtmFields;
22
+ /**
23
+ * First-touch per session: store each UTM component the first time it appears in the URL.
24
+ * Call on route changes so client-side navigations to ?utm_*= still capture.
25
+ */
26
+ export declare function captureFirstTouchUtmFromUrlSearchParams(search: string): void;
27
+ /** Values previously captured for this tab session (for checkout API bodies). */
28
+ export declare function getStoredUtmFields(): UtmFields;
29
+ //# sourceMappingURL=utmAttribution.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utmAttribution.d.ts","sourceRoot":"","sources":["../src/utmAttribution.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,SAAS;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAQD,4FAA4F;AAC5F,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,CAkBhF;AAED,kEAAkE;AAClE,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,SAAS,GAAG,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAe5F;AAED,8DAA8D;AAC9D,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,SAAS,GAAG;IACxD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAYA;AAED,2EAA2E;AAC3E,wBAAgB,2BAA2B,CACzC,EAAE,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG,IAAI,GAAG,SAAS,GACxD,SAAS,CAkBX;AAED;;;GAGG;AACH,wBAAgB,uCAAuC,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAkB5E;AAED,iFAAiF;AACjF,wBAAgB,kBAAkB,IAAI,SAAS,CAkB9C"}
@@ -0,0 +1,124 @@
1
+ /**
2
+ * UTM / marketing attribution: first-touch capture in sessionStorage, Stripe metadata keys,
3
+ * and persistence on Ticket rows.
4
+ */
5
+ const SESSION_KEYS = {
6
+ utmSource: "bash_utm_source",
7
+ utmMedium: "bash_utm_medium",
8
+ utmCampaign: "bash_utm_campaign",
9
+ };
10
+ /** Normalize optional UTM strings from API args (Stripe checkout / payment intent body). */
11
+ export function utmFieldsFromCheckoutArgs(args) {
12
+ const s = args.utmSource?.trim();
13
+ const m = args.utmMedium?.trim();
14
+ const c = args.utmCampaign?.trim();
15
+ if (!s && !m && !c) {
16
+ return undefined;
17
+ }
18
+ const out = {};
19
+ if (s) {
20
+ out.utmSource = s.slice(0, 500);
21
+ }
22
+ if (m) {
23
+ out.utmMedium = m.slice(0, 500);
24
+ }
25
+ if (c) {
26
+ out.utmCampaign = c.slice(0, 500);
27
+ }
28
+ return out;
29
+ }
30
+ /** Stripe Checkout / PaymentIntent metadata (snake_case keys). */
31
+ export function utmFieldsToStripeMetadata(utm) {
32
+ if (!utm) {
33
+ return {};
34
+ }
35
+ const out = {};
36
+ if (utm.utmSource) {
37
+ out.utm_source = utm.utmSource;
38
+ }
39
+ if (utm.utmMedium) {
40
+ out.utm_medium = utm.utmMedium;
41
+ }
42
+ if (utm.utmCampaign) {
43
+ out.utm_campaign = utm.utmCampaign;
44
+ }
45
+ return out;
46
+ }
47
+ /** Prisma `Ticket` columns for persisted UTM (omit empty). */
48
+ export function utmFieldsToTicketColumns(utm) {
49
+ const out = {};
50
+ if (utm.utmSource) {
51
+ out.utmSource = utm.utmSource;
52
+ }
53
+ if (utm.utmMedium) {
54
+ out.utmMedium = utm.utmMedium;
55
+ }
56
+ if (utm.utmCampaign) {
57
+ out.utmCampaign = utm.utmCampaign;
58
+ }
59
+ return out;
60
+ }
61
+ /** Read UTM from Stripe object metadata into Prisma Ticket field names. */
62
+ export function utmFieldsFromStripeMetadata(md) {
63
+ if (!md) {
64
+ return {};
65
+ }
66
+ const s = md.utm_source?.trim();
67
+ const m = md.utm_medium?.trim();
68
+ const c = md.utm_campaign?.trim();
69
+ const out = {};
70
+ if (s) {
71
+ out.utmSource = s.slice(0, 500);
72
+ }
73
+ if (m) {
74
+ out.utmMedium = m.slice(0, 500);
75
+ }
76
+ if (c) {
77
+ out.utmCampaign = c.slice(0, 500);
78
+ }
79
+ return out;
80
+ }
81
+ /**
82
+ * First-touch per session: store each UTM component the first time it appears in the URL.
83
+ * Call on route changes so client-side navigations to ?utm_*= still capture.
84
+ */
85
+ export function captureFirstTouchUtmFromUrlSearchParams(search) {
86
+ if (typeof window === "undefined" || typeof sessionStorage === "undefined") {
87
+ return;
88
+ }
89
+ const q = search.startsWith("?") ? search.slice(1) : search;
90
+ const params = new URLSearchParams(q);
91
+ const pairs = [
92
+ ["utmSource", "utm_source"],
93
+ ["utmMedium", "utm_medium"],
94
+ ["utmCampaign", "utm_campaign"],
95
+ ];
96
+ for (const [storageField, paramName] of pairs) {
97
+ const v = params.get(paramName)?.trim();
98
+ const key = SESSION_KEYS[storageField];
99
+ if (v && !sessionStorage.getItem(key)) {
100
+ sessionStorage.setItem(key, v.slice(0, 500));
101
+ }
102
+ }
103
+ }
104
+ /** Values previously captured for this tab session (for checkout API bodies). */
105
+ export function getStoredUtmFields() {
106
+ if (typeof sessionStorage === "undefined") {
107
+ return {};
108
+ }
109
+ const s = sessionStorage.getItem(SESSION_KEYS.utmSource)?.trim();
110
+ const m = sessionStorage.getItem(SESSION_KEYS.utmMedium)?.trim();
111
+ const c = sessionStorage.getItem(SESSION_KEYS.utmCampaign)?.trim();
112
+ const out = {};
113
+ if (s) {
114
+ out.utmSource = s;
115
+ }
116
+ if (m) {
117
+ out.utmMedium = m;
118
+ }
119
+ if (c) {
120
+ out.utmCampaign = c;
121
+ }
122
+ return out;
123
+ }
124
+ //# sourceMappingURL=utmAttribution.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utmAttribution.js","sourceRoot":"","sources":["../src/utmAttribution.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bash-app/bash-common",
3
- "version": "30.214.0",
3
+ "version": "30.216.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",
@@ -615,6 +615,10 @@ model BashEvent {
615
615
  waiverUrl String?
616
616
  waiverRequired Boolean @default(false)
617
617
  waiverDisplayType String? @default("inline")
618
+ /// Host opt-in: show photo/video consent at checkout; null photoReleaseText = platform default template
619
+ photoReleaseEnabled Boolean @default(false)
620
+ photoReleaseRequired Boolean @default(true)
621
+ photoReleaseText String? @db.Text
618
622
  targetAudienceId String? @unique
619
623
  amountOfGuestsId String? @unique
620
624
  vibe String?
@@ -793,6 +797,7 @@ model BashEvent {
793
797
  // Per-event referral rewards
794
798
  eventReferralRewards EventReferralReward[]
795
799
  eventReferrals EventReferral[]
800
+ bashEventDonations BashEventDonation[]
796
801
 
797
802
  // User night itineraries (events in user's "My Night" plan)
798
803
  userItineraryItems UserItineraryItem[]
@@ -1316,6 +1321,8 @@ model Ticket {
1316
1321
  waitlistJoinedAt DateTime?
1317
1322
  waitlistNotifiedAt DateTime?
1318
1323
  waitlistExpiresAt DateTime?
1324
+ /** Set when we send the "your waitlist window expires soon" reminder (once per ticket). */
1325
+ waitlistReminderSentAt DateTime?
1319
1326
  refundRequestedAt DateTime? // Set when RefundPending; cleared once refund processes
1320
1327
  checkInLocation String?
1321
1328
  checkOutLocation String?
@@ -1325,12 +1332,19 @@ model Ticket {
1325
1332
  lastValidationAttempt DateTime?
1326
1333
  lastValidatedBy String?
1327
1334
  waitlistUserId String?
1335
+ /// Rotated when ticket is transferred; QR payload must match for check-in (null = legacy tickets, no strict check).
1336
+ qrToken String?
1328
1337
 
1329
1338
  // BashPoints Purchase Tracking
1330
1339
  purchaseType String? // "USD", "BashPoints", "Free", "Comp"
1331
1340
  pointsPaid Int? // BashPoints amount paid (if purchaseType="BashPoints")
1332
1341
  stripePurchaseId String? // Stripe payment ID (if purchaseType="USD")
1333
1342
 
1343
+ // Marketing attribution (from landing URL → sessionStorage → Stripe metadata → ticket row)
1344
+ utmSource String?
1345
+ utmMedium String?
1346
+ utmCampaign String?
1347
+
1334
1348
  bashEvent BashEvent @relation(fields: [bashEventId], references: [id])
1335
1349
  checkout Checkout? @relation(fields: [checkoutId], references: [id])
1336
1350
  forUser User? @relation("TicketsISent", fields: [forUserId], references: [id])
@@ -1340,6 +1354,7 @@ model Ticket {
1340
1354
  waitlistUser User? @relation("TicketsOnWaitlist", fields: [waitlistUserId], references: [id])
1341
1355
  metadata TicketMetadata[]
1342
1356
  transfers TicketTransfer[]
1357
+ transferInvite TicketTransferInvite?
1343
1358
  appliedDiscounts AppliedDiscount[] // NEW - Discounts applied to this ticket
1344
1359
  eventReferral EventReferral? // When this ticket was purchased via a referral link
1345
1360
 
@@ -1361,6 +1376,33 @@ model TicketTransfer {
1361
1376
  @@index([ticketId])
1362
1377
  }
1363
1378
 
1379
+ enum TicketTransferInviteStatus {
1380
+ PENDING
1381
+ ACCEPTED
1382
+ DECLINED
1383
+ EXPIRED
1384
+ }
1385
+
1386
+ /// Pending peer-to-peer transfer; completes into `TicketTransfer` on accept.
1387
+ model TicketTransferInvite {
1388
+ id String @id @default(cuid())
1389
+ ticketId String @unique
1390
+ fromUserId String
1391
+ toEmail String?
1392
+ toUserId String?
1393
+ token String @unique
1394
+ status TicketTransferInviteStatus @default(PENDING)
1395
+ expiresAt DateTime
1396
+ createdAt DateTime @default(now())
1397
+
1398
+ ticket Ticket @relation(fields: [ticketId], references: [id], onDelete: Cascade)
1399
+ fromUser User @relation("TicketTransferInviteFrom", fields: [fromUserId], references: [id])
1400
+ invitedUser User? @relation("TicketTransferInviteToUser", fields: [toUserId], references: [id])
1401
+
1402
+ @@index([token])
1403
+ @@index([fromUserId])
1404
+ }
1405
+
1364
1406
  model TicketMetadata {
1365
1407
  id String @id @default(cuid())
1366
1408
  ticketId String
@@ -1373,6 +1415,27 @@ model TicketMetadata {
1373
1415
  @@index([ticketId])
1374
1416
  }
1375
1417
 
1418
+ /// Stripe donation to an event (Checkout session or PaymentIntent); includes optional UTM attribution.
1419
+ model BashEventDonation {
1420
+ id String @id @default(cuid())
1421
+ bashEventId String
1422
+ donorId String?
1423
+ donorEmail String?
1424
+ amountCents Int
1425
+ stripeCheckoutSessionId String? @unique
1426
+ stripePaymentIntentId String? @unique
1427
+ utmSource String?
1428
+ utmMedium String?
1429
+ utmCampaign String?
1430
+ createdAt DateTime @default(now())
1431
+
1432
+ bashEvent BashEvent @relation(fields: [bashEventId], references: [id], onDelete: Cascade)
1433
+ donor User? @relation(fields: [donorId], references: [id], onDelete: Cascade)
1434
+
1435
+ @@index([bashEventId])
1436
+ @@index([donorId])
1437
+ }
1438
+
1376
1439
  model unusedModelButNeededForSomeTypesToBeDefinedForTypescript {
1377
1440
  id String @id @default(cuid())
1378
1441
  doNotUseVibeEnum BashEventVibeTags @default(Wild)
@@ -1607,6 +1670,9 @@ model Review {
1607
1670
  bashEventId String
1608
1671
  createdAt DateTime @default(now())
1609
1672
  updatedAt DateTime @updatedAt
1673
+ /// Public reply from the event host (service provider) to the reviewer.
1674
+ hostReplyText String? @db.Text
1675
+ hostReplyAt DateTime?
1610
1676
  comments BashComment[]
1611
1677
  bashEvent BashEvent @relation(fields: [bashEventId], references: [id], onDelete: Cascade)
1612
1678
  creator User @relation(fields: [creatorId], references: [id], onDelete: Cascade)
@@ -1724,6 +1790,8 @@ model User {
1724
1790
  birthdayReminderEnabled Boolean @default(false)
1725
1791
  birthdayReminderDaysAdvance Int @default(7)
1726
1792
  birthdayCategories String[] @default([]) // e.g. restaurant, coffee, dessert
1793
+ /// Calendar year when we last sent the "your birthday month freebies" reminder (cron on 1st of month).
1794
+ birthdayMonthReminderSentYear Int?
1727
1795
  idDocumentUrl String? // Optional: secure ID upload for verification
1728
1796
  gender Gender?
1729
1797
  sex Sex?
@@ -1905,9 +1973,12 @@ model User {
1905
1973
  stripeAccounts StripeAccount[]
1906
1974
  ticketsISent Ticket[] @relation("TicketsISent")
1907
1975
  ticketsIOwn Ticket[] @relation("TicketsIOwn")
1976
+ bashEventDonations BashEventDonation[]
1908
1977
  ticketsOnWaitlist Ticket[] @relation("TicketsOnWaitlist")
1909
1978
  transfersFrom TicketTransfer[] @relation("TransfersFrom")
1910
1979
  transfersTo TicketTransfer[] @relation("TransfersTo")
1980
+ ticketTransferInvitesFrom TicketTransferInvite[] @relation("TicketTransferInviteFrom")
1981
+ ticketTransferInvitesToUser TicketTransferInvite[] @relation("TicketTransferInviteToUser")
1911
1982
  unblocksReceived UnblockedUserHistory[] @relation("UserUnblocksReceived")
1912
1983
  unblocksCreated UnblockedUserHistory[] @relation("UserUnblocksMade")
1913
1984
  suspendedBy User? @relation("SuspendedUsers", fields: [suspendedById], references: [id])
@@ -4075,6 +4146,7 @@ enum NotificationType {
4075
4146
  HostSalesAccelerating // Host: "Your event sales increased 38% today"
4076
4147
  HostTopPromoter // Host: "Top promoter: Alex (6 tickets today)"
4077
4148
  HostSalesSlowing // Host: "Sales slowed today. Try sharing your event."
4149
+ TicketSold // Host: a ticket was purchased for your event (debounced in webhook)
4078
4150
  }
4079
4151
 
4080
4152
  enum NotificationPriority {
@@ -21,6 +21,7 @@ import { ApiServiceCantBookReason } from "./utils/service/apiServiceBookingApiUt
21
21
  import { ServiceAttendeeOption } from "./utils/service/attendeeOptionUtils.js";
22
22
  import { FrontendServiceGetPriceToBookResult } from "./utils/service/frontendServiceBookingUtils.js";
23
23
  import { ServiceSubscriptionTier } from "./utils/userSubscriptionUtils.js";
24
+ import type { UtmFields } from "./utmAttribution.js";
24
25
 
25
26
  export const PASSWORD_MIN_LENGTH = 8 as const;
26
27
  export const PASSWORD_REQUIREMENTS_REGEX = new RegExp(
@@ -259,6 +260,9 @@ export const SERVICE_BOOKING_DETAILS_SERVICE_VIEW_URL_PAGE =
259
260
  "/service/${serviceId}/${serviceType}/${specificId}/booking/${bookingId}/serviceView" as const;
260
261
 
261
262
  export const VERIFICATION_RETURN_URL = `/sign-up` as const;
263
+
264
+ /** Stripe Identity hosted flow returns here (see `createStripeVerificationSession`). */
265
+ export const STRIPE_IDENTITY_RETURN_URL = `/verify-id` as const;
262
266
  export const MY_SERVICES_URL = "/my-services" as const;
263
267
  export const BASH_DETAIL_URL = `/bash` as const;
264
268
  export const BASH_DETAIL_URL_PATTERN = `/bash/$bashEventIdSlug` as const;
@@ -684,7 +688,7 @@ export interface StripePaymentMethod {
684
688
  };
685
689
  }
686
690
 
687
- export interface StripeCreateBashEventTicketsCheckoutSessionArgs {
691
+ export interface StripeCreateBashEventTicketsCheckoutSessionArgs extends UtmFields {
688
692
  bashEventId: string;
689
693
  currency: string;
690
694
  paymentMethodType: string;
@@ -705,11 +709,15 @@ export interface StripeCreateBashEventTicketsCheckoutSessionArgs {
705
709
  attributionRef?: string;
706
710
  }
707
711
 
708
- export interface StripeCreateBashEventDonationCheckoutSessionArgs {
712
+ export interface StripeCreateBashEventDonationCheckoutSessionArgs extends UtmFields {
709
713
  bashEventId: string;
710
714
  currency: string;
711
715
  paymentMethodType: string;
712
716
  donationAmount: number;
717
+ /** Required for guest (unauthenticated) donation checkout — Stripe collects payment; we persist receipt to this email. */
718
+ guestEmail?: string;
719
+ guestFirstName?: string;
720
+ guestLastName?: string;
713
721
  }
714
722
 
715
723
  export interface StripeCreateSetupPaymentMethodSessionArgs {
@@ -146,6 +146,8 @@ export const FRONT_END_USER_DATA_TO_SELECT = {
146
146
  sex: true,
147
147
  documentIDId: true,
148
148
  // documentID: true,
149
+ /** Set when Stripe Identity verification completes (hosted flow). */
150
+ idVerified: true,
149
151
  reviews: true,
150
152
  contacts: true,
151
153
  accepted: true,
package/src/index.ts CHANGED
@@ -1,4 +1,6 @@
1
1
  export * from "./definitions.js";
2
+ export * from "./legalTemplates.js";
3
+ export * from "./utmAttribution.js";
2
4
  export * from "./stripeListingSubscriptionMessages.js";
3
5
  export * from "./extendedSchemas.js";
4
6
  export * from "./bashFeedTypes.js";
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Default copy for host opt-in photo/video consent at event checkout.
3
+ * When `BashEvent.photoReleaseText` is null and `photoReleaseEnabled` is true, use this text.
4
+ * Not legal advice; hosts may supply custom text via the wizard.
5
+ */
6
+ export const DEFAULT_PHOTO_RELEASE_TEXT = `By attending this event, you understand that photography, audio recording, and video recording may occur. You consent to being photographed, filmed, and/or recorded, and you grant the event organizer and its licensees the right to use your name, image, likeness, and voice in any media (including for promotion of this and future events), without payment or other compensation, unless prohibited by law.
7
+
8
+ If you do not wish to appear in promotional materials, contact the event organizer before or during the event. For minors, a parent or guardian must agree to this consent.`;
9
+
10
+ /**
11
+ * Effective photo release text for display (wizard preview, event page, checkout).
12
+ */
13
+ export function getPhotoReleaseDisplayText(
14
+ photoReleaseText: string | null | undefined
15
+ ): string {
16
+ const trimmed = photoReleaseText?.trim();
17
+ if (trimmed) {
18
+ return trimmed;
19
+ }
20
+ return DEFAULT_PHOTO_RELEASE_TEXT;
21
+ }
@@ -0,0 +1,142 @@
1
+ /**
2
+ * UTM / marketing attribution: first-touch capture in sessionStorage, Stripe metadata keys,
3
+ * and persistence on Ticket rows.
4
+ */
5
+
6
+ export interface UtmFields {
7
+ utmSource?: string;
8
+ utmMedium?: string;
9
+ utmCampaign?: string;
10
+ }
11
+
12
+ const SESSION_KEYS = {
13
+ utmSource: "bash_utm_source",
14
+ utmMedium: "bash_utm_medium",
15
+ utmCampaign: "bash_utm_campaign",
16
+ } as const;
17
+
18
+ /** Normalize optional UTM strings from API args (Stripe checkout / payment intent body). */
19
+ export function utmFieldsFromCheckoutArgs(args: UtmFields): UtmFields | undefined {
20
+ const s = args.utmSource?.trim();
21
+ const m = args.utmMedium?.trim();
22
+ const c = args.utmCampaign?.trim();
23
+ if (!s && !m && !c) {
24
+ return undefined;
25
+ }
26
+ const out: UtmFields = {};
27
+ if (s) {
28
+ out.utmSource = s.slice(0, 500);
29
+ }
30
+ if (m) {
31
+ out.utmMedium = m.slice(0, 500);
32
+ }
33
+ if (c) {
34
+ out.utmCampaign = c.slice(0, 500);
35
+ }
36
+ return out;
37
+ }
38
+
39
+ /** Stripe Checkout / PaymentIntent metadata (snake_case keys). */
40
+ export function utmFieldsToStripeMetadata(utm: UtmFields | undefined): Record<string, string> {
41
+ if (!utm) {
42
+ return {};
43
+ }
44
+ const out: Record<string, string> = {};
45
+ if (utm.utmSource) {
46
+ out.utm_source = utm.utmSource;
47
+ }
48
+ if (utm.utmMedium) {
49
+ out.utm_medium = utm.utmMedium;
50
+ }
51
+ if (utm.utmCampaign) {
52
+ out.utm_campaign = utm.utmCampaign;
53
+ }
54
+ return out;
55
+ }
56
+
57
+ /** Prisma `Ticket` columns for persisted UTM (omit empty). */
58
+ export function utmFieldsToTicketColumns(utm: UtmFields): {
59
+ utmSource?: string;
60
+ utmMedium?: string;
61
+ utmCampaign?: string;
62
+ } {
63
+ const out: { utmSource?: string; utmMedium?: string; utmCampaign?: string } = {};
64
+ if (utm.utmSource) {
65
+ out.utmSource = utm.utmSource;
66
+ }
67
+ if (utm.utmMedium) {
68
+ out.utmMedium = utm.utmMedium;
69
+ }
70
+ if (utm.utmCampaign) {
71
+ out.utmCampaign = utm.utmCampaign;
72
+ }
73
+ return out;
74
+ }
75
+
76
+ /** Read UTM from Stripe object metadata into Prisma Ticket field names. */
77
+ export function utmFieldsFromStripeMetadata(
78
+ md: Record<string, string | undefined> | null | undefined
79
+ ): UtmFields {
80
+ if (!md) {
81
+ return {};
82
+ }
83
+ const s = md.utm_source?.trim();
84
+ const m = md.utm_medium?.trim();
85
+ const c = md.utm_campaign?.trim();
86
+ const out: UtmFields = {};
87
+ if (s) {
88
+ out.utmSource = s.slice(0, 500);
89
+ }
90
+ if (m) {
91
+ out.utmMedium = m.slice(0, 500);
92
+ }
93
+ if (c) {
94
+ out.utmCampaign = c.slice(0, 500);
95
+ }
96
+ return out;
97
+ }
98
+
99
+ /**
100
+ * First-touch per session: store each UTM component the first time it appears in the URL.
101
+ * Call on route changes so client-side navigations to ?utm_*= still capture.
102
+ */
103
+ export function captureFirstTouchUtmFromUrlSearchParams(search: string): void {
104
+ if (typeof window === "undefined" || typeof sessionStorage === "undefined") {
105
+ return;
106
+ }
107
+ const q = search.startsWith("?") ? search.slice(1) : search;
108
+ const params = new URLSearchParams(q);
109
+ const pairs: Array<[keyof typeof SESSION_KEYS, string]> = [
110
+ ["utmSource", "utm_source"],
111
+ ["utmMedium", "utm_medium"],
112
+ ["utmCampaign", "utm_campaign"],
113
+ ];
114
+ for (const [storageField, paramName] of pairs) {
115
+ const v = params.get(paramName)?.trim();
116
+ const key = SESSION_KEYS[storageField];
117
+ if (v && !sessionStorage.getItem(key)) {
118
+ sessionStorage.setItem(key, v.slice(0, 500));
119
+ }
120
+ }
121
+ }
122
+
123
+ /** Values previously captured for this tab session (for checkout API bodies). */
124
+ export function getStoredUtmFields(): UtmFields {
125
+ if (typeof sessionStorage === "undefined") {
126
+ return {};
127
+ }
128
+ const s = sessionStorage.getItem(SESSION_KEYS.utmSource)?.trim();
129
+ const m = sessionStorage.getItem(SESSION_KEYS.utmMedium)?.trim();
130
+ const c = sessionStorage.getItem(SESSION_KEYS.utmCampaign)?.trim();
131
+ const out: UtmFields = {};
132
+ if (s) {
133
+ out.utmSource = s;
134
+ }
135
+ if (m) {
136
+ out.utmMedium = m;
137
+ }
138
+ if (c) {
139
+ out.utmCampaign = c;
140
+ }
141
+ return out;
142
+ }