@bash-app/bash-common 30.383.0 → 30.385.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__/accessScreening.test.js +39 -1
- package/dist/__tests__/accessScreening.test.js.map +1 -1
- package/dist/__tests__/applicationFunnel.test.d.ts +2 -0
- package/dist/__tests__/applicationFunnel.test.d.ts.map +1 -0
- package/dist/__tests__/applicationFunnel.test.js +126 -0
- package/dist/__tests__/applicationFunnel.test.js.map +1 -0
- package/dist/__tests__/definitionsHelpers.test.js +20 -1
- package/dist/__tests__/definitionsHelpers.test.js.map +1 -1
- package/dist/__tests__/fundingMeter.test.d.ts +2 -0
- package/dist/__tests__/fundingMeter.test.d.ts.map +1 -0
- package/dist/__tests__/fundingMeter.test.js +129 -0
- package/dist/__tests__/fundingMeter.test.js.map +1 -0
- package/dist/__tests__/giveaway.test.d.ts +2 -0
- package/dist/__tests__/giveaway.test.d.ts.map +1 -0
- package/dist/__tests__/giveaway.test.js +65 -0
- package/dist/__tests__/giveaway.test.js.map +1 -0
- package/dist/__tests__/promoterCompetitionUtils.test.d.ts +2 -0
- package/dist/__tests__/promoterCompetitionUtils.test.d.ts.map +1 -0
- package/dist/__tests__/promoterCompetitionUtils.test.js +262 -0
- package/dist/__tests__/promoterCompetitionUtils.test.js.map +1 -0
- package/dist/accessScreening.d.ts +18 -3
- package/dist/accessScreening.d.ts.map +1 -1
- package/dist/accessScreening.js +26 -0
- package/dist/accessScreening.js.map +1 -1
- package/dist/applicationFunnel.d.ts +58 -0
- package/dist/applicationFunnel.d.ts.map +1 -0
- package/dist/applicationFunnel.js +147 -0
- package/dist/applicationFunnel.js.map +1 -0
- package/dist/definitions.d.ts +145 -5
- package/dist/definitions.d.ts.map +1 -1
- package/dist/definitions.js +137 -5
- package/dist/definitions.js.map +1 -1
- package/dist/extendedSchemas.d.ts +159 -0
- package/dist/extendedSchemas.d.ts.map +1 -1
- package/dist/extendedSchemas.js +6 -0
- package/dist/extendedSchemas.js.map +1 -1
- package/dist/fundingMeter.d.ts +66 -0
- package/dist/fundingMeter.d.ts.map +1 -0
- package/dist/fundingMeter.js +99 -0
- package/dist/fundingMeter.js.map +1 -0
- package/dist/giveaway.d.ts +71 -0
- package/dist/giveaway.d.ts.map +1 -0
- package/dist/giveaway.js +117 -0
- package/dist/giveaway.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/utils/__tests__/bashHostIdentity.test.d.ts +2 -0
- package/dist/utils/__tests__/bashHostIdentity.test.d.ts.map +1 -0
- package/dist/utils/__tests__/bashHostIdentity.test.js +39 -0
- package/dist/utils/__tests__/bashHostIdentity.test.js.map +1 -0
- package/dist/utils/__tests__/promoterCompetitionUtils.test.d.ts +2 -0
- package/dist/utils/__tests__/promoterCompetitionUtils.test.d.ts.map +1 -0
- package/dist/utils/__tests__/promoterCompetitionUtils.test.js +104 -0
- package/dist/utils/__tests__/promoterCompetitionUtils.test.js.map +1 -0
- package/dist/utils/__tests__/slugUtils.test.js +29 -2
- package/dist/utils/__tests__/slugUtils.test.js.map +1 -1
- package/dist/utils/bashHostIdentity.d.ts +18 -0
- package/dist/utils/bashHostIdentity.d.ts.map +1 -0
- package/dist/utils/bashHostIdentity.js +17 -0
- package/dist/utils/bashHostIdentity.js.map +1 -0
- package/dist/utils/promoterCompetitionUtils.d.ts +89 -0
- package/dist/utils/promoterCompetitionUtils.d.ts.map +1 -0
- package/dist/utils/promoterCompetitionUtils.js +158 -0
- package/dist/utils/promoterCompetitionUtils.js.map +1 -0
- package/dist/utils/slugUtils.d.ts +2 -0
- package/dist/utils/slugUtils.d.ts.map +1 -1
- package/dist/utils/slugUtils.js +5 -1
- package/dist/utils/slugUtils.js.map +1 -1
- package/package.json +1 -1
- package/prisma/schema.prisma +415 -25
- package/src/__tests__/accessScreening.test.ts +69 -1
- package/src/__tests__/applicationFunnel.test.ts +197 -0
- package/src/__tests__/definitionsHelpers.test.ts +24 -0
- package/src/__tests__/fundingMeter.test.ts +143 -0
- package/src/__tests__/giveaway.test.ts +111 -0
- package/src/__tests__/promoterCompetitionUtils.test.ts +334 -0
- package/src/accessScreening.ts +49 -0
- package/src/applicationFunnel.ts +225 -0
- package/src/definitions.ts +181 -5
- package/src/extendedSchemas.ts +116 -0
- package/src/fundingMeter.ts +188 -0
- package/src/giveaway.ts +182 -0
- package/src/index.ts +14 -0
- package/src/utils/__tests__/bashHostIdentity.test.ts +57 -0
- package/src/utils/__tests__/promoterCompetitionUtils.test.ts +128 -0
- package/src/utils/__tests__/slugUtils.test.ts +44 -0
- package/src/utils/bashHostIdentity.ts +30 -0
- package/src/utils/promoterCompetitionUtils.ts +235 -0
- package/src/utils/slugUtils.ts +11 -0
package/prisma/schema.prisma
CHANGED
|
@@ -268,6 +268,19 @@ model Competition {
|
|
|
268
268
|
/// How 1st/2nd/3rd place icons appear on leaderboards and profiles
|
|
269
269
|
placementAwardStyle PlacementAwardStyle @default(Trophy)
|
|
270
270
|
|
|
271
|
+
/// PROMOTER competitions only — purpose distinguishes consumer contests from ticket-sales races
|
|
272
|
+
competitionPurpose CompetitionPurpose @default(CONSUMER)
|
|
273
|
+
/// PROMOTER: total ticket-sale goal for the competition
|
|
274
|
+
promoterSalesGoal Int?
|
|
275
|
+
/// PROMOTER: maximum organizer cash reward exposure in cents
|
|
276
|
+
promoterRewardBudgetCents Int?
|
|
277
|
+
/// PROMOTER: how milestone rewards are calculated
|
|
278
|
+
promoterRewardMode PromoterRewardMode @default(TOTAL_AT_MILESTONE)
|
|
279
|
+
/// PROMOTER: who can enroll as a promoter
|
|
280
|
+
promoterRecruitMode PromoterRecruitMode @default(InviteOnly)
|
|
281
|
+
/// PROMOTER: attribution window in days (purchases within N days of referral click count)
|
|
282
|
+
referralWindowDays Int? @default(30)
|
|
283
|
+
|
|
271
284
|
/// Optional Adventures rewards when someone becomes an ACCEPTED participant
|
|
272
285
|
participationBashPoints Int?
|
|
273
286
|
participationEventBadgeId String?
|
|
@@ -292,6 +305,11 @@ model Competition {
|
|
|
292
305
|
judgeScores CompetitionJudgeScore[]
|
|
293
306
|
notifications Notification[]
|
|
294
307
|
sideQuests SideQuest[]
|
|
308
|
+
giveaways Giveaway[]
|
|
309
|
+
promoterMilestones PromoterMilestone[]
|
|
310
|
+
promoterRewards PromoterReward[]
|
|
311
|
+
promoters Promoter[]
|
|
312
|
+
promoterEventPerformances PromoterEventPerformance[]
|
|
295
313
|
participationEventBadge EventBadge? @relation("CompetitionParticipationBadge", fields: [participationEventBadgeId], references: [id], onDelete: SetNull)
|
|
296
314
|
finalistEventBadge EventBadge? @relation("CompetitionFinalistBadge", fields: [finalistEventBadgeId], references: [id], onDelete: SetNull)
|
|
297
315
|
winEventBadge EventBadge? @relation("CompetitionWinBadge", fields: [winEventBadgeId], references: [id], onDelete: SetNull)
|
|
@@ -305,6 +323,67 @@ model Competition {
|
|
|
305
323
|
@@index([winEventBadgeId])
|
|
306
324
|
}
|
|
307
325
|
|
|
326
|
+
/// Threshold-based reward step in a PROMOTER competition.
|
|
327
|
+
/// Each row defines what a promoter earns when they hit `threshold` qualified ticket sales,
|
|
328
|
+
/// or `rank` (e.g. rank=1 for first-place prize).
|
|
329
|
+
model PromoterMilestone {
|
|
330
|
+
id String @id @default(cuid())
|
|
331
|
+
competitionId String
|
|
332
|
+
/// null = rank-based prize (use `rank`); non-null = threshold-based
|
|
333
|
+
threshold Int?
|
|
334
|
+
/// null = threshold-based (use `threshold`); 1 = first-place prize, etc.
|
|
335
|
+
rank Int?
|
|
336
|
+
rewardType PromoterRewardType
|
|
337
|
+
/// Cash reward in cents (used when rewardType = CASH)
|
|
338
|
+
rewardAmountCents Int?
|
|
339
|
+
/// Human-readable label shown to promoters (e.g. "Free VIP upgrade")
|
|
340
|
+
rewardDescription String?
|
|
341
|
+
/// Ticket tier to award (for TICKET / TICKET_UPGRADE rewards)
|
|
342
|
+
ticketTierId String?
|
|
343
|
+
/// Linked sponsor prize (for SPONSOR_PRIZE rewards)
|
|
344
|
+
sponsorPrizeId String?
|
|
345
|
+
/// Controls display order in UIs
|
|
346
|
+
displayOrder Int @default(0)
|
|
347
|
+
createdAt DateTime @default(now())
|
|
348
|
+
updatedAt DateTime @updatedAt
|
|
349
|
+
|
|
350
|
+
competition Competition @relation(fields: [competitionId], references: [id], onDelete: Cascade)
|
|
351
|
+
rewards PromoterReward[]
|
|
352
|
+
|
|
353
|
+
@@index([competitionId])
|
|
354
|
+
@@index([threshold])
|
|
355
|
+
@@index([rank])
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
/// Tracks a specific reward earned (or pending/revoked) by a promoter participant.
|
|
359
|
+
/// Created when a promoter's qualified sales cross a milestone threshold or they win a rank prize.
|
|
360
|
+
model PromoterReward {
|
|
361
|
+
id String @id @default(cuid())
|
|
362
|
+
competitionId String
|
|
363
|
+
/// FK to Promoter.id (the per-bash promoter row, not User)
|
|
364
|
+
promoterId String
|
|
365
|
+
/// null for rank-based rewards (use `rank`)
|
|
366
|
+
milestoneId String?
|
|
367
|
+
/// For rank prizes (1 = first place, etc.)
|
|
368
|
+
rank Int?
|
|
369
|
+
/// Snapshot of qualified sales at the time this reward status was last updated
|
|
370
|
+
qualifiedSalesSnapshot Int @default(0)
|
|
371
|
+
status PromoterRewardStatus @default(PENDING)
|
|
372
|
+
earnedAt DateTime?
|
|
373
|
+
fulfilledAt DateTime?
|
|
374
|
+
revokedAt DateTime?
|
|
375
|
+
revokeReason String?
|
|
376
|
+
createdAt DateTime @default(now())
|
|
377
|
+
updatedAt DateTime @updatedAt
|
|
378
|
+
|
|
379
|
+
competition Competition @relation(fields: [competitionId], references: [id], onDelete: Cascade)
|
|
380
|
+
milestone PromoterMilestone? @relation(fields: [milestoneId], references: [id], onDelete: SetNull)
|
|
381
|
+
|
|
382
|
+
@@index([competitionId, promoterId])
|
|
383
|
+
@@index([promoterId])
|
|
384
|
+
@@index([status])
|
|
385
|
+
}
|
|
386
|
+
|
|
308
387
|
model CompetitionJudgeAssignment {
|
|
309
388
|
id String @id @default(cuid())
|
|
310
389
|
competitionId String
|
|
@@ -611,10 +690,16 @@ model Promoter {
|
|
|
611
690
|
updatedAt DateTime @updatedAt
|
|
612
691
|
userId String? // null until invited promoter signs up (do not use host id as placeholder)
|
|
613
692
|
invitedEmail String? // normalized invitee email for reconciliation when userId is null
|
|
693
|
+
/// When set, this promoter is enrolled in a specific PROMOTER competition
|
|
694
|
+
competitionId String?
|
|
695
|
+
/// Cached count of qualified ticket sales for the linked competition (updated async after checkout/refund)
|
|
696
|
+
qualifiedSales Int @default(0)
|
|
614
697
|
promoCodes BashEventPromoCode[]
|
|
615
698
|
promoterUser User? @relation(fields: [userId], references: [id])
|
|
699
|
+
competition Competition? @relation(fields: [competitionId], references: [id], onDelete: SetNull)
|
|
616
700
|
|
|
617
701
|
@@unique([promoterId, promotedForBash])
|
|
702
|
+
@@index([competitionId])
|
|
618
703
|
}
|
|
619
704
|
|
|
620
705
|
model PromoterStats {
|
|
@@ -632,11 +717,85 @@ model PromoterStats {
|
|
|
632
717
|
pendingCredits Int @default(0)
|
|
633
718
|
availableCredits Int @default(0)
|
|
634
719
|
promoterInvitations Int @default(0)
|
|
720
|
+
// Cross-competition lifetime aggregates (added in promoter network layer migration)
|
|
721
|
+
totalCompetitionsJoined Int @default(0)
|
|
722
|
+
totalCompetitionsWithSale Int @default(0)
|
|
723
|
+
totalMilestonesReached Int @default(0)
|
|
724
|
+
totalCompetitionsWon Int @default(0) // rank=1 achieved
|
|
725
|
+
totalEventsPromoted Int @default(0)
|
|
726
|
+
repeatOrganizerCount Int @default(0) // distinct organizers worked with 2+ times
|
|
727
|
+
lifetimeQualifiedTickets Int @default(0)
|
|
728
|
+
lifetimeRevenueCents Int @default(0)
|
|
635
729
|
createdAt DateTime @default(now())
|
|
636
730
|
updatedAt DateTime @updatedAt
|
|
637
731
|
user User @relation(fields: [userId], references: [id])
|
|
638
732
|
}
|
|
639
733
|
|
|
734
|
+
/// Persisted per-promoter per-event performance record.
|
|
735
|
+
/// Created when a promoter joins a PROMOTER competition; updated async after each qualified sale/refund.
|
|
736
|
+
/// Survives competition end and event archival.
|
|
737
|
+
model PromoterEventPerformance {
|
|
738
|
+
id String @id @default(cuid())
|
|
739
|
+
promoterUserId String
|
|
740
|
+
bashEventId String
|
|
741
|
+
competitionId String
|
|
742
|
+
|
|
743
|
+
clicks Int @default(0)
|
|
744
|
+
checkoutStarts Int @default(0)
|
|
745
|
+
qualifiedOrders Int @default(0)
|
|
746
|
+
qualifiedTickets Int @default(0)
|
|
747
|
+
revenueGeneratedCents Int @default(0)
|
|
748
|
+
|
|
749
|
+
highestMilestoneThreshold Int?
|
|
750
|
+
finalRank Int?
|
|
751
|
+
|
|
752
|
+
eventCategory String?
|
|
753
|
+
eventCity String?
|
|
754
|
+
eventRegion String?
|
|
755
|
+
|
|
756
|
+
joinedAt DateTime @default(now())
|
|
757
|
+
lastSaleAt DateTime?
|
|
758
|
+
completedAt DateTime?
|
|
759
|
+
createdAt DateTime @default(now())
|
|
760
|
+
updatedAt DateTime @updatedAt
|
|
761
|
+
|
|
762
|
+
promoterUser User @relation("PromoterEventPerformances", fields: [promoterUserId], references: [id], onDelete: Cascade)
|
|
763
|
+
bashEvent BashEvent @relation(fields: [bashEventId], references: [id], onDelete: Cascade)
|
|
764
|
+
competition Competition @relation(fields: [competitionId], references: [id], onDelete: Cascade)
|
|
765
|
+
|
|
766
|
+
@@unique([promoterUserId, competitionId])
|
|
767
|
+
@@index([promoterUserId])
|
|
768
|
+
@@index([bashEventId])
|
|
769
|
+
@@index([eventCategory, promoterUserId])
|
|
770
|
+
@@index([eventCity, promoterUserId])
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
/// Cross-event relationship between a host (organizer) and a promoter.
|
|
774
|
+
/// Updated each time they work together. Enables "Invite Previous Promoters" and relationship depth metrics.
|
|
775
|
+
model OrganizerPromoterRelationship {
|
|
776
|
+
id String @id @default(cuid())
|
|
777
|
+
organizerUserId String
|
|
778
|
+
promoterUserId String
|
|
779
|
+
|
|
780
|
+
timesInvited Int @default(1)
|
|
781
|
+
timesJoined Int @default(0)
|
|
782
|
+
eventsWithSale Int @default(0)
|
|
783
|
+
totalTicketsGenerated Int @default(0)
|
|
784
|
+
totalRevenueGeneratedCents Int @default(0)
|
|
785
|
+
lastWorkedTogetherAt DateTime?
|
|
786
|
+
lastInvitedAt DateTime @default(now())
|
|
787
|
+
|
|
788
|
+
createdAt DateTime @default(now())
|
|
789
|
+
updatedAt DateTime @updatedAt
|
|
790
|
+
|
|
791
|
+
organizer User @relation("OrganizerPromoterRelationshipsAsOrganizer", fields: [organizerUserId], references: [id], onDelete: Cascade)
|
|
792
|
+
promoter User @relation("OrganizerPromoterRelationshipsAsPromoter", fields: [promoterUserId], references: [id], onDelete: Cascade)
|
|
793
|
+
|
|
794
|
+
@@unique([organizerUserId, promoterUserId])
|
|
795
|
+
@@index([organizerUserId])
|
|
796
|
+
@@index([promoterUserId])
|
|
797
|
+
}
|
|
798
|
+
|
|
640
799
|
model PromoterClick {
|
|
641
800
|
id String @id @default(cuid())
|
|
642
801
|
promoterId String
|
|
@@ -936,6 +1095,12 @@ model BashEvent {
|
|
|
936
1095
|
/// When true, only accounts with a published service profile (Vendor/Venue/Entertainment/Exhibitor/Sponsor/Event
|
|
937
1096
|
/// Service) can view budget lines revealed via `Budget.showOnBashDetailPage`. Default off = anyone can click to view.
|
|
938
1097
|
budgetRestrictedToServiceProviders Boolean @default(false)
|
|
1098
|
+
/// Public funding meter: value coming in toward included budget lines (not host spend).
|
|
1099
|
+
showFundingMeter Boolean @default(false)
|
|
1100
|
+
/// When false, public can Pay now only — Commit / pledge POST is rejected.
|
|
1101
|
+
fundingAllowCommitments Boolean @default(true)
|
|
1102
|
+
/// When true, open pledges fill the lighter meter segment. Default off: bar is collected only.
|
|
1103
|
+
fundingShowPledgesOnMeter Boolean @default(false)
|
|
939
1104
|
/// When true on Rsvp-mode events, affirmative RSVPs land in a host approval queue first.
|
|
940
1105
|
rsvpRequiresApproval Boolean @default(false)
|
|
941
1106
|
/// Hide when guests RSVP'd on host-facing attendee views.
|
|
@@ -943,6 +1108,8 @@ model BashEvent {
|
|
|
943
1108
|
/// Only allow inviting people who share a mutual bash with the host.
|
|
944
1109
|
invitesLimitedToMutuals Boolean @default(false)
|
|
945
1110
|
showOrganizerTitles Boolean @default(false)
|
|
1111
|
+
/// When false, public/guest surfaces hide host identity (cards + Meet the host).
|
|
1112
|
+
showHostOnBashPage Boolean @default(true)
|
|
946
1113
|
/// When true, low-stock scarcity badges show "X% left" instead of "Only N left".
|
|
947
1114
|
showPercentRemaining Boolean @default(false)
|
|
948
1115
|
servicePreferences Json? // New tiered status: { "Entertainment": "need", "Sponsors": "booked_closed", ... }
|
|
@@ -1002,6 +1169,14 @@ model BashEvent {
|
|
|
1002
1169
|
guestsCanInviteOthers Boolean @default(false)
|
|
1003
1170
|
/// Private-event screening: route access requests to a host approval queue
|
|
1004
1171
|
accessScreeningEnabled Boolean @default(false)
|
|
1172
|
+
/// Optional host application (markup + questions) before RSVP or ticket checkout.
|
|
1173
|
+
applicationEnabled Boolean @default(false)
|
|
1174
|
+
/// Rich-text intro shown at the top of the guest application.
|
|
1175
|
+
applicationIntroHtml String? @db.Text
|
|
1176
|
+
/// After this time, guests cannot submit a new application. Hosts can still review.
|
|
1177
|
+
applicationClosesAt DateTime?
|
|
1178
|
+
/// When true, auto-approve applicants this host has approved on a prior bash.
|
|
1179
|
+
autoApproveRegulars Boolean @default(false)
|
|
1005
1180
|
/// Collaborative post-event photo/video album contributions
|
|
1006
1181
|
albumEnabled Boolean @default(false)
|
|
1007
1182
|
/// When true, attendee uploads require host approval before appearing in the public album.
|
|
@@ -1038,6 +1213,10 @@ model BashEvent {
|
|
|
1038
1213
|
organizationId String?
|
|
1039
1214
|
organization Organization? @relation("OrganizationBashEvents", fields: [organizationId], references: [id])
|
|
1040
1215
|
|
|
1216
|
+
/// Host-as-service identity. XOR with organizationId (enforced in upsert + DB check).
|
|
1217
|
+
hostedByServiceId String?
|
|
1218
|
+
hostedByService Service? @relation("BashEventHostedByService", fields: [hostedByServiceId], references: [id], onDelete: SetNull)
|
|
1219
|
+
|
|
1041
1220
|
// Organization access controls (only apply when organizationId is set)
|
|
1042
1221
|
requiresOrgMembership Boolean @default(false) // Must be member to attend/RSVP
|
|
1043
1222
|
allowMemberGuests Boolean @default(false) // Members can bring +1s
|
|
@@ -1149,7 +1328,10 @@ model BashEvent {
|
|
|
1149
1328
|
eventReferralRewards EventReferralReward[]
|
|
1150
1329
|
eventReferrals EventReferral[]
|
|
1151
1330
|
discussionComments EventDiscussionComment[]
|
|
1152
|
-
bashEventDonations
|
|
1331
|
+
bashEventDonations BashEventDonation[]
|
|
1332
|
+
budgetContributions BudgetContribution[]
|
|
1333
|
+
giveaways Giveaway[]
|
|
1334
|
+
promoterEventPerformances PromoterEventPerformance[]
|
|
1153
1335
|
|
|
1154
1336
|
// Adventures / Side Quests
|
|
1155
1337
|
sideQuests SideQuest[]
|
|
@@ -1215,6 +1397,7 @@ model BashEvent {
|
|
|
1215
1397
|
@@index([templateId])
|
|
1216
1398
|
@@index([parentEventId])
|
|
1217
1399
|
@@index([organizationId])
|
|
1400
|
+
@@index([hostedByServiceId])
|
|
1218
1401
|
@@index([eventSeriesId])
|
|
1219
1402
|
@@index([status, aiApprovalVerdict])
|
|
1220
1403
|
}
|
|
@@ -2025,11 +2208,16 @@ model PublicBashRsvp {
|
|
|
2025
2208
|
plusOneNames String[] @default([])
|
|
2026
2209
|
/// Set when the guest keeps or declines after a postponement; cleared on each new Postpone.
|
|
2027
2210
|
postponeRespondedAt DateTime?
|
|
2211
|
+
/// Optional guest photo submitted with an RSVP application.
|
|
2212
|
+
applicationPhotoUrl String?
|
|
2213
|
+
/// Optional host sentence included when an RSVP application is denied.
|
|
2214
|
+
hostNote String?
|
|
2028
2215
|
createdAt DateTime @default(now())
|
|
2029
2216
|
updatedAt DateTime @updatedAt
|
|
2030
2217
|
|
|
2031
|
-
bashEvent
|
|
2032
|
-
user
|
|
2218
|
+
bashEvent BashEvent @relation(fields: [bashEventId], references: [id], onDelete: Cascade)
|
|
2219
|
+
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
2220
|
+
applicationAnswers BashEventQuestionAnswer[]
|
|
2033
2221
|
|
|
2034
2222
|
@@unique([bashEventId, userId])
|
|
2035
2223
|
@@index([bashEventId])
|
|
@@ -2190,6 +2378,7 @@ model SideQuest {
|
|
|
2190
2378
|
eventBadge EventBadge? @relation(fields: [eventBadgeId], references: [id], onDelete: SetNull)
|
|
2191
2379
|
competition Competition? @relation(fields: [competitionId], references: [id], onDelete: SetNull)
|
|
2192
2380
|
completions SideQuestCompletion[]
|
|
2381
|
+
giveaways Giveaway[]
|
|
2193
2382
|
milestonesUnlocking SideQuestMilestone[] @relation("MilestoneUnlocksQuest")
|
|
2194
2383
|
checkpoints SideQuestCheckpoint[]
|
|
2195
2384
|
progressHits SideQuestProgressHit[]
|
|
@@ -2464,34 +2653,57 @@ enum BashEventQuestionType {
|
|
|
2464
2653
|
YesNo
|
|
2465
2654
|
}
|
|
2466
2655
|
|
|
2467
|
-
///
|
|
2656
|
+
/// What happens when a choice answer is not in acceptableOptions.
|
|
2657
|
+
enum QuestionMismatchAction {
|
|
2658
|
+
None
|
|
2659
|
+
FlagForReview
|
|
2660
|
+
AutoDeny
|
|
2661
|
+
}
|
|
2662
|
+
|
|
2663
|
+
/// Host-defined custom RSVP / checkout / application question for a bash.
|
|
2468
2664
|
model BashEventCustomQuestion {
|
|
2469
|
-
id
|
|
2470
|
-
bashEventId
|
|
2471
|
-
prompt
|
|
2472
|
-
type
|
|
2473
|
-
options
|
|
2474
|
-
required
|
|
2475
|
-
sortOrder
|
|
2476
|
-
|
|
2477
|
-
|
|
2665
|
+
id String @id @default(cuid())
|
|
2666
|
+
bashEventId String
|
|
2667
|
+
prompt String
|
|
2668
|
+
type BashEventQuestionType @default(ShortText)
|
|
2669
|
+
options String[] @default([])
|
|
2670
|
+
required Boolean @default(false)
|
|
2671
|
+
sortOrder Int @default(0)
|
|
2672
|
+
/// null = every applying surface (all application tiers + RSVP).
|
|
2673
|
+
ticketTierId String?
|
|
2674
|
+
mismatchAction QuestionMismatchAction @default(None)
|
|
2675
|
+
acceptableOptions String[] @default([])
|
|
2676
|
+
/// When set, only show this question if the parent answer matches showWhenAnswer.
|
|
2677
|
+
parentQuestionId String?
|
|
2678
|
+
showWhenAnswer String?
|
|
2679
|
+
createdAt DateTime @default(now())
|
|
2680
|
+
updatedAt DateTime @updatedAt
|
|
2478
2681
|
|
|
2479
2682
|
@@index([bashEventId])
|
|
2683
|
+
@@index([ticketTierId])
|
|
2684
|
+
@@index([parentQuestionId])
|
|
2480
2685
|
}
|
|
2481
2686
|
|
|
2482
|
-
/// An attendee's answer to a custom question (captured at RSVP / checkout).
|
|
2687
|
+
/// An attendee's answer to a custom question (captured at RSVP / checkout / application).
|
|
2483
2688
|
model BashEventQuestionAnswer {
|
|
2484
|
-
id
|
|
2485
|
-
questionId
|
|
2486
|
-
bashEventId
|
|
2487
|
-
userId
|
|
2488
|
-
email
|
|
2489
|
-
ticketId
|
|
2490
|
-
|
|
2491
|
-
|
|
2689
|
+
id String @id @default(cuid())
|
|
2690
|
+
questionId String
|
|
2691
|
+
bashEventId String
|
|
2692
|
+
userId String?
|
|
2693
|
+
email String?
|
|
2694
|
+
ticketId String?
|
|
2695
|
+
accessRequestId String?
|
|
2696
|
+
publicRsvpId String?
|
|
2697
|
+
answer String
|
|
2698
|
+
createdAt DateTime @default(now())
|
|
2699
|
+
|
|
2700
|
+
accessRequest BashEventAccessRequest? @relation(fields: [accessRequestId], references: [id], onDelete: SetNull)
|
|
2701
|
+
publicRsvp PublicBashRsvp? @relation(fields: [publicRsvpId], references: [id], onDelete: SetNull)
|
|
2492
2702
|
|
|
2493
2703
|
@@index([questionId])
|
|
2494
2704
|
@@index([bashEventId])
|
|
2705
|
+
@@index([accessRequestId])
|
|
2706
|
+
@@index([publicRsvpId])
|
|
2495
2707
|
}
|
|
2496
2708
|
|
|
2497
2709
|
enum BashEventAccessRequestStatus {
|
|
@@ -2510,10 +2722,17 @@ model BashEventAccessRequest {
|
|
|
2510
2722
|
status BashEventAccessRequestStatus @default(Pending)
|
|
2511
2723
|
reviewedByUserId String?
|
|
2512
2724
|
reviewedAt DateTime?
|
|
2513
|
-
|
|
2514
|
-
|
|
2725
|
+
/// Optional host sentence included when the request is denied.
|
|
2726
|
+
hostNote String?
|
|
2727
|
+
ticketTierId String?
|
|
2728
|
+
applicationPhotoUrl String?
|
|
2729
|
+
createdAt DateTime @default(now())
|
|
2730
|
+
updatedAt DateTime @updatedAt
|
|
2731
|
+
|
|
2732
|
+
answers BashEventQuestionAnswer[]
|
|
2515
2733
|
|
|
2516
2734
|
@@index([bashEventId, status])
|
|
2735
|
+
@@index([ticketTierId])
|
|
2517
2736
|
}
|
|
2518
2737
|
|
|
2519
2738
|
/// A collaborative album contribution (photo/video URL) for a bash.
|
|
@@ -3324,6 +3543,8 @@ model TicketTier {
|
|
|
3324
3543
|
|
|
3325
3544
|
/// Host opt-in: buyers of this tier may choose mailed or venue will-call physical delivery (see TicketPrintOrder).
|
|
3326
3545
|
allowsPhysicalDelivery Boolean @default(false)
|
|
3546
|
+
/// Guests must complete the event application and be approved before buying this tier.
|
|
3547
|
+
requiresApplication Boolean @default(false)
|
|
3327
3548
|
|
|
3328
3549
|
@@unique([bashEventId, title])
|
|
3329
3550
|
@@index([availableAt])
|
|
@@ -3474,6 +3695,7 @@ model Ticket {
|
|
|
3474
3695
|
flyerConversions FlyerConversion[]
|
|
3475
3696
|
coatCheckEntitlements CoatCheckEntitlement[]
|
|
3476
3697
|
printOrder TicketPrintOrder?
|
|
3698
|
+
giveawayRedemptions GiveawayRedemption[]
|
|
3477
3699
|
|
|
3478
3700
|
@@index([bashEventId])
|
|
3479
3701
|
@@index([bashEventId, seatId])
|
|
@@ -4451,6 +4673,7 @@ model User {
|
|
|
4451
4673
|
eventFeaturedGuestSpots EventFeaturedGuest[] @relation("FeaturedGuestOnEvent")
|
|
4452
4674
|
eventAttendeeVisibilities EventAttendeeVisibility[] @relation("AttendeeVisibilityOnEvent")
|
|
4453
4675
|
bashEventDonations BashEventDonation[]
|
|
4676
|
+
budgetContributions BudgetContribution[]
|
|
4454
4677
|
bashCreativeSubmissions BashCreativeSubmission[]
|
|
4455
4678
|
ticketsOnWaitlist Ticket[] @relation("TicketsOnWaitlist")
|
|
4456
4679
|
transfersFrom TicketTransfer[] @relation("TransfersFrom")
|
|
@@ -4557,6 +4780,9 @@ model User {
|
|
|
4557
4780
|
coatCheckEntitlementsOwned CoatCheckEntitlement[] @relation("CoatCheckOwner")
|
|
4558
4781
|
coatCheckEntitlementsCheckedIn CoatCheckEntitlement[] @relation("CoatCheckCheckedInBy")
|
|
4559
4782
|
coatCheckEntitlementsClaimed CoatCheckEntitlement[] @relation("CoatCheckClaimedBy")
|
|
4783
|
+
giveawayRedemptions GiveawayRedemption[] @relation("GiveawayRedemptionUser")
|
|
4784
|
+
giveawayRedemptionsReceived GiveawayRedemption[] @relation("GiveawayReceivedBy")
|
|
4785
|
+
giveawayRedemptionsVoided GiveawayRedemption[] @relation("GiveawayVoidedBy")
|
|
4560
4786
|
bashBusWaitlistSignup BashBusWaitlistSignup?
|
|
4561
4787
|
collectibleRedemptions CollectibleRedemption[]
|
|
4562
4788
|
bashFeedSaves BashFeedSave[]
|
|
@@ -4636,6 +4862,11 @@ model User {
|
|
|
4636
4862
|
|
|
4637
4863
|
phoneVerificationCodes PhoneVerificationCode[]
|
|
4638
4864
|
smsSendLogs SmsSendLog[]
|
|
4865
|
+
|
|
4866
|
+
// Promoter Network Layer relations
|
|
4867
|
+
promoterEventPerformances PromoterEventPerformance[] @relation("PromoterEventPerformances")
|
|
4868
|
+
organizerPromoterRelationshipsAsOrganizer OrganizerPromoterRelationship[] @relation("OrganizerPromoterRelationshipsAsOrganizer")
|
|
4869
|
+
organizerPromoterRelationshipsAsPromoter OrganizerPromoterRelationship[] @relation("OrganizerPromoterRelationshipsAsPromoter")
|
|
4639
4870
|
}
|
|
4640
4871
|
|
|
4641
4872
|
model PhoneVerificationCode {
|
|
@@ -5285,6 +5516,7 @@ model Service {
|
|
|
5285
5516
|
serviceCategoryRequests ServiceCategoryRequest[] // Services created from approved category requests
|
|
5286
5517
|
associatedBashesReferencingMe AssociatedBash[] @relation("AssociatedBashToService")
|
|
5287
5518
|
bashEvent BashEvent[] @relation("BashEventToService")
|
|
5519
|
+
hostedBashEvents BashEvent[] @relation("BashEventHostedByService")
|
|
5288
5520
|
media Media[] @relation("MediaToService")
|
|
5289
5521
|
analytics ServiceAnalytics[] // Track service analytics
|
|
5290
5522
|
scoutReferrals ScoutReferral[] @relation("ScoutServiceProfile")
|
|
@@ -5308,6 +5540,7 @@ model Service {
|
|
|
5308
5540
|
serviceReviews ServiceReview[]
|
|
5309
5541
|
providerHostReviews ProviderHostReview[]
|
|
5310
5542
|
sideQuestCheckpoints SideQuestCheckpoint[]
|
|
5543
|
+
giveaways Giveaway[]
|
|
5311
5544
|
serviceRankings ServiceRankings?
|
|
5312
5545
|
|
|
5313
5546
|
@@index([serviceListingStripeSubscriptionId])
|
|
@@ -6993,6 +7226,8 @@ model Budget {
|
|
|
6993
7226
|
remainingCents Int? // Can be computed: totalAllocatedCents - spentCents
|
|
6994
7227
|
/// Host opt-in: reveal this line's category + amount to providers on the public bash detail page.
|
|
6995
7228
|
showOnBashDetailPage Boolean @default(false)
|
|
7229
|
+
/// When true (default), this line's allocation is part of the public funding goal.
|
|
7230
|
+
includeOnFundingMeter Boolean @default(true)
|
|
6996
7231
|
|
|
6997
7232
|
// Categorization
|
|
6998
7233
|
category String? // "Marketing", "Catering", "Venue", "Annual", "Activities"
|
|
@@ -7022,7 +7257,8 @@ model Budget {
|
|
|
7022
7257
|
service Service? @relation("ServiceBudgets", fields: [serviceId], references: [id], onDelete: Cascade)
|
|
7023
7258
|
submitter User? @relation("BudgetSubmitter", fields: [submittedBy], references: [id])
|
|
7024
7259
|
approver User? @relation("BudgetApprover", fields: [approverId], references: [id])
|
|
7025
|
-
expenses
|
|
7260
|
+
expenses Expense[]
|
|
7261
|
+
contributions BudgetContribution[]
|
|
7026
7262
|
|
|
7027
7263
|
@@index([organizationId])
|
|
7028
7264
|
@@index([bashEventId])
|
|
@@ -7034,6 +7270,116 @@ model Budget {
|
|
|
7034
7270
|
@@index([fiscalYear])
|
|
7035
7271
|
}
|
|
7036
7272
|
|
|
7273
|
+
enum BudgetContributionKind {
|
|
7274
|
+
Cash
|
|
7275
|
+
InKind
|
|
7276
|
+
}
|
|
7277
|
+
|
|
7278
|
+
enum BudgetContributionStatus {
|
|
7279
|
+
Pledged
|
|
7280
|
+
Paid
|
|
7281
|
+
Fulfilled
|
|
7282
|
+
Declined
|
|
7283
|
+
Cancelled
|
|
7284
|
+
}
|
|
7285
|
+
|
|
7286
|
+
enum BudgetContributionSource {
|
|
7287
|
+
Stripe
|
|
7288
|
+
HostEntered
|
|
7289
|
+
PublicPledge
|
|
7290
|
+
}
|
|
7291
|
+
|
|
7292
|
+
/// Value coming in toward a bash budget line (host-entered, public pledge, or Stripe).
|
|
7293
|
+
/// `budgetId` is required on create for HostEntered / PublicPledge / Stripe; null is unallocated only.
|
|
7294
|
+
model BudgetContribution {
|
|
7295
|
+
id String @id @default(cuid())
|
|
7296
|
+
bashEventId String
|
|
7297
|
+
budgetId String?
|
|
7298
|
+
contributorUserId String?
|
|
7299
|
+
displayName String
|
|
7300
|
+
kind BudgetContributionKind
|
|
7301
|
+
status BudgetContributionStatus
|
|
7302
|
+
source BudgetContributionSource
|
|
7303
|
+
amountCents Int
|
|
7304
|
+
note String?
|
|
7305
|
+
stripeCheckoutSessionId String? @unique
|
|
7306
|
+
stripePaymentIntentId String? @unique
|
|
7307
|
+
createdAt DateTime @default(now())
|
|
7308
|
+
updatedAt DateTime @updatedAt
|
|
7309
|
+
|
|
7310
|
+
bashEvent BashEvent @relation(fields: [bashEventId], references: [id], onDelete: Cascade)
|
|
7311
|
+
budget Budget? @relation(fields: [budgetId], references: [id], onDelete: SetNull)
|
|
7312
|
+
contributor User? @relation(fields: [contributorUserId], references: [id], onDelete: SetNull)
|
|
7313
|
+
|
|
7314
|
+
@@index([bashEventId])
|
|
7315
|
+
@@index([budgetId])
|
|
7316
|
+
@@index([contributorUserId])
|
|
7317
|
+
@@index([status])
|
|
7318
|
+
}
|
|
7319
|
+
|
|
7320
|
+
enum GiveawayEligibility {
|
|
7321
|
+
AnyoneGoing
|
|
7322
|
+
TicketHolders
|
|
7323
|
+
CheckedIn
|
|
7324
|
+
CompetitionParticipants
|
|
7325
|
+
SideQuestCompleters
|
|
7326
|
+
}
|
|
7327
|
+
|
|
7328
|
+
/// Host/sponsor swag handed out at the bash. Not merch (for sale) and not a competition prize.
|
|
7329
|
+
model Giveaway {
|
|
7330
|
+
id String @id @default(cuid())
|
|
7331
|
+
bashEventId String
|
|
7332
|
+
name String
|
|
7333
|
+
description String?
|
|
7334
|
+
imageUrl String?
|
|
7335
|
+
quantityTotal Int
|
|
7336
|
+
quantityRemaining Int
|
|
7337
|
+
displayOrder Int @default(0)
|
|
7338
|
+
sponsorLabel String?
|
|
7339
|
+
sponsorServiceId String?
|
|
7340
|
+
eligibility GiveawayEligibility
|
|
7341
|
+
competitionId String?
|
|
7342
|
+
sideQuestId String?
|
|
7343
|
+
pickupNote String?
|
|
7344
|
+
createdAt DateTime @default(now())
|
|
7345
|
+
updatedAt DateTime @updatedAt
|
|
7346
|
+
|
|
7347
|
+
bashEvent BashEvent @relation(fields: [bashEventId], references: [id], onDelete: Cascade)
|
|
7348
|
+
competition Competition? @relation(fields: [competitionId], references: [id], onDelete: SetNull)
|
|
7349
|
+
sideQuest SideQuest? @relation(fields: [sideQuestId], references: [id], onDelete: SetNull)
|
|
7350
|
+
sponsorService Service? @relation(fields: [sponsorServiceId], references: [id], onDelete: SetNull)
|
|
7351
|
+
redemptions GiveawayRedemption[]
|
|
7352
|
+
|
|
7353
|
+
@@index([bashEventId])
|
|
7354
|
+
@@index([bashEventId, displayOrder])
|
|
7355
|
+
@@index([competitionId])
|
|
7356
|
+
@@index([sideQuestId])
|
|
7357
|
+
}
|
|
7358
|
+
|
|
7359
|
+
/// Event-team confirmed handout. Partial unique (giveawayId, attendeeId) WHERE voidedAt IS NULL — migration SQL only.
|
|
7360
|
+
model GiveawayRedemption {
|
|
7361
|
+
id String @id @default(cuid())
|
|
7362
|
+
giveawayId String
|
|
7363
|
+
attendeeId String
|
|
7364
|
+
userId String?
|
|
7365
|
+
ticketId String?
|
|
7366
|
+
receivedAt DateTime @default(now())
|
|
7367
|
+
receivedByUserId String
|
|
7368
|
+
voidedAt DateTime?
|
|
7369
|
+
voidedByUserId String?
|
|
7370
|
+
|
|
7371
|
+
giveaway Giveaway @relation(fields: [giveawayId], references: [id], onDelete: Cascade)
|
|
7372
|
+
user User? @relation("GiveawayRedemptionUser", fields: [userId], references: [id], onDelete: SetNull)
|
|
7373
|
+
ticket Ticket? @relation(fields: [ticketId], references: [id], onDelete: SetNull)
|
|
7374
|
+
receivedBy User @relation("GiveawayReceivedBy", fields: [receivedByUserId], references: [id], onDelete: Restrict)
|
|
7375
|
+
voidedBy User? @relation("GiveawayVoidedBy", fields: [voidedByUserId], references: [id], onDelete: SetNull)
|
|
7376
|
+
|
|
7377
|
+
@@index([giveawayId])
|
|
7378
|
+
@@index([attendeeId])
|
|
7379
|
+
@@index([ticketId])
|
|
7380
|
+
@@index([userId])
|
|
7381
|
+
}
|
|
7382
|
+
|
|
7037
7383
|
enum ExpenseExtractionStatus {
|
|
7038
7384
|
none
|
|
7039
7385
|
pending
|
|
@@ -8176,6 +8522,13 @@ enum NotificationType {
|
|
|
8176
8522
|
CompetitionPrizeOfferReceived // Host: someone offered a prize contribution
|
|
8177
8523
|
CompetitionPrizeOfferAccepted // Offeror: host accepted your prize offer
|
|
8178
8524
|
CompetitionPrizeOfferDeclined // Offeror: host declined your prize offer
|
|
8525
|
+
PromoterCompetitionJoined // Organizer: a promoter joined the challenge
|
|
8526
|
+
PromoterCompetitionMilestoneReached // Promoter: you hit a milestone and earned a reward
|
|
8527
|
+
PromoterCompetitionLeaderboardChange // Promoter: your leaderboard rank changed
|
|
8528
|
+
PromoterCompetitionEnding // Promoter: competition ending in 24h (with earned progress)
|
|
8529
|
+
PromoterCompetitionCompleted // Promoter + organizer: competition finished
|
|
8530
|
+
PromoterCompetitionRewardFulfilled // Promoter: organizer marked your reward as fulfilled
|
|
8531
|
+
PreviousPromoterInvited // Promoter: organizer you've worked with is inviting you back
|
|
8179
8532
|
BashRating
|
|
8180
8533
|
BashRatingMilestone
|
|
8181
8534
|
BashFeedPost
|
|
@@ -8872,6 +9225,41 @@ enum CompetitionType {
|
|
|
8872
9225
|
AUDIENCE_VOTING // Audience Voting-Based
|
|
8873
9226
|
}
|
|
8874
9227
|
|
|
9228
|
+
enum CompetitionPurpose {
|
|
9229
|
+
CONSUMER // existing behavior — vote/bracket/raffle/contest
|
|
9230
|
+
PROMOTER // ticket sales contest — rewards promoters per milestone
|
|
9231
|
+
}
|
|
9232
|
+
|
|
9233
|
+
enum PromoterRewardMode {
|
|
9234
|
+
TOTAL_AT_MILESTONE // "10 sales = $40 total earned" (default)
|
|
9235
|
+
ADDITIVE // milestone rewards stack on each other
|
|
9236
|
+
}
|
|
9237
|
+
|
|
9238
|
+
enum PromoterRecruitMode {
|
|
9239
|
+
Public // anyone can join from bash page
|
|
9240
|
+
InviteOnly // organizer sends invites (default)
|
|
9241
|
+
Private // no enrollment shown publicly
|
|
9242
|
+
}
|
|
9243
|
+
|
|
9244
|
+
enum PromoterRewardType {
|
|
9245
|
+
CASH
|
|
9246
|
+
TICKET
|
|
9247
|
+
TICKET_UPGRADE
|
|
9248
|
+
TABLE
|
|
9249
|
+
ACCESS
|
|
9250
|
+
MERCH
|
|
9251
|
+
SPONSOR_PRIZE
|
|
9252
|
+
CREDIT
|
|
9253
|
+
CUSTOM
|
|
9254
|
+
}
|
|
9255
|
+
|
|
9256
|
+
enum PromoterRewardStatus {
|
|
9257
|
+
PENDING // milestone not yet reached
|
|
9258
|
+
EARNED // threshold crossed; awaiting fulfillment
|
|
9259
|
+
FULFILLED // organizer marked delivered
|
|
9260
|
+
REVOKED // refunds pushed promoter below threshold; FULFILLED rewards are never auto-revoked
|
|
9261
|
+
}
|
|
9262
|
+
|
|
8875
9263
|
enum PlacementAwardStyle {
|
|
8876
9264
|
Trophy // Gold/silver/bronze trophies for 1st/2nd/3rd
|
|
8877
9265
|
Medal // Gold/silver/bronze medals for 1st/2nd/3rd
|
|
@@ -12212,6 +12600,8 @@ model AppliedDiscount {
|
|
|
12212
12600
|
attributionCampaignId String?
|
|
12213
12601
|
commissionRate Float?
|
|
12214
12602
|
commissionAmount Int? // In cents
|
|
12603
|
+
/// Set when this discount was applied under a PROMOTER competition — used for attribution recalculation
|
|
12604
|
+
competitionId String?
|
|
12215
12605
|
|
|
12216
12606
|
// Display
|
|
12217
12607
|
displayReason String? // "Early Bird Discount" for receipt
|