@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.
- package/dist/__tests__/agePolicy.test.d.ts +2 -0
- package/dist/__tests__/agePolicy.test.d.ts.map +1 -0
- package/dist/__tests__/agePolicy.test.js +203 -0
- package/dist/__tests__/agePolicy.test.js.map +1 -0
- package/dist/__tests__/getDisplayGender.test.d.ts +2 -0
- package/dist/__tests__/getDisplayGender.test.d.ts.map +1 -0
- package/dist/__tests__/getDisplayGender.test.js +34 -0
- package/dist/__tests__/getDisplayGender.test.js.map +1 -0
- package/dist/__tests__/statusEnums.test.d.ts +2 -0
- package/dist/__tests__/statusEnums.test.d.ts.map +1 -0
- package/dist/__tests__/statusEnums.test.js +24 -0
- package/dist/__tests__/statusEnums.test.js.map +1 -0
- package/dist/aiApproval.d.ts +89 -0
- package/dist/aiApproval.d.ts.map +1 -0
- package/dist/aiApproval.js +82 -0
- package/dist/aiApproval.js.map +1 -0
- package/dist/definitions.d.ts +44 -2
- package/dist/definitions.d.ts.map +1 -1
- package/dist/definitions.js +106 -2
- package/dist/definitions.js.map +1 -1
- package/dist/extendedSchemas.d.ts +280 -105
- package/dist/extendedSchemas.d.ts.map +1 -1
- package/dist/extendedSchemas.js +34 -2
- package/dist/extendedSchemas.js.map +1 -1
- package/dist/index.d.ts +5 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/legalTemplates.d.ts +1 -1
- package/dist/legalTemplates.js +1 -1
- package/dist/utils/__tests__/badgeUtils.test.d.ts +2 -0
- package/dist/utils/__tests__/badgeUtils.test.d.ts.map +1 -0
- package/dist/utils/__tests__/badgeUtils.test.js +157 -0
- package/dist/utils/__tests__/badgeUtils.test.js.map +1 -0
- package/dist/utils/__tests__/bashPointsPaymentUtils.test.d.ts +2 -0
- package/dist/utils/__tests__/bashPointsPaymentUtils.test.d.ts.map +1 -0
- package/dist/utils/__tests__/bashPointsPaymentUtils.test.js +114 -0
- package/dist/utils/__tests__/bashPointsPaymentUtils.test.js.map +1 -0
- package/dist/utils/__tests__/contentFilterUtils.test.d.ts +2 -0
- package/dist/utils/__tests__/contentFilterUtils.test.d.ts.map +1 -0
- package/dist/utils/__tests__/contentFilterUtils.test.js +443 -0
- package/dist/utils/__tests__/contentFilterUtils.test.js.map +1 -0
- package/dist/utils/__tests__/displayDateUtils.test.d.ts +2 -0
- package/dist/utils/__tests__/displayDateUtils.test.d.ts.map +1 -0
- package/dist/utils/__tests__/displayDateUtils.test.js +105 -0
- package/dist/utils/__tests__/displayDateUtils.test.js.map +1 -0
- package/dist/utils/__tests__/flyerUtils.test.d.ts +2 -0
- package/dist/utils/__tests__/flyerUtils.test.d.ts.map +1 -0
- package/dist/utils/__tests__/flyerUtils.test.js +49 -0
- package/dist/utils/__tests__/flyerUtils.test.js.map +1 -0
- package/dist/utils/__tests__/getBackendHost.test.d.ts +2 -0
- package/dist/utils/__tests__/getBackendHost.test.d.ts.map +1 -0
- package/dist/utils/__tests__/getBackendHost.test.js +104 -0
- package/dist/utils/__tests__/getBackendHost.test.js.map +1 -0
- package/dist/utils/__tests__/getFrontendHost.test.d.ts +2 -0
- package/dist/utils/__tests__/getFrontendHost.test.d.ts.map +1 -0
- package/dist/utils/__tests__/getFrontendHost.test.js +207 -0
- package/dist/utils/__tests__/getFrontendHost.test.js.map +1 -0
- package/dist/utils/__tests__/promoCodesUtils.test.d.ts +2 -0
- package/dist/utils/__tests__/promoCodesUtils.test.d.ts.map +1 -0
- package/dist/utils/__tests__/promoCodesUtils.test.js +183 -0
- package/dist/utils/__tests__/promoCodesUtils.test.js.map +1 -0
- package/dist/utils/__tests__/qrCodeUtils.test.d.ts +2 -0
- package/dist/utils/__tests__/qrCodeUtils.test.d.ts.map +1 -0
- package/dist/utils/__tests__/qrCodeUtils.test.js +99 -0
- package/dist/utils/__tests__/qrCodeUtils.test.js.map +1 -0
- package/dist/utils/__tests__/stripeAccountUtils.test.d.ts +2 -0
- package/dist/utils/__tests__/stripeAccountUtils.test.d.ts.map +1 -0
- package/dist/utils/__tests__/stripeAccountUtils.test.js +75 -0
- package/dist/utils/__tests__/stripeAccountUtils.test.js.map +1 -0
- package/dist/utils/blog/__tests__/getRelatedBlogPosts.test.d.ts +2 -0
- package/dist/utils/blog/__tests__/getRelatedBlogPosts.test.d.ts.map +1 -0
- package/dist/utils/blog/__tests__/getRelatedBlogPosts.test.js +233 -0
- package/dist/utils/blog/__tests__/getRelatedBlogPosts.test.js.map +1 -0
- package/dist/utils/blog/blogCommentDbUtils.d.ts +161 -0
- package/dist/utils/blog/blogCommentDbUtils.d.ts.map +1 -0
- package/dist/utils/blog/blogCommentDbUtils.js +111 -0
- package/dist/utils/blog/blogCommentDbUtils.js.map +1 -0
- package/dist/utils/blog/blogDbUtils.d.ts +10 -0
- package/dist/utils/blog/blogDbUtils.d.ts.map +1 -1
- package/dist/utils/blog/blogDbUtils.js +71 -0
- package/dist/utils/blog/blogDbUtils.js.map +1 -1
- package/dist/utils/flyerUtils.d.ts +42 -0
- package/dist/utils/flyerUtils.d.ts.map +1 -0
- package/dist/utils/flyerUtils.js +104 -0
- package/dist/utils/flyerUtils.js.map +1 -0
- package/dist/utils/urlUtils.d.ts +10 -0
- package/dist/utils/urlUtils.d.ts.map +1 -1
- package/dist/utils/urlUtils.js +24 -5
- package/dist/utils/urlUtils.js.map +1 -1
- package/dist/utils/userUtils.d.ts +32 -0
- package/dist/utils/userUtils.d.ts.map +1 -1
- package/dist/utils/userUtils.js +27 -0
- package/dist/utils/userUtils.js.map +1 -1
- package/package.json +1 -1
- package/prisma/schema.prisma +1196 -845
- package/src/__tests__/agePolicy.test.ts +257 -0
- package/src/__tests__/getDisplayGender.test.ts +50 -0
- package/src/__tests__/statusEnums.test.ts +36 -0
- package/src/aiApproval.ts +118 -0
- package/src/definitions.ts +138 -1
- package/src/extendedSchemas.ts +86 -3
- package/src/index.ts +15 -0
- package/src/legalTemplates.ts +1 -1
- package/src/utils/__tests__/badgeUtils.test.ts +191 -0
- package/src/utils/__tests__/bashPointsPaymentUtils.test.ts +153 -0
- package/src/utils/__tests__/contentFilterUtils.test.ts +547 -0
- package/src/utils/__tests__/displayDateUtils.test.ts +113 -0
- package/src/utils/__tests__/flyerUtils.test.ts +70 -0
- package/src/utils/__tests__/getBackendHost.test.ts +128 -0
- package/src/utils/__tests__/getFrontendHost.test.ts +232 -0
- package/src/utils/__tests__/promoCodesUtils.test.ts +237 -0
- package/src/utils/__tests__/qrCodeUtils.test.ts +143 -0
- package/src/utils/__tests__/stripeAccountUtils.test.ts +93 -0
- package/src/utils/blog/__tests__/getRelatedBlogPosts.test.ts +271 -0
- package/src/utils/blog/blogCommentDbUtils.ts +161 -0
- package/src/utils/blog/blogDbUtils.ts +95 -1
- package/src/utils/flyerUtils.ts +137 -0
- package/src/utils/urlUtils.ts +27 -5
- package/src/utils/userUtils.ts +40 -0
- package/dist/utils/__tests__/cancellationPolicyRefundResolver.test.d.ts +0 -6
- package/dist/utils/__tests__/cancellationPolicyRefundResolver.test.d.ts.map +0 -1
- package/dist/utils/__tests__/cancellationPolicyRefundResolver.test.js +0 -104
- package/dist/utils/__tests__/cancellationPolicyRefundResolver.test.js.map +0 -1
- package/dist/utils/service/serviceRateDBUtils.d.ts +0 -1
- package/dist/utils/service/serviceRateDBUtils.d.ts.map +0 -1
- package/dist/utils/service/serviceRateDBUtils.js +0 -159
- package/dist/utils/service/serviceRateDBUtils.js.map +0 -1
- package/prisma/migrations/add_bash_availability.sql +0 -53
- package/prisma/migrations/add_bashcash_pricing_to_ticket_tier.sql +0 -15
- package/prisma/migrations/add_bashpoints_purchase_tracking.sql +0 -33
- package/prisma/migrations/add_event_group_allow_auto_join.sql +0 -17
- package/prisma/migrations/add_group_member_status_not_going_maybe.sql +0 -5
- package/prisma/migrations/add_groups_and_momentum.sql +0 -135
- package/prisma/migrations/add_groups_momentum_phase0_4.sql +0 -200
- package/prisma/migrations/add_new_feature_tables.sql +0 -140
- package/prisma/migrations/add_pricing_type_enum.sql +0 -88
- package/prisma/migrations/add_tier_privacy_and_fee_handling.sql +0 -29
- package/prisma/migrations/diagnostic_bashcash_columns.sql +0 -157
- package/prisma/migrations/fix_bashcash_referral_code_schema_mismatch.sql +0 -81
- package/prisma/migrations/rename_bashcash_to_bashpoints.sql +0 -183
- package/prisma/migrations/rename_bashcredits_to_bashpoints.sql +0 -96
package/prisma/schema.prisma
CHANGED
|
@@ -55,38 +55,38 @@ model BashComment {
|
|
|
55
55
|
|
|
56
56
|
// BashFeed Models - Event-Centric Social Discovery Feed
|
|
57
57
|
model BashFeedPost {
|
|
58
|
-
id
|
|
59
|
-
userId
|
|
60
|
-
bashId
|
|
61
|
-
serviceId
|
|
62
|
-
bashAssociationType
|
|
63
|
-
content
|
|
64
|
-
mediaIds
|
|
65
|
-
mentionedUserIds
|
|
66
|
-
isAnonymous
|
|
67
|
-
viewCount
|
|
68
|
-
isFeatured
|
|
69
|
-
featuredAt
|
|
70
|
-
featuredBoost
|
|
71
|
-
featuredUntil
|
|
72
|
-
createdAt
|
|
73
|
-
updatedAt
|
|
74
|
-
editedAt
|
|
58
|
+
id String @id @default(cuid())
|
|
59
|
+
userId String
|
|
60
|
+
bashId String?
|
|
61
|
+
serviceId String?
|
|
62
|
+
bashAssociationType BashAssociationType? // How user is associated with the bash (for post display)
|
|
63
|
+
content String? @db.Text
|
|
64
|
+
mediaIds String[] // Array of Media IDs
|
|
65
|
+
mentionedUserIds String[] // Array of User IDs mentioned in post
|
|
66
|
+
isAnonymous Boolean @default(false) // User can choose to post anonymously
|
|
67
|
+
viewCount Int @default(0) // Analytics only, not shown publicly
|
|
68
|
+
isFeatured Boolean @default(false) // Post is promoted/featured
|
|
69
|
+
featuredAt DateTime? // When post was featured
|
|
70
|
+
featuredBoost Float @default(0) // Current boost score (time-decayed)
|
|
71
|
+
featuredUntil DateTime? // When the feature boost expires
|
|
72
|
+
createdAt DateTime @default(now())
|
|
73
|
+
updatedAt DateTime @updatedAt
|
|
74
|
+
editedAt DateTime?
|
|
75
75
|
/// When set, this row is a feed "repost shell": `user` is the reposter; content lives on `repostOf`.
|
|
76
|
-
repostOfPostId
|
|
77
|
-
repostOf
|
|
78
|
-
repostShells
|
|
76
|
+
repostOfPostId String?
|
|
77
|
+
repostOf BashFeedPost? @relation("BashFeedPostRepost", fields: [repostOfPostId], references: [id], onDelete: Cascade)
|
|
78
|
+
repostShells BashFeedPost[] @relation("BashFeedPostRepost")
|
|
79
79
|
|
|
80
80
|
// Relationships
|
|
81
|
-
user
|
|
82
|
-
bash
|
|
83
|
-
service
|
|
84
|
-
likes
|
|
85
|
-
comments
|
|
86
|
-
ratings
|
|
87
|
-
reports
|
|
88
|
-
saves
|
|
89
|
-
reposts
|
|
81
|
+
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
82
|
+
bash BashEvent? @relation(fields: [bashId], references: [id], onDelete: Cascade)
|
|
83
|
+
service Service? @relation(fields: [serviceId], references: [id], onDelete: Cascade)
|
|
84
|
+
likes BashFeedLike[]
|
|
85
|
+
comments BashFeedComment[]
|
|
86
|
+
ratings BashFeedRating[]
|
|
87
|
+
reports BashFeedReport[]
|
|
88
|
+
saves BashFeedSave[]
|
|
89
|
+
reposts BashFeedRepost[]
|
|
90
90
|
helpfulVotes ReviewHelpfulVote[]
|
|
91
91
|
|
|
92
92
|
@@unique([userId, repostOfPostId])
|
|
@@ -236,18 +236,18 @@ model Competition {
|
|
|
236
236
|
bracketData Json? // Store bracket structure/metadata
|
|
237
237
|
bracketVisible Boolean @default(true)
|
|
238
238
|
|
|
239
|
-
createdAt
|
|
240
|
-
updatedAt
|
|
241
|
-
bashEvent
|
|
242
|
-
owner
|
|
243
|
-
sponsor
|
|
244
|
-
prizes
|
|
245
|
-
participants
|
|
246
|
-
votes
|
|
247
|
-
matches
|
|
248
|
-
judgeAssignments
|
|
249
|
-
judgeScores
|
|
250
|
-
notifications
|
|
239
|
+
createdAt DateTime @default(now())
|
|
240
|
+
updatedAt DateTime @updatedAt
|
|
241
|
+
bashEvent BashEvent @relation(fields: [bashEventId], references: [id], onDelete: Cascade)
|
|
242
|
+
owner User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
243
|
+
sponsor CompetitionSponsor[]
|
|
244
|
+
prizes Prize[]
|
|
245
|
+
participants CompetitionParticipant[]
|
|
246
|
+
votes CompetitionVote[]
|
|
247
|
+
matches CompetitionMatch[]
|
|
248
|
+
judgeAssignments CompetitionJudgeAssignment[]
|
|
249
|
+
judgeScores CompetitionJudgeScore[]
|
|
250
|
+
notifications Notification[]
|
|
251
251
|
|
|
252
252
|
@@index([bashEventId])
|
|
253
253
|
@@index([competitionType])
|
|
@@ -318,9 +318,9 @@ model CompetitionParticipant {
|
|
|
318
318
|
votes CompetitionVote[]
|
|
319
319
|
|
|
320
320
|
// Tournament bracket relations
|
|
321
|
-
matchesAsParticipant1 CompetitionMatch[]
|
|
322
|
-
matchesAsParticipant2 CompetitionMatch[]
|
|
323
|
-
matchesWon CompetitionMatch[]
|
|
321
|
+
matchesAsParticipant1 CompetitionMatch[] @relation("MatchParticipant1")
|
|
322
|
+
matchesAsParticipant2 CompetitionMatch[] @relation("MatchParticipant2")
|
|
323
|
+
matchesWon CompetitionMatch[] @relation("MatchWinner")
|
|
324
324
|
judgeScores CompetitionJudgeScore[]
|
|
325
325
|
|
|
326
326
|
@@index([competitionId])
|
|
@@ -376,7 +376,7 @@ model CompetitionVote {
|
|
|
376
376
|
}
|
|
377
377
|
|
|
378
378
|
model EventTask {
|
|
379
|
-
id String
|
|
379
|
+
id String @id @default(cuid())
|
|
380
380
|
creatorId String
|
|
381
381
|
bashEventId String
|
|
382
382
|
title String
|
|
@@ -385,15 +385,16 @@ model EventTask {
|
|
|
385
385
|
status TaskStatus?
|
|
386
386
|
neededCount Int? // Number of volunteers needed
|
|
387
387
|
estimatedDuration Int? // Estimated duration in minutes
|
|
388
|
-
createdAt DateTime?
|
|
388
|
+
createdAt DateTime? @default(now())
|
|
389
389
|
organizationId String? // Organization association
|
|
390
|
-
assignedTo User?
|
|
391
|
-
bashEvent BashEvent
|
|
392
|
-
creator User
|
|
390
|
+
assignedTo User? @relation("TasksAssignedToMe", fields: [assignedToId], references: [id], onDelete: Cascade)
|
|
391
|
+
bashEvent BashEvent @relation(fields: [bashEventId], references: [id], onDelete: Cascade)
|
|
392
|
+
creator User @relation(fields: [creatorId], references: [id], onDelete: Cascade)
|
|
393
393
|
notificationsReferencingMe Notification[]
|
|
394
394
|
comments TaskComment[]
|
|
395
395
|
invitations TaskInvitation[]
|
|
396
|
-
|
|
396
|
+
expenses Expense[]
|
|
397
|
+
potluckItem PotluckItem? @relation("PotluckItemTask")
|
|
397
398
|
bashEventSuggestion BashEventSuggestion? @relation("SuggestionTask")
|
|
398
399
|
}
|
|
399
400
|
|
|
@@ -462,20 +463,20 @@ model SentReminder {
|
|
|
462
463
|
}
|
|
463
464
|
|
|
464
465
|
model BashEventPromoCode {
|
|
465
|
-
id
|
|
466
|
-
code
|
|
467
|
-
ticketTierId
|
|
468
|
-
stripeCouponId
|
|
469
|
-
discountAmountInCents
|
|
470
|
-
discountAmountPercentage
|
|
471
|
-
maxRedemptions
|
|
472
|
-
redeemBy
|
|
473
|
-
promoterId
|
|
474
|
-
meta
|
|
475
|
-
bashPointsRewardPerTicket Int?
|
|
476
|
-
promoter
|
|
477
|
-
ticketTier
|
|
478
|
-
usedBy
|
|
466
|
+
id String @id @default(cuid())
|
|
467
|
+
code String
|
|
468
|
+
ticketTierId String
|
|
469
|
+
stripeCouponId String?
|
|
470
|
+
discountAmountInCents Int?
|
|
471
|
+
discountAmountPercentage Int?
|
|
472
|
+
maxRedemptions Int?
|
|
473
|
+
redeemBy DateTime?
|
|
474
|
+
promoterId String?
|
|
475
|
+
meta String?
|
|
476
|
+
bashPointsRewardPerTicket Int? // Host-defined BashPoints per ticket for promoter rewards
|
|
477
|
+
promoter Promoter? @relation(fields: [promoterId], references: [id])
|
|
478
|
+
ticketTier TicketTier @relation(fields: [ticketTierId], references: [id])
|
|
479
|
+
usedBy User[] @relation("BashEventPromoCodeToUser")
|
|
479
480
|
|
|
480
481
|
@@unique([ticketTierId, code])
|
|
481
482
|
}
|
|
@@ -588,6 +589,7 @@ model Invitation {
|
|
|
588
589
|
rejectedDate DateTime?
|
|
589
590
|
maybeDate DateTime?
|
|
590
591
|
isFreeGuest Boolean @default(false)
|
|
592
|
+
sentCount Int @default(1) // Number of times this invitation email has been sent (1 on initial send; incremented on each host-confirmed re-invite for the same email + bash)
|
|
591
593
|
associatedBash AssociatedBash?
|
|
592
594
|
bashEvent BashEvent? @relation(fields: [bashEventId], references: [id], onDelete: Cascade)
|
|
593
595
|
creator User @relation("InvitationsCreatedByMe", fields: [creatorId], references: [id], onDelete: Cascade)
|
|
@@ -600,124 +602,135 @@ model Invitation {
|
|
|
600
602
|
}
|
|
601
603
|
|
|
602
604
|
model BashEvent {
|
|
603
|
-
id
|
|
604
|
-
source
|
|
605
|
-
sourcePartnerId
|
|
606
|
-
title
|
|
607
|
-
slug
|
|
608
|
-
creatorId
|
|
609
|
-
createdAt
|
|
610
|
-
isApproved
|
|
611
|
-
description
|
|
612
|
-
eventType
|
|
613
|
-
timezone
|
|
614
|
-
startDateTime
|
|
615
|
-
endDateTime
|
|
616
|
-
waiverUrl
|
|
617
|
-
waiverRequired
|
|
618
|
-
waiverDisplayType
|
|
605
|
+
id String @id @default(cuid())
|
|
606
|
+
source BashEventSource @default(Bash)
|
|
607
|
+
sourcePartnerId String? // When source=Partner, e.g. 'jamwith', 'mixlog'
|
|
608
|
+
title String
|
|
609
|
+
slug String? @unique
|
|
610
|
+
creatorId String
|
|
611
|
+
createdAt DateTime? @default(now())
|
|
612
|
+
isApproved Boolean? @default(false)
|
|
613
|
+
description String?
|
|
614
|
+
eventType String @default("Other")
|
|
615
|
+
timezone String?
|
|
616
|
+
startDateTime DateTime?
|
|
617
|
+
endDateTime DateTime?
|
|
618
|
+
waiverUrl String?
|
|
619
|
+
waiverRequired Boolean @default(false)
|
|
620
|
+
waiverDisplayType String? @default("inline")
|
|
619
621
|
/// Host opt-in: show photo/video consent at checkout; null photoReleaseText = platform default template
|
|
620
|
-
photoReleaseEnabled
|
|
621
|
-
photoReleaseRequired
|
|
622
|
-
photoReleaseText
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
622
|
+
photoReleaseEnabled Boolean @default(false)
|
|
623
|
+
photoReleaseRequired Boolean @default(true)
|
|
624
|
+
photoReleaseText String? @db.Text
|
|
625
|
+
/// Host-required IDs for ticket checkout
|
|
626
|
+
requireGovernmentId Boolean @default(false)
|
|
627
|
+
requireStudentId Boolean @default(false)
|
|
628
|
+
/// Minimum-age policy surfaced on the BashCard and used as a discover filter.
|
|
629
|
+
/// When set to EighteenPlus / TwentyOnePlus the wizard auto-toggles requireGovernmentId
|
|
630
|
+
/// so we can verify age via the user's stored ID at checkout.
|
|
631
|
+
agePolicy AgePolicy @default(AllAges)
|
|
632
|
+
targetAudienceId String? @unique
|
|
633
|
+
amountOfGuestsId String? @unique
|
|
634
|
+
vibe String?
|
|
635
|
+
occasion String?
|
|
636
|
+
dress String?
|
|
637
|
+
allowed String?
|
|
638
|
+
notAllowed String?
|
|
639
|
+
eventFormat EventFormat? // Derived from location and videoLink: In-Person, Virtual, or Hybrid
|
|
640
|
+
nonProfit Boolean?
|
|
641
|
+
nonProfitId String?
|
|
642
|
+
privacy Privacy @default(Public)
|
|
643
|
+
capacity Int?
|
|
644
|
+
location String?
|
|
645
|
+
street String?
|
|
646
|
+
city String?
|
|
647
|
+
state String?
|
|
648
|
+
zipCode String?
|
|
649
|
+
country String?
|
|
650
|
+
status BashStatus @default(Draft)
|
|
651
|
+
tags String[]
|
|
652
|
+
coverPhoto String?
|
|
653
|
+
clubId String?
|
|
654
|
+
dateTimePublished DateTime?
|
|
655
|
+
includedItems String[]
|
|
656
|
+
videoLink String?
|
|
657
|
+
subtitle String?
|
|
658
|
+
isFeatured Boolean?
|
|
659
|
+
featuredUntil DateTime? // When paid feature expires (null = no expiry / super-user pinned)
|
|
660
|
+
isTrending Boolean?
|
|
661
|
+
venueId String?
|
|
662
|
+
averageRating Float? @default(0)
|
|
663
|
+
totalRatings Int? @default(0) // Total count of all ratings (Review + BashFeedRating)
|
|
664
|
+
totalReviews Int? @default(0) // Count of Review records (anonymous quick ratings)
|
|
665
|
+
totalFeedRatings Int? @default(0) // Count of BashFeedRating records (from posts)
|
|
666
|
+
allowDonations Boolean? @default(false)
|
|
667
|
+
suggestedDonationAmount Int?
|
|
668
|
+
donationDetails String?
|
|
669
|
+
absorbDonationFees Boolean @default(false)
|
|
670
|
+
absorbTicketFees Boolean @default(false)
|
|
662
671
|
/// When true, attendees may request a refund from the app/email (host approves in Tickets → Refunds). When false, self-serve refund CTAs are hidden.
|
|
663
|
-
allowAttendeeRefundRequests Boolean
|
|
672
|
+
allowAttendeeRefundRequests Boolean @default(true)
|
|
664
673
|
// GuestPays / Split: Stripe processing + Bash platform fee presentation (see platformFeeEnabled).
|
|
665
|
-
feeHandling
|
|
674
|
+
feeHandling String @default("HostAbsorbs") // "GuestPays" | "HostAbsorbs" | "Split"
|
|
666
675
|
/// When true, Bash charges platformFeeRate on ticket gross (e.g. 3%) in addition to Stripe processing pass-through.
|
|
667
|
-
platformFeeEnabled
|
|
676
|
+
platformFeeEnabled Boolean @default(false)
|
|
668
677
|
/// Bash platform take rate on ticket gross (e.g. 0.03 = 3%). Ignored when platformFeeEnabled is false.
|
|
669
|
-
platformFeeRate
|
|
678
|
+
platformFeeRate Float @default(0.03)
|
|
670
679
|
/// Optional: attendees can tag which act they came to see; drives attribution reports and future payouts.
|
|
671
|
-
artistAttributionEnabled
|
|
680
|
+
artistAttributionEnabled Boolean @default(false)
|
|
672
681
|
/// "percentage" | "flat" — how artistPayoutRate is interpreted for suggested splits (display/export).
|
|
673
|
-
artistPayoutMode
|
|
682
|
+
artistPayoutMode String?
|
|
674
683
|
/// Percentage of door (0–100) or flat cents per ticket depending on artistPayoutMode.
|
|
675
|
-
artistPayoutRate
|
|
676
|
-
topPromoterPrize
|
|
677
|
-
promoterLeaderboardIsPublic
|
|
678
|
-
showAttendees
|
|
679
|
-
/// Host opt-in: show soft "public interest" controls on the
|
|
680
|
-
allowPublicInterestRsvp
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
684
|
+
artistPayoutRate Float?
|
|
685
|
+
topPromoterPrize String? // Optional prize label: "Free table for your crew"
|
|
686
|
+
promoterLeaderboardIsPublic Boolean @default(false) // Host opts in to public leaderboard
|
|
687
|
+
showAttendees Boolean @default(true)
|
|
688
|
+
/// Host opt-in: show soft "public interest" controls on the bash detail page (signed-in viewers). Not a guest list; invite RSVP stays separate.
|
|
689
|
+
allowPublicInterestRsvp Boolean @default(false)
|
|
690
|
+
/// When true, guests can join a waitlist (activated automatically when amountOfGuests.allowWaitlistAtMax is set and max capacity is reached)
|
|
691
|
+
waitlistEnabled Boolean @default(false)
|
|
692
|
+
attendeeDisplayMode String @default("All") // "All" | "NetworkOnly" | "Hidden"
|
|
693
|
+
showOrganizerTitles Boolean @default(false)
|
|
694
|
+
servicePreferences Json? // New tiered status: { "Entertainment": "need", "Sponsors": "booked_closed", ... }
|
|
695
|
+
bookedServices Json? // Booked service details: { "Entertainment": { serviceId: "...", providerId: "...", bookedAt: "..." }, ... }
|
|
696
|
+
serviceVisibility Json? // DEPRECATED: Use servicePreferences instead. Kept for backward compatibility during migration.
|
|
697
|
+
plannedServiceIds String[] @default([]) // Service IDs the host has flagged as "plan to book" in the wizard
|
|
698
|
+
originalCreatorId String?
|
|
699
|
+
transferredAt DateTime?
|
|
700
|
+
transferredFromId String?
|
|
701
|
+
transferCount Int @default(0)
|
|
702
|
+
payoutUserId String? // When set, payouts go to this user's Stripe instead of owner's (for transfer-with-retained-payouts)
|
|
703
|
+
startTimeLocked Boolean @default(false)
|
|
704
|
+
p2pPaymentMethod String?
|
|
705
|
+
venmoUsername String?
|
|
706
|
+
venmoQRCodeUrl String?
|
|
707
|
+
zelleEmail String?
|
|
708
|
+
zellePhone String?
|
|
709
|
+
zelleQRCodeUrl String?
|
|
710
|
+
externalTicketUrl String? // URL to external ticket purchase page (for imported events)
|
|
711
|
+
externalPriceMin Int? // Minimum ticket price in cents (for imported events)
|
|
699
712
|
/// Structured potluck / BYOB (MVP: flags + free-text notes on detail + wizard)
|
|
700
|
-
potluckEnabled
|
|
701
|
-
byobEnabled
|
|
702
|
-
potluckNotes
|
|
713
|
+
potluckEnabled Boolean @default(false)
|
|
714
|
+
byobEnabled Boolean @default(false)
|
|
715
|
+
potluckNotes String? @db.Text
|
|
703
716
|
/// When false, included/allowed/not-allowed chips are read-only (no upvotes or suggestions)
|
|
704
|
-
collaborationEnabled
|
|
705
|
-
/// Host opt-in: show icebreaker prompts on the
|
|
706
|
-
icebreakerEnabled
|
|
717
|
+
collaborationEnabled Boolean @default(true)
|
|
718
|
+
/// Host opt-in: show icebreaker prompts on the bash detail page for guests
|
|
719
|
+
icebreakerEnabled Boolean @default(false)
|
|
707
720
|
/// Host-curated merch catalog for this event (informational; not a checkout line item for MVP)
|
|
708
|
-
merchandiseItems
|
|
709
|
-
externalPriceMax
|
|
710
|
-
externalPriceSummary
|
|
711
|
-
customTermsAndConditions
|
|
712
|
-
itinerary
|
|
713
|
-
backgroundImage
|
|
714
|
-
themeColor
|
|
721
|
+
merchandiseItems Json?
|
|
722
|
+
externalPriceMax Int? // Maximum ticket price in cents (for imported events)
|
|
723
|
+
externalPriceSummary String? // Human-readable price summary e.g., "$50 - $150" or "$75"
|
|
724
|
+
customTermsAndConditions String?
|
|
725
|
+
itinerary Json? // Array of { id: string, title: string, startTime: string, endTime: string, description?: string }
|
|
726
|
+
backgroundImage String? // Custom or curated background image URL for the bash detail page
|
|
727
|
+
themeColor String? // Dominant hex color extracted from the event flyer (e.g. "#7c3aed")
|
|
715
728
|
|
|
716
729
|
// Host broadcast fields
|
|
717
|
-
postEventMessageSent
|
|
718
|
-
postEventMessageSentAt
|
|
719
|
-
broadcastCount
|
|
720
|
-
lastBroadcastAt
|
|
730
|
+
postEventMessageSent Boolean @default(false)
|
|
731
|
+
postEventMessageSentAt DateTime?
|
|
732
|
+
broadcastCount Int @default(0)
|
|
733
|
+
lastBroadcastAt DateTime?
|
|
721
734
|
|
|
722
735
|
// Idea-specific fields (only used when status = 'Idea')
|
|
723
736
|
ideaExpiresAt DateTime?
|
|
@@ -737,6 +750,9 @@ model BashEvent {
|
|
|
737
750
|
maxGuestsPerMember Int? // Guest limit per member (null = unlimited)
|
|
738
751
|
restrictToOrgDepartments String[] @default([]) // Empty = all departments can see/join
|
|
739
752
|
|
|
753
|
+
/// When true, new event expenses default to Pending until host/org approves (see Expense.status).
|
|
754
|
+
requireExpenseApproval Boolean @default(false)
|
|
755
|
+
|
|
740
756
|
associatedBashesReferencingMe AssociatedBash[]
|
|
741
757
|
comments BashComment[]
|
|
742
758
|
amountOfGuests AmountOfGuests? @relation(fields: [amountOfGuestsId], references: [id], onDelete: Cascade)
|
|
@@ -801,7 +817,9 @@ model BashEvent {
|
|
|
801
817
|
interests IdeaInterest[]
|
|
802
818
|
configurations IdeaConfiguration[]
|
|
803
819
|
|
|
804
|
-
/**
|
|
820
|
+
/**
|
|
821
|
+
* Logged-in users: soft RSVP (Going / Maybe / NotGoing) for public published events — not org EventRSVP
|
|
822
|
+
*/
|
|
805
823
|
publicBashRsvps PublicBashRsvp[]
|
|
806
824
|
|
|
807
825
|
// Claiming Relations
|
|
@@ -828,17 +846,33 @@ model BashEvent {
|
|
|
828
846
|
rsvps EventRSVP[] @relation("EventRSVPs")
|
|
829
847
|
|
|
830
848
|
// Groups & page views (Phases 0–4)
|
|
831
|
-
pageViews
|
|
832
|
-
eventGroups
|
|
849
|
+
pageViews BashEventPageView[]
|
|
850
|
+
eventGroups EventGroup[]
|
|
833
851
|
groupUnlockOffers GroupUnlockOffer[]
|
|
834
852
|
|
|
835
853
|
bashEventArtists BashEventArtist[]
|
|
836
854
|
vanityPaths EventVanityPath[]
|
|
855
|
+
flyerCampaigns FlyerCampaign[]
|
|
856
|
+
|
|
857
|
+
/// Latest AI moderator verdict (see `bashApprovalAiService` + `mapAiResultToDecision`).
|
|
858
|
+
/// Null = never reviewed by AI. Recomputed each time the bash transitions to Pending
|
|
859
|
+
/// or a super-user clicks "Re-run AI review".
|
|
860
|
+
aiApprovalVerdict AiApprovalVerdict?
|
|
861
|
+
aiApprovalConfidence Float?
|
|
862
|
+
/// Structured `AiApprovalReasons` (criteria scores + hostFacingMessage + adminFacingNotes).
|
|
863
|
+
/// Schema lives in `bash-common/src/extendedSchemas.ts`.
|
|
864
|
+
aiApprovalReasons Json?
|
|
865
|
+
aiApprovalReviewedAt DateTime?
|
|
866
|
+
aiApprovalModel String?
|
|
867
|
+
aiApprovalRunCount Int @default(0)
|
|
868
|
+
/// SHA-256 of the snapshot fed to the AI; lets us skip a re-run when nothing changed.
|
|
869
|
+
aiApprovalContentHash String?
|
|
837
870
|
|
|
838
871
|
@@index([templateId])
|
|
839
872
|
@@index([parentEventId])
|
|
840
873
|
@@index([organizationId])
|
|
841
874
|
@@index([eventSeriesId])
|
|
875
|
+
@@index([status, aiApprovalVerdict])
|
|
842
876
|
}
|
|
843
877
|
|
|
844
878
|
/// Lineup / attribution roster for an event (optional act list for checkout tagging).
|
|
@@ -858,6 +892,197 @@ model BashEventArtist {
|
|
|
858
892
|
@@index([serviceId])
|
|
859
893
|
}
|
|
860
894
|
|
|
895
|
+
// --- Flyer Blast (USPS EDDM neighborhood mail campaigns) ---
|
|
896
|
+
enum FlyerTargetingMode {
|
|
897
|
+
RADIUS
|
|
898
|
+
CUSTOM
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
enum FlyerFulfillmentType {
|
|
902
|
+
SELF_MAIL
|
|
903
|
+
DONE_FOR_YOU
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
enum FlyerCampaignStatus {
|
|
907
|
+
DRAFT
|
|
908
|
+
ARTWORK_REVIEW
|
|
909
|
+
PAID
|
|
910
|
+
PRINTING
|
|
911
|
+
IN_TRANSIT
|
|
912
|
+
DELIVERED
|
|
913
|
+
CANCELLED
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
enum FlyerSponsorSlot {
|
|
917
|
+
FEATURED
|
|
918
|
+
SUPPORTING_1
|
|
919
|
+
SUPPORTING_2
|
|
920
|
+
}
|
|
921
|
+
|
|
922
|
+
enum FlyerConversionType {
|
|
923
|
+
QR_SCAN
|
|
924
|
+
RSVP
|
|
925
|
+
TICKET_PURCHASE
|
|
926
|
+
SPONSOR_QR_SCAN
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
model FlyerCampaign {
|
|
930
|
+
id String @id @default(cuid())
|
|
931
|
+
bashEventId String
|
|
932
|
+
hostUserId String
|
|
933
|
+
|
|
934
|
+
targetingMode FlyerTargetingMode @default(RADIUS)
|
|
935
|
+
radiusMiles Float?
|
|
936
|
+
centerLat Float?
|
|
937
|
+
centerLng Float?
|
|
938
|
+
customPolygon Json?
|
|
939
|
+
totalHouseholds Int?
|
|
940
|
+
|
|
941
|
+
fulfillmentType FlyerFulfillmentType @default(DONE_FOR_YOU)
|
|
942
|
+
|
|
943
|
+
printPostageCostCents Int?
|
|
944
|
+
bashFeeCents Int?
|
|
945
|
+
sponsorRevenueCents Int?
|
|
946
|
+
hostTotalCostCents Int?
|
|
947
|
+
stripePaymentIntentId String?
|
|
948
|
+
paidAt DateTime?
|
|
949
|
+
|
|
950
|
+
campaignQrSlug String @unique
|
|
951
|
+
campaignPromoCode String?
|
|
952
|
+
|
|
953
|
+
ctaLabel String?
|
|
954
|
+
templateVariant String @default("default")
|
|
955
|
+
|
|
956
|
+
status FlyerCampaignStatus @default(DRAFT)
|
|
957
|
+
|
|
958
|
+
vendorOrderRef String?
|
|
959
|
+
vendorStatus String?
|
|
960
|
+
|
|
961
|
+
bashEvent BashEvent @relation(fields: [bashEventId], references: [id], onDelete: Cascade)
|
|
962
|
+
host User @relation(fields: [hostUserId], references: [id], onDelete: Cascade)
|
|
963
|
+
routes FlyerMailingRoute[]
|
|
964
|
+
artworkVersions FlyerArtwork[]
|
|
965
|
+
sponsors FlyerCampaignSponsor[]
|
|
966
|
+
conversions FlyerConversion[]
|
|
967
|
+
|
|
968
|
+
createdAt DateTime @default(now())
|
|
969
|
+
updatedAt DateTime @updatedAt
|
|
970
|
+
|
|
971
|
+
@@index([bashEventId])
|
|
972
|
+
@@index([hostUserId])
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
model FlyerMailingRoute {
|
|
976
|
+
id String @id @default(cuid())
|
|
977
|
+
campaignId String
|
|
978
|
+
campaign FlyerCampaign @relation(fields: [campaignId], references: [id], onDelete: Cascade)
|
|
979
|
+
|
|
980
|
+
crrtCode String
|
|
981
|
+
zipCode String
|
|
982
|
+
city String
|
|
983
|
+
state String @default("UT")
|
|
984
|
+
householdCount Int
|
|
985
|
+
|
|
986
|
+
medianIncomeBand String?
|
|
987
|
+
avgHouseholdSize Float?
|
|
988
|
+
medianAge Float?
|
|
989
|
+
|
|
990
|
+
createdAt DateTime @default(now())
|
|
991
|
+
|
|
992
|
+
@@unique([campaignId, crrtCode, zipCode])
|
|
993
|
+
@@index([campaignId])
|
|
994
|
+
}
|
|
995
|
+
|
|
996
|
+
model FlyerArtwork {
|
|
997
|
+
id String @id @default(cuid())
|
|
998
|
+
campaignId String
|
|
999
|
+
campaign FlyerCampaign @relation(fields: [campaignId], references: [id], onDelete: Cascade)
|
|
1000
|
+
|
|
1001
|
+
version Int
|
|
1002
|
+
s3KeyPrintPdf String?
|
|
1003
|
+
s3KeyPreviewPng String?
|
|
1004
|
+
|
|
1005
|
+
widthIn Float @default(6.25)
|
|
1006
|
+
heightIn Float @default(11)
|
|
1007
|
+
isEddmCompliant Boolean @default(false)
|
|
1008
|
+
|
|
1009
|
+
createdAt DateTime @default(now())
|
|
1010
|
+
|
|
1011
|
+
@@index([campaignId])
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
model FlyerCampaignSponsor {
|
|
1015
|
+
id String @id @default(cuid())
|
|
1016
|
+
campaignId String
|
|
1017
|
+
campaign FlyerCampaign @relation(fields: [campaignId], references: [id], onDelete: Cascade)
|
|
1018
|
+
|
|
1019
|
+
slotType FlyerSponsorSlot
|
|
1020
|
+
businessName String
|
|
1021
|
+
logoS3Key String?
|
|
1022
|
+
ctaText String?
|
|
1023
|
+
sponsorQrSlug String? @unique
|
|
1024
|
+
|
|
1025
|
+
slotPriceCents Int @default(0)
|
|
1026
|
+
stripePaymentIntentId String?
|
|
1027
|
+
paidAt DateTime?
|
|
1028
|
+
|
|
1029
|
+
hostPayoutCents Int?
|
|
1030
|
+
bashFeeCents Int?
|
|
1031
|
+
|
|
1032
|
+
conversions FlyerConversion[]
|
|
1033
|
+
|
|
1034
|
+
createdAt DateTime @default(now())
|
|
1035
|
+
|
|
1036
|
+
@@unique([campaignId, slotType])
|
|
1037
|
+
@@index([campaignId])
|
|
1038
|
+
}
|
|
1039
|
+
|
|
1040
|
+
model FlyerConversion {
|
|
1041
|
+
id String @id @default(cuid())
|
|
1042
|
+
campaignId String
|
|
1043
|
+
campaign FlyerCampaign @relation(fields: [campaignId], references: [id], onDelete: Cascade)
|
|
1044
|
+
|
|
1045
|
+
type FlyerConversionType @default(QR_SCAN)
|
|
1046
|
+
sponsorId String?
|
|
1047
|
+
ticketId String?
|
|
1048
|
+
|
|
1049
|
+
crrtCode String?
|
|
1050
|
+
userAgent String?
|
|
1051
|
+
|
|
1052
|
+
occurredAt DateTime @default(now())
|
|
1053
|
+
|
|
1054
|
+
sponsor FlyerCampaignSponsor? @relation(fields: [sponsorId], references: [id], onDelete: SetNull)
|
|
1055
|
+
ticket Ticket? @relation(fields: [ticketId], references: [id], onDelete: SetNull)
|
|
1056
|
+
|
|
1057
|
+
@@index([campaignId])
|
|
1058
|
+
@@index([occurredAt])
|
|
1059
|
+
@@index([sponsorId])
|
|
1060
|
+
@@index([ticketId])
|
|
1061
|
+
}
|
|
1062
|
+
|
|
1063
|
+
/// USPS carrier-route catalog (Utah MVP; expand for national rollout).
|
|
1064
|
+
model PostalCarrierRoute {
|
|
1065
|
+
id String @id @default(cuid())
|
|
1066
|
+
crrtCode String
|
|
1067
|
+
zipCode String
|
|
1068
|
+
city String
|
|
1069
|
+
state String @default("UT")
|
|
1070
|
+
latitude Float
|
|
1071
|
+
longitude Float
|
|
1072
|
+
householdCount Int
|
|
1073
|
+
residentialOnly Boolean @default(true)
|
|
1074
|
+
medianIncomeBand String?
|
|
1075
|
+
avgHouseholdSize Float?
|
|
1076
|
+
medianAge Float?
|
|
1077
|
+
|
|
1078
|
+
createdAt DateTime @default(now())
|
|
1079
|
+
updatedAt DateTime @updatedAt
|
|
1080
|
+
|
|
1081
|
+
@@unique([zipCode, crrtCode])
|
|
1082
|
+
@@index([latitude, longitude])
|
|
1083
|
+
@@index([zipCode])
|
|
1084
|
+
}
|
|
1085
|
+
|
|
861
1086
|
enum BashCreativeStatus {
|
|
862
1087
|
Pending
|
|
863
1088
|
InReview
|
|
@@ -870,16 +1095,16 @@ enum BashCreativeStatus {
|
|
|
870
1095
|
model BashCreativeSubmission {
|
|
871
1096
|
id String @id @default(cuid())
|
|
872
1097
|
serviceId String
|
|
873
|
-
service Service
|
|
1098
|
+
service Service @relation(fields: [serviceId], references: [id], onDelete: Cascade)
|
|
874
1099
|
submittedById String?
|
|
875
|
-
submittedBy User?
|
|
876
|
-
status BashCreativeStatus
|
|
877
|
-
scriptNotes String?
|
|
1100
|
+
submittedBy User? @relation(fields: [submittedById], references: [id], onDelete: SetNull)
|
|
1101
|
+
status BashCreativeStatus @default(Pending)
|
|
1102
|
+
scriptNotes String? @db.Text
|
|
878
1103
|
footageUrl String?
|
|
879
1104
|
deliverableUrl String?
|
|
880
|
-
requestedAt DateTime
|
|
1105
|
+
requestedAt DateTime @default(now())
|
|
881
1106
|
deliveredAt DateTime?
|
|
882
|
-
updatedAt DateTime
|
|
1107
|
+
updatedAt DateTime @updatedAt
|
|
883
1108
|
|
|
884
1109
|
@@index([serviceId])
|
|
885
1110
|
@@index([status])
|
|
@@ -1045,15 +1270,15 @@ model PublicBashRsvp {
|
|
|
1045
1270
|
|
|
1046
1271
|
// Per-event referral rewards: host defines tiers (e.g. 3 referrals = free drink)
|
|
1047
1272
|
model EventReferralReward {
|
|
1048
|
-
id
|
|
1049
|
-
bashEventId
|
|
1050
|
-
referralCount
|
|
1051
|
-
rewardType
|
|
1052
|
-
rewardLabel
|
|
1053
|
-
bashPointsAmount Int?
|
|
1054
|
-
sortOrder
|
|
1055
|
-
createdAt
|
|
1056
|
-
updatedAt
|
|
1273
|
+
id String @id @default(cuid())
|
|
1274
|
+
bashEventId String
|
|
1275
|
+
referralCount Int // How many referrals needed for this reward
|
|
1276
|
+
rewardType String // BashPoints, FreeTicket, FreeDrink, Custom
|
|
1277
|
+
rewardLabel String // e.g. "Free drink at the bar"
|
|
1278
|
+
bashPointsAmount Int? // When rewardType=BashPoints
|
|
1279
|
+
sortOrder Int @default(0)
|
|
1280
|
+
createdAt DateTime @default(now())
|
|
1281
|
+
updatedAt DateTime @updatedAt
|
|
1057
1282
|
|
|
1058
1283
|
bashEvent BashEvent @relation(fields: [bashEventId], references: [id], onDelete: Cascade)
|
|
1059
1284
|
|
|
@@ -1062,12 +1287,12 @@ model EventReferralReward {
|
|
|
1062
1287
|
|
|
1063
1288
|
// Tracks referrals: attendee A referred person B who bought a ticket
|
|
1064
1289
|
model EventReferral {
|
|
1065
|
-
id
|
|
1066
|
-
bashEventId
|
|
1067
|
-
referrerId
|
|
1068
|
-
referredUserId
|
|
1069
|
-
ticketId
|
|
1070
|
-
createdAt
|
|
1290
|
+
id String @id @default(cuid())
|
|
1291
|
+
bashEventId String
|
|
1292
|
+
referrerId String // Attendee who shared their link
|
|
1293
|
+
referredUserId String // Person who bought via the link
|
|
1294
|
+
ticketId String? @unique // Ticket purchased (optional, 1:1 with Ticket)
|
|
1295
|
+
createdAt DateTime @default(now())
|
|
1071
1296
|
|
|
1072
1297
|
bashEvent BashEvent @relation(fields: [bashEventId], references: [id], onDelete: Cascade)
|
|
1073
1298
|
referrer User @relation("EventReferralsMade", fields: [referrerId], references: [id], onDelete: Cascade)
|
|
@@ -1081,16 +1306,16 @@ model EventReferral {
|
|
|
1081
1306
|
|
|
1082
1307
|
// Curated event lists for discovery (super-user editorial tool)
|
|
1083
1308
|
model BashList {
|
|
1084
|
-
id
|
|
1085
|
-
title
|
|
1086
|
-
slug
|
|
1087
|
-
description
|
|
1088
|
-
filterConfig
|
|
1089
|
-
isFeatured
|
|
1090
|
-
sortOrder
|
|
1091
|
-
createdById
|
|
1092
|
-
createdAt
|
|
1093
|
-
updatedAt
|
|
1309
|
+
id String @id @default(cuid())
|
|
1310
|
+
title String // e.g. "Best Friday Night in Ogden"
|
|
1311
|
+
slug String @unique // URL-friendly identifier
|
|
1312
|
+
description String? @db.Text
|
|
1313
|
+
filterConfig Json // { dateRange?, city?, state?, eventType?, maxPrice?, ... }
|
|
1314
|
+
isFeatured Boolean @default(false)
|
|
1315
|
+
sortOrder Int @default(0)
|
|
1316
|
+
createdById String
|
|
1317
|
+
createdAt DateTime @default(now())
|
|
1318
|
+
updatedAt DateTime @updatedAt
|
|
1094
1319
|
|
|
1095
1320
|
createdBy User @relation(fields: [createdById], references: [id], onDelete: Cascade)
|
|
1096
1321
|
|
|
@@ -1103,11 +1328,11 @@ model UserItinerary {
|
|
|
1103
1328
|
id String @id @default(cuid())
|
|
1104
1329
|
userId String
|
|
1105
1330
|
date DateTime @db.Date // The night (e.g. 2026-03-15)
|
|
1106
|
-
title String?
|
|
1331
|
+
title String? // e.g. "Friday night out"
|
|
1107
1332
|
createdAt DateTime @default(now())
|
|
1108
1333
|
updatedAt DateTime @updatedAt
|
|
1109
1334
|
|
|
1110
|
-
user User
|
|
1335
|
+
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
1111
1336
|
items UserItineraryItem[]
|
|
1112
1337
|
|
|
1113
1338
|
@@unique([userId, date])
|
|
@@ -1138,15 +1363,15 @@ model Coordinates {
|
|
|
1138
1363
|
}
|
|
1139
1364
|
|
|
1140
1365
|
model Checkout {
|
|
1141
|
-
id String
|
|
1366
|
+
id String @id @default(cuid())
|
|
1142
1367
|
ownerId String
|
|
1143
1368
|
bashEventId String
|
|
1144
|
-
checkoutDateTime DateTime?
|
|
1145
|
-
stripeCheckoutSessionId String?
|
|
1146
|
-
stripePaymentIntentId String?
|
|
1369
|
+
checkoutDateTime DateTime? @default(now())
|
|
1370
|
+
stripeCheckoutSessionId String? @unique
|
|
1371
|
+
stripePaymentIntentId String? @unique
|
|
1147
1372
|
refundedAt DateTime?
|
|
1148
|
-
bashEvent BashEvent
|
|
1149
|
-
owner User
|
|
1373
|
+
bashEvent BashEvent @relation(fields: [bashEventId], references: [id], onDelete: Cascade)
|
|
1374
|
+
owner User @relation(fields: [ownerId], references: [id], onDelete: Cascade)
|
|
1150
1375
|
tickets Ticket[]
|
|
1151
1376
|
appliedDiscounts AppliedDiscount[] // NEW - Discounts applied to this checkout
|
|
1152
1377
|
waiverAcceptances WaiverAcceptance[]
|
|
@@ -1184,13 +1409,13 @@ model BashCreditTransaction {
|
|
|
1184
1409
|
status CreditTransactionStatus @default(Pending)
|
|
1185
1410
|
|
|
1186
1411
|
// Source Tracking (Legacy fields - keeping for backwards compatibility)
|
|
1187
|
-
source
|
|
1188
|
-
referralCode
|
|
1189
|
-
referredUserId
|
|
1190
|
-
referredUser
|
|
1191
|
-
membershipTier
|
|
1192
|
-
description
|
|
1193
|
-
metadata
|
|
1412
|
+
source String // Legacy source field
|
|
1413
|
+
referralCode String?
|
|
1414
|
+
referredUserId String?
|
|
1415
|
+
referredUser User? @relation("ReferredUser", fields: [referredUserId], references: [id])
|
|
1416
|
+
membershipTier MembershipTier?
|
|
1417
|
+
description String?
|
|
1418
|
+
metadata String? // JSON string for additional context
|
|
1194
1419
|
|
|
1195
1420
|
// New Source Tracking
|
|
1196
1421
|
sourceType CreditSourceType?
|
|
@@ -1226,19 +1451,19 @@ model BashCreditTransaction {
|
|
|
1226
1451
|
}
|
|
1227
1452
|
|
|
1228
1453
|
model PendingBashPointsGift {
|
|
1229
|
-
id
|
|
1230
|
-
senderId
|
|
1231
|
-
sender
|
|
1232
|
-
recipientEmail
|
|
1233
|
-
amount
|
|
1234
|
-
message
|
|
1235
|
-
status
|
|
1236
|
-
claimedAt
|
|
1454
|
+
id String @id @default(cuid())
|
|
1455
|
+
senderId String
|
|
1456
|
+
sender User @relation("SentPendingGifts", fields: [senderId], references: [id], onDelete: Cascade)
|
|
1457
|
+
recipientEmail String
|
|
1458
|
+
amount Int
|
|
1459
|
+
message String?
|
|
1460
|
+
status PendingGiftStatus @default(Pending)
|
|
1461
|
+
claimedAt DateTime?
|
|
1237
1462
|
claimedByUserId String?
|
|
1238
|
-
claimedBy
|
|
1239
|
-
returnedAt
|
|
1240
|
-
expiresAt
|
|
1241
|
-
createdAt
|
|
1463
|
+
claimedBy User? @relation("ClaimedPendingGifts", fields: [claimedByUserId], references: [id], onDelete: SetNull)
|
|
1464
|
+
returnedAt DateTime?
|
|
1465
|
+
expiresAt DateTime
|
|
1466
|
+
createdAt DateTime @default(now())
|
|
1242
1467
|
|
|
1243
1468
|
@@index([recipientEmail, status])
|
|
1244
1469
|
@@index([senderId])
|
|
@@ -1369,23 +1594,23 @@ model TicketTier {
|
|
|
1369
1594
|
// Availability rules
|
|
1370
1595
|
availabilityType String @default("Immediate") // "Immediate" | "OnDate" | "EngagedUsersOnly" | "UnlockWhenInterestReached" | "UnlockWhenTicketsSold"
|
|
1371
1596
|
availableAt DateTime? // OnDate: when tier unlocks
|
|
1372
|
-
availableWhenInterestReached
|
|
1373
|
-
unlockWhenTicketsSold Int?
|
|
1374
|
-
maxTicketsPerUser Int?
|
|
1597
|
+
availableWhenInterestReached Int? // UnlockWhenInterestReached: min IdeaInterest count
|
|
1598
|
+
unlockWhenTicketsSold Int? // UnlockWhenTicketsSold: min tickets sold across event to unlock this tier
|
|
1599
|
+
maxTicketsPerUser Int? // Optional per-user purchase cap
|
|
1375
1600
|
|
|
1376
1601
|
// Privacy: "Public" | "LinkOnly" | "InviteOnly"
|
|
1377
|
-
tierPrivacy
|
|
1602
|
+
tierPrivacy String @default("Public")
|
|
1378
1603
|
|
|
1379
1604
|
// Checkout timer: host-configurable per-tier timeout (minutes). null = no timer.
|
|
1380
|
-
checkoutTimeoutMinutes
|
|
1605
|
+
checkoutTimeoutMinutes Int?
|
|
1381
1606
|
|
|
1382
1607
|
/// When true, BashPass subscribers may redeem this tier (subject to caps).
|
|
1383
|
-
bashPassEligible
|
|
1608
|
+
bashPassEligible Boolean @default(false)
|
|
1384
1609
|
/// Max BashPass redemptions for this tier (null = unlimited within tier capacity).
|
|
1385
|
-
bashPassMaxRedemptions
|
|
1610
|
+
bashPassMaxRedemptions Int?
|
|
1611
|
+
ticketGiftGrants TicketGiftGrant[]
|
|
1386
1612
|
|
|
1387
1613
|
@@unique([bashEventId, title])
|
|
1388
|
-
ticketGiftGrants TicketGiftGrant[]
|
|
1389
1614
|
}
|
|
1390
1615
|
|
|
1391
1616
|
enum TicketGiftGrantStatus {
|
|
@@ -1442,7 +1667,9 @@ model Ticket {
|
|
|
1442
1667
|
waitlistJoinedAt DateTime?
|
|
1443
1668
|
waitlistNotifiedAt DateTime?
|
|
1444
1669
|
waitlistExpiresAt DateTime?
|
|
1445
|
-
/**
|
|
1670
|
+
/**
|
|
1671
|
+
* Set when we send the "your waitlist window expires soon" reminder (once per ticket).
|
|
1672
|
+
*/
|
|
1446
1673
|
waitlistReminderSentAt DateTime?
|
|
1447
1674
|
refundRequestedAt DateTime? // Set when RefundPending; cleared once refund processes
|
|
1448
1675
|
checkInLocation String?
|
|
@@ -1472,20 +1699,21 @@ model Ticket {
|
|
|
1472
1699
|
utmMedium String?
|
|
1473
1700
|
utmCampaign String?
|
|
1474
1701
|
|
|
1475
|
-
bashEvent
|
|
1702
|
+
bashEvent BashEvent @relation(fields: [bashEventId], references: [id])
|
|
1476
1703
|
attributedArtistId String?
|
|
1477
|
-
attributedArtist BashEventArtist?
|
|
1478
|
-
checkout
|
|
1479
|
-
forUser
|
|
1480
|
-
invitation
|
|
1481
|
-
owner
|
|
1482
|
-
ticketTier
|
|
1483
|
-
waitlistUser
|
|
1484
|
-
metadata
|
|
1485
|
-
transfers
|
|
1486
|
-
transferInvite
|
|
1487
|
-
appliedDiscounts
|
|
1488
|
-
eventReferral
|
|
1704
|
+
attributedArtist BashEventArtist? @relation(fields: [attributedArtistId], references: [id], onDelete: SetNull)
|
|
1705
|
+
checkout Checkout? @relation(fields: [checkoutId], references: [id])
|
|
1706
|
+
forUser User? @relation("TicketsISent", fields: [forUserId], references: [id])
|
|
1707
|
+
invitation Invitation? @relation("TicketsForInvitation", fields: [invitationId], references: [id])
|
|
1708
|
+
owner User @relation("TicketsIOwn", fields: [ownerId], references: [id])
|
|
1709
|
+
ticketTier TicketTier? @relation(fields: [ticketTierId], references: [id])
|
|
1710
|
+
waitlistUser User? @relation("TicketsOnWaitlist", fields: [waitlistUserId], references: [id])
|
|
1711
|
+
metadata TicketMetadata[]
|
|
1712
|
+
transfers TicketTransfer[]
|
|
1713
|
+
transferInvite TicketTransferInvite?
|
|
1714
|
+
appliedDiscounts AppliedDiscount[] // NEW - Discounts applied to this ticket
|
|
1715
|
+
eventReferral EventReferral? // When this ticket was purchased via a referral link
|
|
1716
|
+
flyerConversions FlyerConversion[]
|
|
1489
1717
|
|
|
1490
1718
|
@@index([bashEventId])
|
|
1491
1719
|
@@index([waitlistUserId])
|
|
@@ -1526,9 +1754,9 @@ model TicketTransferInvite {
|
|
|
1526
1754
|
expiresAt DateTime
|
|
1527
1755
|
createdAt DateTime @default(now())
|
|
1528
1756
|
|
|
1529
|
-
ticket
|
|
1530
|
-
fromUser
|
|
1531
|
-
invitedUser User?
|
|
1757
|
+
ticket Ticket @relation(fields: [ticketId], references: [id], onDelete: Cascade)
|
|
1758
|
+
fromUser User @relation("TicketTransferInviteFrom", fields: [fromUserId], references: [id])
|
|
1759
|
+
invitedUser User? @relation("TicketTransferInviteToUser", fields: [toUserId], references: [id])
|
|
1532
1760
|
|
|
1533
1761
|
@@index([token])
|
|
1534
1762
|
@@index([fromUserId])
|
|
@@ -1593,20 +1821,20 @@ model Recurrence {
|
|
|
1593
1821
|
|
|
1594
1822
|
// Recurring event series: template that spawns many BashEvent instances (e.g. "Every Tuesday 7pm for 14 weeks")
|
|
1595
1823
|
model EventSeries {
|
|
1596
|
-
id String
|
|
1824
|
+
id String @id @default(cuid())
|
|
1597
1825
|
organizationId String?
|
|
1598
1826
|
creatorId String
|
|
1599
1827
|
name String
|
|
1600
|
-
description String?
|
|
1828
|
+
description String? @db.Text
|
|
1601
1829
|
frequency RecurringFrequency
|
|
1602
|
-
interval Int
|
|
1830
|
+
interval Int @default(1)
|
|
1603
1831
|
repeatOnDays DayOfWeek[]
|
|
1604
1832
|
seriesStart DateTime
|
|
1605
1833
|
seriesEnd DateTime
|
|
1606
|
-
exceptions Json?
|
|
1607
|
-
templateConfig Json?
|
|
1608
|
-
createdAt DateTime
|
|
1609
|
-
updatedAt DateTime
|
|
1834
|
+
exceptions Json? // Array of ISO date strings to skip
|
|
1835
|
+
templateConfig Json? // Event defaults: title pattern, ticketTiers, etc.
|
|
1836
|
+
createdAt DateTime @default(now())
|
|
1837
|
+
updatedAt DateTime @updatedAt
|
|
1610
1838
|
|
|
1611
1839
|
organization Organization? @relation("OrganizationEventSeries", fields: [organizationId], references: [id], onDelete: SetNull)
|
|
1612
1840
|
creator User @relation("EventSeriesCreator", fields: [creatorId], references: [id], onDelete: Restrict)
|
|
@@ -1655,21 +1883,28 @@ model BashEventTemplate {
|
|
|
1655
1883
|
|
|
1656
1884
|
// Used by BashEvent (amountOfGuests) and by Services (crowdSizeId/crowdSize); same model, different relation names.
|
|
1657
1885
|
model AmountOfGuests {
|
|
1658
|
-
id
|
|
1659
|
-
minimum
|
|
1660
|
-
ideal
|
|
1661
|
-
expected
|
|
1662
|
-
showMinimumGuests
|
|
1663
|
-
showIdealGuests
|
|
1664
|
-
showExpectedGuests
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1886
|
+
id String @id @default(cuid())
|
|
1887
|
+
minimum Int? @default(10)
|
|
1888
|
+
ideal Int? @default(35)
|
|
1889
|
+
expected Int? @default(25)
|
|
1890
|
+
showMinimumGuests Boolean @default(true)
|
|
1891
|
+
showIdealGuests Boolean @default(true)
|
|
1892
|
+
showExpectedGuests Boolean @default(true)
|
|
1893
|
+
maximum Int?
|
|
1894
|
+
showMaximumGuests Boolean @default(false)
|
|
1895
|
+
autoCancelIfMinNotMet Boolean @default(false)
|
|
1896
|
+
autoPublicWhenMinMet Boolean @default(false)
|
|
1897
|
+
makePrivateAtMax Boolean @default(false)
|
|
1898
|
+
allowWaitlistAtMax Boolean @default(false)
|
|
1899
|
+
aimingForMaxCapacity Boolean @default(false)
|
|
1900
|
+
venueId String?
|
|
1901
|
+
organizationId String?
|
|
1902
|
+
bashEvent BashEvent?
|
|
1903
|
+
entertainmentService EntertainmentService?
|
|
1904
|
+
eventService EventService?
|
|
1905
|
+
exhibitor Exhibitor?
|
|
1906
|
+
sponsor Sponsor?
|
|
1907
|
+
vendor Vendor?
|
|
1673
1908
|
}
|
|
1674
1909
|
|
|
1675
1910
|
model TargetAudience {
|
|
@@ -1795,19 +2030,19 @@ model Prize {
|
|
|
1795
2030
|
}
|
|
1796
2031
|
|
|
1797
2032
|
model Review {
|
|
1798
|
-
id
|
|
1799
|
-
rating
|
|
1800
|
-
creatorId
|
|
1801
|
-
bashEventId
|
|
1802
|
-
createdAt
|
|
1803
|
-
updatedAt
|
|
2033
|
+
id String @id @default(cuid())
|
|
2034
|
+
rating Int
|
|
2035
|
+
creatorId String
|
|
2036
|
+
bashEventId String
|
|
2037
|
+
createdAt DateTime @default(now())
|
|
2038
|
+
updatedAt DateTime @updatedAt
|
|
1804
2039
|
/// Public reply from the event host (service provider) to the reviewer.
|
|
1805
|
-
hostReplyText String?
|
|
2040
|
+
hostReplyText String? @db.Text
|
|
1806
2041
|
hostReplyAt DateTime?
|
|
1807
|
-
comments
|
|
1808
|
-
bashEvent
|
|
1809
|
-
creator
|
|
1810
|
-
helpfulVotes
|
|
2042
|
+
comments BashComment[]
|
|
2043
|
+
bashEvent BashEvent @relation(fields: [bashEventId], references: [id], onDelete: Cascade)
|
|
2044
|
+
creator User @relation(fields: [creatorId], references: [id], onDelete: Cascade)
|
|
2045
|
+
helpfulVotes ReviewHelpfulVote[]
|
|
1811
2046
|
|
|
1812
2047
|
@@unique([creatorId, bashEventId])
|
|
1813
2048
|
}
|
|
@@ -1891,7 +2126,7 @@ model User {
|
|
|
1891
2126
|
isSuperUser Boolean @default(false)
|
|
1892
2127
|
isSuspended Boolean @default(false)
|
|
1893
2128
|
intent UserIntent?
|
|
1894
|
-
signupSource String?
|
|
2129
|
+
signupSource String? // e.g. 'jamwith', 'mixlog', 'organic' for attribution
|
|
1895
2130
|
googleCalendarAccess String?
|
|
1896
2131
|
|
|
1897
2132
|
// Google OAuth tokens for API access (Contacts, Calendar, etc.)
|
|
@@ -1900,123 +2135,148 @@ model User {
|
|
|
1900
2135
|
googleTokenExpiry DateTime?
|
|
1901
2136
|
|
|
1902
2137
|
// LinkedIn OAuth tokens for UGC posting (w_member_social scope)
|
|
1903
|
-
linkedinAccessToken
|
|
1904
|
-
linkedinTokenExpiry
|
|
1905
|
-
linkedinPersonId
|
|
1906
|
-
linkedinVanityUrl
|
|
1907
|
-
linkedinHeadline
|
|
1908
|
-
|
|
1909
|
-
givenName
|
|
1910
|
-
familyName
|
|
1911
|
-
nameChangeCount
|
|
1912
|
-
hash
|
|
1913
|
-
previousPasswordHashes
|
|
1914
|
-
emailVerified
|
|
1915
|
-
image
|
|
1916
|
-
imageUpdatedAt
|
|
1917
|
-
uploadedImage
|
|
1918
|
-
uploadedImageUpdatedAt
|
|
1919
|
-
dob
|
|
1920
|
-
showBirthdayOnProfile
|
|
2138
|
+
linkedinAccessToken String?
|
|
2139
|
+
linkedinTokenExpiry DateTime?
|
|
2140
|
+
linkedinPersonId String? // LinkedIn `sub` / person URN
|
|
2141
|
+
linkedinVanityUrl String? // e.g. "stevegoodrick" → linkedin.com/in/stevegoodrick
|
|
2142
|
+
linkedinHeadline String? // e.g. "Founder at The Bash App"
|
|
2143
|
+
|
|
2144
|
+
givenName String?
|
|
2145
|
+
familyName String?
|
|
2146
|
+
nameChangeCount Int @default(0)
|
|
2147
|
+
hash String?
|
|
2148
|
+
previousPasswordHashes String[] @default([]) // Last 5 bcrypt hashes (oldest first) for password-reuse prevention
|
|
2149
|
+
emailVerified DateTime?
|
|
2150
|
+
image String?
|
|
2151
|
+
imageUpdatedAt DateTime? // When Google/OAuth image was last updated
|
|
2152
|
+
uploadedImage String?
|
|
2153
|
+
uploadedImageUpdatedAt DateTime? // When manually uploaded image was last updated
|
|
2154
|
+
dob DateTime?
|
|
2155
|
+
showBirthdayOnProfile Boolean @default(false) // If true, show month/day on public profile
|
|
1921
2156
|
// Part B: Birthday Rewards full product
|
|
1922
|
-
birthdayRewardsOptIn
|
|
1923
|
-
birthdayRewardsOptInAt
|
|
1924
|
-
birthdayLocationId
|
|
1925
|
-
birthdayMaxDistanceMiles
|
|
1926
|
-
birthdayNoPurchaseOnly
|
|
2157
|
+
birthdayRewardsOptIn Boolean @default(false)
|
|
2158
|
+
birthdayRewardsOptInAt DateTime?
|
|
2159
|
+
birthdayLocationId String? // FK UserLocation (birthday home base)
|
|
2160
|
+
birthdayMaxDistanceMiles Int @default(25)
|
|
2161
|
+
birthdayNoPurchaseOnly Boolean @default(false)
|
|
1927
2162
|
/// Email reminder N days before birthday (birthday rewards plan nudge)
|
|
1928
|
-
birthdayReminderEnabled
|
|
1929
|
-
birthdayReminderDaysAdvance
|
|
1930
|
-
birthdayCategories
|
|
2163
|
+
birthdayReminderEnabled Boolean @default(true)
|
|
2164
|
+
birthdayReminderDaysAdvance Int @default(7)
|
|
2165
|
+
birthdayCategories String[] @default([]) // e.g. restaurant, coffee, dessert
|
|
1931
2166
|
/// Calendar year when we last sent the "your birthday month freebies" reminder (cron on 1st of month).
|
|
1932
|
-
birthdayMonthReminderSentYear
|
|
1933
|
-
idDocumentUrl
|
|
1934
|
-
gender
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
2167
|
+
birthdayMonthReminderSentYear Int?
|
|
2168
|
+
idDocumentUrl String? // Optional: secure ID upload for verification
|
|
2169
|
+
gender Gender?
|
|
2170
|
+
/// Free-text self-described gender. Takes precedence over `gender` when present.
|
|
2171
|
+
genderIdentity String?
|
|
2172
|
+
sex Sex?
|
|
2173
|
+
/// Public-profile visibility flags for self-reported demographics
|
|
2174
|
+
showAgeOnProfile Boolean @default(true)
|
|
2175
|
+
showGenderOnProfile Boolean @default(true)
|
|
2176
|
+
/// Master visibility toggle for ID/Payment/Host/Student trust badges
|
|
2177
|
+
showVerifiedBadgesOnProfile Boolean @default(true)
|
|
2178
|
+
organization String?
|
|
2179
|
+
jobTitle String?
|
|
2180
|
+
roles UserRole[] @default([User])
|
|
2181
|
+
aboutMe String?
|
|
2182
|
+
levelBadge String?
|
|
2183
|
+
temporaryBadges String[] @default([])
|
|
2184
|
+
status UserStatus
|
|
2185
|
+
hostRating Float?
|
|
2186
|
+
totalRatings Int?
|
|
2187
|
+
totalEventsHosted Int? @default(0) // Total published/completed events hosted
|
|
2188
|
+
totalAttendeesHosted Int? @default(0) // Total checked-in attendees across all events
|
|
2189
|
+
totalBookingsAccepted Int? @default(0) // Service provider stat
|
|
2190
|
+
totalBookingsCompleted Int? @default(0) // Service provider stat
|
|
2191
|
+
magicLink String?
|
|
2192
|
+
magicLinkExpiration DateTime?
|
|
2193
|
+
hostNumber Int?
|
|
2194
|
+
foundingHostBadgeAwarded Boolean @default(false)
|
|
2195
|
+
firstBashWithAttendeesDate DateTime?
|
|
2196
|
+
bashesCreatedCount Int @default(0)
|
|
2197
|
+
bashesPublishedCount Int @default(0)
|
|
2198
|
+
bashesApprovedCount Int @default(0)
|
|
2199
|
+
bashesCompletedCount Int @default(0)
|
|
2200
|
+
magicLinkUsed DateTime?
|
|
2201
|
+
idVerified DateTime?
|
|
2202
|
+
street String?
|
|
2203
|
+
city String?
|
|
2204
|
+
state String?
|
|
2205
|
+
zipCode String?
|
|
2206
|
+
country String? @default("US")
|
|
2207
|
+
phone String?
|
|
2208
|
+
documentIDId String? @unique
|
|
2209
|
+
/// Encrypted-S3 key for the user's stored government-ID image (deleted per retention policy / on ID expiration)
|
|
2210
|
+
govIdImageS3Key String?
|
|
2211
|
+
/// When the gov-ID image becomes deletable (null = "indefinite, until I remove it").
|
|
2212
|
+
/// Indexed via a Postgres PARTIAL index for the expireIdImages cron — see
|
|
2213
|
+
/// migrations/20260418061500_index_gov_id_image_expires_at. Prisma does
|
|
2214
|
+
/// not support partial indexes declaratively, so the index is SQL-only.
|
|
2215
|
+
govIdImageExpiresAt DateTime?
|
|
2216
|
+
/// Retention policy for the stored gov-ID image (drives expireIdImages cron)
|
|
2217
|
+
govIdRetentionPolicy GovIdRetentionPolicy?
|
|
2218
|
+
/// GDPR Art. 7 audit trail for retention-policy consent
|
|
2219
|
+
govIdRetentionConsentedAt DateTime?
|
|
2220
|
+
/// Encrypted-S3 key for the user's stored student-ID image (no OCR; school inferred via vision model)
|
|
2221
|
+
studentIdImageS3Key String?
|
|
2222
|
+
studentIdUploadedAt DateTime?
|
|
2223
|
+
/// School/university name extracted from student-ID by vision model; user-editable.
|
|
2224
|
+
schoolName String?
|
|
2225
|
+
/// Whether `schoolName` came from the AI vision model or was edited by the user
|
|
2226
|
+
schoolNameSource SchoolNameSource?
|
|
2227
|
+
accepted Boolean? @default(false)
|
|
2228
|
+
boughtTicket Boolean? @default(false)
|
|
2229
|
+
noPay Boolean? @default(false)
|
|
2230
|
+
supportedEvent Boolean? @default(false)
|
|
2231
|
+
suspendedUntil DateTime?
|
|
2232
|
+
suspendedById String?
|
|
2233
|
+
isLightweightAccount Boolean @default(false)
|
|
2234
|
+
notifyForTrendingBashes Boolean @default(false)
|
|
2235
|
+
trendingBashThreshold Int @default(10)
|
|
2236
|
+
artistsToSee String[] @default([])
|
|
2237
|
+
googleCalendarSyncSettings String?
|
|
2238
|
+
membershipTier MembershipTier @default(Basic)
|
|
2239
|
+
membershipExpiresAt DateTime?
|
|
2240
|
+
membershipAutoRenew Boolean @default(false)
|
|
2241
|
+
membershipBillingInterval String?
|
|
2242
|
+
membershipLastBilledAt DateTime?
|
|
2243
|
+
membershipFeaturedEventsUsed Int @default(0)
|
|
2244
|
+
membershipStripeSubscriptionId String? @unique
|
|
1985
2245
|
/// Optional consumer BashPass subscription (waives guest platform fee on tickets; monthly BashPoints).
|
|
1986
|
-
bashPassStripeSubscriptionId
|
|
1987
|
-
bashPassCurrentPeriodEnd
|
|
2246
|
+
bashPassStripeSubscriptionId String? @unique
|
|
2247
|
+
bashPassCurrentPeriodEnd DateTime?
|
|
1988
2248
|
/// Stripe price tier for standalone BashPass; effective tier may also come from membership bundle.
|
|
1989
|
-
bashPassTier
|
|
1990
|
-
bashPassEventsUsedThisMonth
|
|
1991
|
-
bashPassMonthlyCapResetAt
|
|
1992
|
-
isVerified
|
|
1993
|
-
verificationMethod
|
|
1994
|
-
verifiedAt
|
|
1995
|
-
verificationScore
|
|
2249
|
+
bashPassTier BashPassTier?
|
|
2250
|
+
bashPassEventsUsedThisMonth Int @default(0)
|
|
2251
|
+
bashPassMonthlyCapResetAt DateTime?
|
|
2252
|
+
isVerified Boolean @default(false)
|
|
2253
|
+
verificationMethod String?
|
|
2254
|
+
verifiedAt DateTime?
|
|
2255
|
+
verificationScore Int @default(0)
|
|
1996
2256
|
/// $1 card verification (Stripe) — distinct from Stripe Identity / isVerified
|
|
1997
|
-
paymentVerified
|
|
1998
|
-
paymentVerifiedAt
|
|
2257
|
+
paymentVerified Boolean @default(false)
|
|
2258
|
+
paymentVerifiedAt DateTime?
|
|
1999
2259
|
/// One-time BashPoints bonus after $1 verification payment succeeded
|
|
2000
|
-
paymentVerificationBonusAwarded Boolean
|
|
2001
|
-
biometricFingerprint
|
|
2002
|
-
venmoUsername
|
|
2003
|
-
venmoQRCodeUrl
|
|
2004
|
-
zelleEmail
|
|
2260
|
+
paymentVerificationBonusAwarded Boolean @default(false)
|
|
2261
|
+
biometricFingerprint String?
|
|
2262
|
+
venmoUsername String?
|
|
2263
|
+
venmoQRCodeUrl String?
|
|
2264
|
+
zelleEmail String?
|
|
2005
2265
|
/// Optional Venmo / Zelle / CashApp handle shown to hosts (promo requests, code assignment). Bash does not move money.
|
|
2006
|
-
paymentHandle
|
|
2007
|
-
zellePhone
|
|
2008
|
-
zelleQRCodeUrl
|
|
2009
|
-
isAmbashador
|
|
2010
|
-
ambashadorAwardedAt
|
|
2011
|
-
isBashInsider
|
|
2012
|
-
insiderAwardedAt
|
|
2013
|
-
scoutTier
|
|
2014
|
-
scoutAwardedAt
|
|
2015
|
-
agentAwardedAt
|
|
2016
|
-
totalServiceReferrals
|
|
2017
|
-
isFirstInCity
|
|
2018
|
-
firstInCityAt
|
|
2019
|
-
fcmTokens
|
|
2266
|
+
paymentHandle String?
|
|
2267
|
+
zellePhone String?
|
|
2268
|
+
zelleQRCodeUrl String?
|
|
2269
|
+
isAmbashador Boolean @default(false)
|
|
2270
|
+
ambashadorAwardedAt DateTime?
|
|
2271
|
+
isBashInsider Boolean @default(false)
|
|
2272
|
+
insiderAwardedAt DateTime?
|
|
2273
|
+
scoutTier ScoutTier @default(None)
|
|
2274
|
+
scoutAwardedAt DateTime?
|
|
2275
|
+
agentAwardedAt DateTime?
|
|
2276
|
+
totalServiceReferrals Int @default(0)
|
|
2277
|
+
isFirstInCity Boolean @default(false)
|
|
2278
|
+
firstInCityAt DateTime?
|
|
2279
|
+
fcmTokens String[] @default([]) // Firebase Cloud Messaging tokens for push notifications
|
|
2020
2280
|
|
|
2021
2281
|
// BashPoints System Fields
|
|
2022
2282
|
bashPointsBalance Int @default(0)
|
|
@@ -2027,48 +2287,49 @@ model User {
|
|
|
2027
2287
|
referralPurchaseCredited Boolean @default(false)
|
|
2028
2288
|
|
|
2029
2289
|
// Security Fields
|
|
2030
|
-
accountLockedUntil
|
|
2031
|
-
revokedTokens
|
|
2032
|
-
auditLogs
|
|
2033
|
-
auditLogsPerformed
|
|
2034
|
-
consents
|
|
2035
|
-
birthdayOfferOptIns
|
|
2036
|
-
birthdayOfferDeliveries
|
|
2037
|
-
birthdayBoostGrants
|
|
2038
|
-
birthdayRewardRedemptions
|
|
2039
|
-
birthdayRewardFavorites
|
|
2040
|
-
birthdayDealSuggestions
|
|
2290
|
+
accountLockedUntil DateTime? // Account lockout timestamp for failed login protection
|
|
2291
|
+
revokedTokens RevokedToken[] @relation("RevokedTokens") // Revoked JWT tokens
|
|
2292
|
+
auditLogs AuditLog[] @relation("UserAuditLogs")
|
|
2293
|
+
auditLogsPerformed AuditLog[] @relation("PerformedByUser")
|
|
2294
|
+
consents UserConsent[]
|
|
2295
|
+
birthdayOfferOptIns UserBirthdayOfferOptIn[]
|
|
2296
|
+
birthdayOfferDeliveries BirthdayOfferDelivery[]
|
|
2297
|
+
birthdayBoostGrants BirthdayBoostGrant[]
|
|
2298
|
+
birthdayRewardRedemptions BirthdayRewardRedemption[]
|
|
2299
|
+
birthdayRewardFavorites BirthdayRewardFavorite[]
|
|
2300
|
+
birthdayDealSuggestions BirthdayDealSuggestion[]
|
|
2041
2301
|
birthdayCityResourceSuggestions BirthdayCityResourceSuggestion[]
|
|
2042
|
-
rewardReports
|
|
2043
|
-
birthdayFreebieVotes
|
|
2044
|
-
rewardReportsReviewed
|
|
2045
|
-
nationalChainReports
|
|
2046
|
-
nationalChainReportsReviewed
|
|
2047
|
-
userLocations
|
|
2048
|
-
birthdayLocation
|
|
2049
|
-
offerClaims
|
|
2050
|
-
birthdayPlans
|
|
2051
|
-
birthdayFreebiesSavedPlan
|
|
2302
|
+
rewardReports RewardReport[]
|
|
2303
|
+
birthdayFreebieVotes BirthdayFreebieVote[]
|
|
2304
|
+
rewardReportsReviewed RewardReport[] @relation("RewardReportReviewedBy")
|
|
2305
|
+
nationalChainReports NationalChainReport[]
|
|
2306
|
+
nationalChainReportsReviewed NationalChainReport[] @relation("NationalChainReportReviewedBy")
|
|
2307
|
+
userLocations UserLocation[]
|
|
2308
|
+
birthdayLocation UserLocation? @relation("UserBirthdayLocation", fields: [birthdayLocationId], references: [id], onDelete: SetNull)
|
|
2309
|
+
offerClaims OfferClaim[]
|
|
2310
|
+
birthdayPlans BirthdayPlan[]
|
|
2311
|
+
birthdayFreebiesSavedPlan BirthdayFreebiesSavedPlan?
|
|
2052
2312
|
|
|
2053
2313
|
associatedBashes AssociatedBash[]
|
|
2054
2314
|
associatedServices AssociatedService[]
|
|
2055
2315
|
comment BashComment[]
|
|
2056
|
-
referredTransactions BashCreditTransaction[]
|
|
2316
|
+
referredTransactions BashCreditTransaction[] @relation("ReferredUser")
|
|
2057
2317
|
creditTransactions BashCreditTransaction[]
|
|
2058
|
-
createdEvents BashEvent[]
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2318
|
+
createdEvents BashEvent[] @relation("CreatedEvent")
|
|
2319
|
+
flyerCampaigns FlyerCampaign[]
|
|
2320
|
+
bashEventsTransferredFrom BashEvent[] @relation("TransferredFrom")
|
|
2321
|
+
bashEventsPayoutRecipient BashEvent[] @relation("BashEventsPayoutRecipient")
|
|
2322
|
+
bashEventMessagesSent BashEventMessage[] @relation("BashMessageSender")
|
|
2323
|
+
bashEventMessagesRead BashEventMessageRead[] @relation("BashMessageReader")
|
|
2324
|
+
transferRequestsFrom BashEventTransferRequest[] @relation("TransferRequestsFrom")
|
|
2325
|
+
transferRequestsTo BashEventTransferRequest[] @relation("TransferRequestsTo")
|
|
2326
|
+
sentPendingGifts PendingBashPointsGift[] @relation("SentPendingGifts")
|
|
2327
|
+
claimedPendingGifts PendingBashPointsGift[] @relation("ClaimedPendingGifts")
|
|
2067
2328
|
biometricCredentials BiometricCredential[]
|
|
2068
|
-
blocksReceived BlockedUser[]
|
|
2069
|
-
blocksCreated BlockedUser[]
|
|
2070
|
-
blogComments BlogComment[]
|
|
2071
|
-
blogPosts BlogPost[]
|
|
2329
|
+
blocksReceived BlockedUser[] @relation("UserBlocksReceived")
|
|
2330
|
+
blocksCreated BlockedUser[] @relation("UserBlocksMade")
|
|
2331
|
+
blogComments BlogComment[] @relation("BlogCommentAuthor")
|
|
2332
|
+
blogPosts BlogPost[] @relation("BlogAuthor")
|
|
2072
2333
|
checkouts Checkout[]
|
|
2073
2334
|
waiverAcceptances WaiverAcceptance[]
|
|
2074
2335
|
clubAdmins ClubAdmin[]
|
|
@@ -2077,90 +2338,90 @@ model User {
|
|
|
2077
2338
|
competitionSponsorships CompetitionSponsor[]
|
|
2078
2339
|
competitionParticipations CompetitionParticipant[]
|
|
2079
2340
|
competitionVotes CompetitionVote[]
|
|
2080
|
-
competitionJudgeAssignments
|
|
2081
|
-
competitionJudgeScoresAuthored CompetitionJudgeScore[]
|
|
2341
|
+
competitionJudgeAssignments CompetitionJudgeAssignment[] @relation("CompetitionJudgeAssignments")
|
|
2342
|
+
competitionJudgeScoresAuthored CompetitionJudgeScore[] @relation("CompetitionJudgeScoresAuthored")
|
|
2082
2343
|
contacts Contact[]
|
|
2083
|
-
contactLists ContactList[]
|
|
2344
|
+
contactLists ContactList[] @relation("UserContactLists")
|
|
2084
2345
|
contactlist ContactList[]
|
|
2085
|
-
expungedDemerits Demerit[]
|
|
2086
|
-
issuedDemerits Demerit[]
|
|
2087
|
-
demerits Demerit[]
|
|
2346
|
+
expungedDemerits Demerit[] @relation("ExpungedDemerits")
|
|
2347
|
+
issuedDemerits Demerit[] @relation("IssuedDemerits")
|
|
2348
|
+
demerits Demerit[] @relation("UserDemerits")
|
|
2088
2349
|
documentID DocumentID?
|
|
2089
|
-
eventTasksAssignedToMe EventTask[]
|
|
2350
|
+
eventTasksAssignedToMe EventTask[] @relation("TasksAssignedToMe")
|
|
2090
2351
|
eventTasks EventTask[]
|
|
2091
|
-
potluckItemsClaimed PotluckItem[]
|
|
2092
|
-
bashEventSuggestionsCreated BashEventSuggestion[]
|
|
2093
|
-
bashSuggestionUpvotes SuggestionUpvote[]
|
|
2094
|
-
itemUpvotesGiven ItemUpvote[]
|
|
2095
|
-
taskCommentsAuthored TaskComment[]
|
|
2096
|
-
taskInvitationsSent TaskInvitation[]
|
|
2097
|
-
taskInvitationsAccepted TaskInvitation[]
|
|
2098
|
-
exhibitorBookingRequestsAsHost ExhibitorBookingRequest[]
|
|
2352
|
+
potluckItemsClaimed PotluckItem[] @relation("PotluckItemsClaimedBy")
|
|
2353
|
+
bashEventSuggestionsCreated BashEventSuggestion[] @relation("BashEventSuggestionsCreated")
|
|
2354
|
+
bashSuggestionUpvotes SuggestionUpvote[] @relation("BashSuggestionUpvotes")
|
|
2355
|
+
itemUpvotesGiven ItemUpvote[] @relation("ItemUpvotesGiven")
|
|
2356
|
+
taskCommentsAuthored TaskComment[] @relation("TaskCommentsAuthored")
|
|
2357
|
+
taskInvitationsSent TaskInvitation[] @relation("TaskInvitationsSent")
|
|
2358
|
+
taskInvitationsAccepted TaskInvitation[] @relation("TaskInvitationsAccepted")
|
|
2359
|
+
exhibitorBookingRequestsAsHost ExhibitorBookingRequest[] @relation("ExhibitorBookingHost")
|
|
2099
2360
|
investments Investment[]
|
|
2100
|
-
invitationsCreatedByMe Invitation[]
|
|
2101
|
-
invitationsSentToMe Invitation[]
|
|
2102
|
-
notificationsCreatedByMe Notification[]
|
|
2103
|
-
notification Notification[]
|
|
2361
|
+
invitationsCreatedByMe Invitation[] @relation("InvitationsCreatedByMe")
|
|
2362
|
+
invitationsSentToMe Invitation[] @relation("InvitationsSentToMe")
|
|
2363
|
+
notificationsCreatedByMe Notification[] @relation("NotificationsCreatedByMe")
|
|
2364
|
+
notification Notification[] @relation("NotificationsReceivedByMe")
|
|
2104
2365
|
competitionPrizes Prize[]
|
|
2105
2366
|
promoter Promoter[]
|
|
2106
2367
|
promoterStats PromoterStats?
|
|
2107
|
-
remindersCreatedByMe Reminder[]
|
|
2108
|
-
remindersAssignedToMe Reminder[]
|
|
2368
|
+
remindersCreatedByMe Reminder[] @relation("RemindersCreatedByMe")
|
|
2369
|
+
remindersAssignedToMe Reminder[] @relation("RemindersAssignedToMe")
|
|
2109
2370
|
sentReminders SentReminder[]
|
|
2110
2371
|
reviews Review[]
|
|
2111
2372
|
firstFreeListingId String?
|
|
2112
|
-
createdServices Service[]
|
|
2113
|
-
ownedServices Service[]
|
|
2114
|
-
serviceBlocksReceived ServiceBlock[]
|
|
2115
|
-
serviceBlocksMade ServiceBlock[]
|
|
2116
|
-
serviceBookingForCreator ServiceBooking[]
|
|
2117
|
-
serviceBookingForUser ServiceBooking[]
|
|
2373
|
+
createdServices Service[] @relation("CreatedService")
|
|
2374
|
+
ownedServices Service[] @relation("OwnedService")
|
|
2375
|
+
serviceBlocksReceived ServiceBlock[] @relation("ServiceBlocksReceived")
|
|
2376
|
+
serviceBlocksMade ServiceBlock[] @relation("ServiceBlocksMade")
|
|
2377
|
+
serviceBookingForCreator ServiceBooking[] @relation("BookingCreator")
|
|
2378
|
+
serviceBookingForUser ServiceBooking[] @relation("BookingForUser")
|
|
2118
2379
|
serviceBookingCheckout ServiceBookingCheckout[]
|
|
2119
|
-
serviceBookingMessages ServiceBookingMessage[]
|
|
2380
|
+
serviceBookingMessages ServiceBookingMessage[] @relation("ServiceMessageSender")
|
|
2120
2381
|
sessions Session[]
|
|
2121
2382
|
socialMediaProfiles SocialMediaProfile[]
|
|
2122
|
-
sponsorBookingRequestsAsHost SponsorBookingRequest[]
|
|
2383
|
+
sponsorBookingRequestsAsHost SponsorBookingRequest[] @relation("SponsorBookingHost")
|
|
2123
2384
|
sponsorships SponsoredEvent[]
|
|
2124
2385
|
stripeAccounts StripeAccount[]
|
|
2125
|
-
ticketsISent Ticket[]
|
|
2126
|
-
ticketsIOwn Ticket[]
|
|
2386
|
+
ticketsISent Ticket[] @relation("TicketsISent")
|
|
2387
|
+
ticketsIOwn Ticket[] @relation("TicketsIOwn")
|
|
2127
2388
|
bashEventDonations BashEventDonation[]
|
|
2128
2389
|
bashCreativeSubmissions BashCreativeSubmission[]
|
|
2129
|
-
ticketsOnWaitlist Ticket[]
|
|
2130
|
-
transfersFrom TicketTransfer[]
|
|
2131
|
-
transfersTo TicketTransfer[]
|
|
2132
|
-
ticketTransferInvitesFrom TicketTransferInvite[]
|
|
2133
|
-
ticketTransferInvitesToUser TicketTransferInvite[]
|
|
2134
|
-
giftGrantsIssued TicketGiftGrant[]
|
|
2135
|
-
giftGrantsReceived TicketGiftGrant[]
|
|
2136
|
-
unblocksReceived UnblockedUserHistory[]
|
|
2137
|
-
unblocksCreated UnblockedUserHistory[]
|
|
2138
|
-
suspendedBy User?
|
|
2139
|
-
suspendedUsers User[]
|
|
2390
|
+
ticketsOnWaitlist Ticket[] @relation("TicketsOnWaitlist")
|
|
2391
|
+
transfersFrom TicketTransfer[] @relation("TransfersFrom")
|
|
2392
|
+
transfersTo TicketTransfer[] @relation("TransfersTo")
|
|
2393
|
+
ticketTransferInvitesFrom TicketTransferInvite[] @relation("TicketTransferInviteFrom")
|
|
2394
|
+
ticketTransferInvitesToUser TicketTransferInvite[] @relation("TicketTransferInviteToUser")
|
|
2395
|
+
giftGrantsIssued TicketGiftGrant[] @relation("GiftGrantsIssued")
|
|
2396
|
+
giftGrantsReceived TicketGiftGrant[] @relation("GiftGrantsReceived")
|
|
2397
|
+
unblocksReceived UnblockedUserHistory[] @relation("UserUnblocksReceived")
|
|
2398
|
+
unblocksCreated UnblockedUserHistory[] @relation("UserUnblocksMade")
|
|
2399
|
+
suspendedBy User? @relation("SuspendedUsers", fields: [suspendedById], references: [id])
|
|
2400
|
+
suspendedUsers User[] @relation("SuspendedUsers")
|
|
2140
2401
|
favorites UserFavorite[]
|
|
2141
2402
|
publicBashRsvps PublicBashRsvp[]
|
|
2142
|
-
following UserFollowing[]
|
|
2143
|
-
followers UserFollowing[]
|
|
2144
|
-
connectionRequestsSent UserConnection[]
|
|
2145
|
-
connectionRequestsReceived UserConnection[]
|
|
2403
|
+
following UserFollowing[] @relation("Follower")
|
|
2404
|
+
followers UserFollowing[] @relation("Following")
|
|
2405
|
+
connectionRequestsSent UserConnection[] @relation("ConnectionRequestsSent")
|
|
2406
|
+
connectionRequestsReceived UserConnection[] @relation("ConnectionRequestsReceived")
|
|
2146
2407
|
links UserLink[]
|
|
2147
2408
|
preferences UserPreferences?
|
|
2148
2409
|
rankings UserRankings?
|
|
2149
2410
|
userPromoCodeRedemption UserPromoCodeRedemption[]
|
|
2150
2411
|
venueLoyaltyRedemptions VenueLoyaltyRedemption[]
|
|
2151
2412
|
referralCode UserReferralCode?
|
|
2152
|
-
referralTokens UserReferralToken[]
|
|
2153
|
-
reportsReceived UserReport[]
|
|
2154
|
-
reportsMade UserReport[]
|
|
2155
|
-
reportsReviewed UserReport[]
|
|
2413
|
+
referralTokens UserReferralToken[] @relation("UserReferralTokens")
|
|
2414
|
+
reportsReceived UserReport[] @relation("ReportsReceived")
|
|
2415
|
+
reportsMade UserReport[] @relation("ReportsMade")
|
|
2416
|
+
reportsReviewed UserReport[] @relation("ReportsReviewed")
|
|
2156
2417
|
userStats UserStats?
|
|
2157
2418
|
userSubscription UserSubscription?
|
|
2158
2419
|
vendorBid VendorBid[]
|
|
2159
|
-
vendorBookingMessages VendorBookingMessage[]
|
|
2420
|
+
vendorBookingMessages VendorBookingMessage[] @relation("VendorMessageSender")
|
|
2160
2421
|
serviceAnalytics ServiceAnalytics[] // Track service analytics for this user
|
|
2161
|
-
vendorBookingRequestsAsHost VendorBookingRequest[]
|
|
2422
|
+
vendorBookingRequestsAsHost VendorBookingRequest[] @relation("VendorBookingHost")
|
|
2162
2423
|
volunteerService VolunteerService[]
|
|
2163
|
-
reviewedAmbashadorApps AmbashadorApplication[]
|
|
2424
|
+
reviewedAmbashadorApps AmbashadorApplication[] @relation("AmbashadorReviewer")
|
|
2164
2425
|
|
|
2165
2426
|
// Claiming Relations
|
|
2166
2427
|
claimRequests ClaimRequest[] @relation("EventClaims")
|
|
@@ -2235,8 +2496,8 @@ model User {
|
|
|
2235
2496
|
bashAvailability BashAvailability? @relation("UserAvailability")
|
|
2236
2497
|
|
|
2237
2498
|
// Groups
|
|
2238
|
-
ownedGroups
|
|
2239
|
-
groupMembers
|
|
2499
|
+
ownedGroups EventGroup[] @relation("OwnedGroups")
|
|
2500
|
+
groupMembers GroupMember[] @relation("GroupMemberships")
|
|
2240
2501
|
|
|
2241
2502
|
// Vanity paths
|
|
2242
2503
|
requestedVanityPaths EventVanityPath[] @relation("VanityRequests")
|
|
@@ -2307,9 +2568,9 @@ model UserPreferences {
|
|
|
2307
2568
|
showEventPrices Boolean @default(true)
|
|
2308
2569
|
|
|
2309
2570
|
// BashFeed Preferences
|
|
2310
|
-
bashFeedDefaultTab
|
|
2311
|
-
bashFeedDefaultSort
|
|
2312
|
-
bashFeedFilters
|
|
2571
|
+
bashFeedDefaultTab String @default("all") // "all", "upcoming", "live", "past", "saved", "my-posts"
|
|
2572
|
+
bashFeedDefaultSort String @default("chronological") // "for_you", "chronological", "trending", etc.
|
|
2573
|
+
bashFeedFilters Json? // Saved filter preferences as JSON
|
|
2313
2574
|
/// Services discovery: keyed by service type tab, e.g. { "Entertainment": { ... } }
|
|
2314
2575
|
serviceFilterSettings Json?
|
|
2315
2576
|
/// Venue discovery filter bar (same pattern as serviceFilterSettings)
|
|
@@ -2588,17 +2849,19 @@ model ServiceBlock {
|
|
|
2588
2849
|
}
|
|
2589
2850
|
|
|
2590
2851
|
model AssociatedBash {
|
|
2591
|
-
id
|
|
2592
|
-
bashEventId
|
|
2593
|
-
invitationId
|
|
2594
|
-
ownerEmail
|
|
2595
|
-
ownerUserId
|
|
2596
|
-
isOrganizer
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2852
|
+
id String @id @default(cuid())
|
|
2853
|
+
bashEventId String
|
|
2854
|
+
invitationId String? @unique
|
|
2855
|
+
ownerEmail String?
|
|
2856
|
+
ownerUserId String?
|
|
2857
|
+
isOrganizer Boolean?
|
|
2858
|
+
isCoHost Boolean? @default(false)
|
|
2859
|
+
isDoorStaff Boolean? @default(false)
|
|
2860
|
+
organizerTitle String?
|
|
2861
|
+
bashEvent BashEvent @relation(fields: [bashEventId], references: [id], onDelete: Cascade)
|
|
2862
|
+
invitation Invitation? @relation(fields: [invitationId], references: [id])
|
|
2863
|
+
owner User? @relation(fields: [ownerUserId], references: [id], onDelete: Cascade)
|
|
2864
|
+
service Service[] @relation("AssociatedBashToService")
|
|
2602
2865
|
|
|
2603
2866
|
@@unique([ownerEmail, bashEventId])
|
|
2604
2867
|
}
|
|
@@ -2708,6 +2971,9 @@ model Service {
|
|
|
2708
2971
|
verifiedAt DateTime? // When verification was approved
|
|
2709
2972
|
licenseNumber String? // License/registration number
|
|
2710
2973
|
certifications String[] @default([]) // Array of certification names
|
|
2974
|
+
/// Custom scope pricing — admin-gated flag for providers who need variable/quote-based pricing
|
|
2975
|
+
customScopeStatus CustomScopeStatus @default(None)
|
|
2976
|
+
customScopeRequestNote String? // Provider's explanation of why they need custom scope
|
|
2711
2977
|
bashFeedPosts BashFeedPost[]
|
|
2712
2978
|
bashEventArtists BashEventArtist[]
|
|
2713
2979
|
bashCreativeSubmissions BashCreativeSubmission[]
|
|
@@ -2745,6 +3011,7 @@ model Service {
|
|
|
2745
3011
|
entertainerMatches VenueEntertainmentMatch[] @relation("EntertainerMatches")
|
|
2746
3012
|
includes ServiceInclude[]
|
|
2747
3013
|
addonRequests ServiceAddonRequest[]
|
|
3014
|
+
serviceBudgets Budget[] @relation("ServiceBudgets")
|
|
2748
3015
|
|
|
2749
3016
|
@@index([serviceListingStripeSubscriptionId])
|
|
2750
3017
|
@@index([isFreeFirstListing])
|
|
@@ -2775,7 +3042,7 @@ model StripeWebhookEvent {
|
|
|
2775
3042
|
|
|
2776
3043
|
model StripeDispute {
|
|
2777
3044
|
id String @id @default(cuid())
|
|
2778
|
-
stripeChargeId String
|
|
3045
|
+
stripeChargeId String @unique
|
|
2779
3046
|
createdAt DateTime @default(now())
|
|
2780
3047
|
|
|
2781
3048
|
@@index([stripeChargeId])
|
|
@@ -3091,9 +3358,9 @@ model Venue {
|
|
|
3091
3358
|
lastMatchNotificationSent DateTime?
|
|
3092
3359
|
|
|
3093
3360
|
/// Venue loyalty program intent (wizard + profile; redemption is future work)
|
|
3094
|
-
loyaltyEnabled
|
|
3095
|
-
loyaltyTemplateIds
|
|
3096
|
-
loyaltyNotes
|
|
3361
|
+
loyaltyEnabled Boolean @default(false)
|
|
3362
|
+
loyaltyTemplateIds String[] @default([])
|
|
3363
|
+
loyaltyNotes String?
|
|
3097
3364
|
|
|
3098
3365
|
bashEvents BashEvent[]
|
|
3099
3366
|
service Service?
|
|
@@ -3166,7 +3433,7 @@ model Organization {
|
|
|
3166
3433
|
secondaryVenueTypes String[] @default([])
|
|
3167
3434
|
baseMembershipPriceCents Int?
|
|
3168
3435
|
premiumMembershipPriceCents Int?
|
|
3169
|
-
membershipBillingInterval String?
|
|
3436
|
+
membershipBillingInterval String? // one_time | monthly | annual for recurring dues
|
|
3170
3437
|
allowGuestsByDefault Boolean @default(false)
|
|
3171
3438
|
defaultGuestLimit Int @default(0)
|
|
3172
3439
|
visibility String @default("Public")
|
|
@@ -3180,7 +3447,7 @@ model Organization {
|
|
|
3180
3447
|
subscriptionStatus String?
|
|
3181
3448
|
stripeSubscriptionId String? @unique
|
|
3182
3449
|
stripeCustomerId String?
|
|
3183
|
-
stripeConnectedAccountId
|
|
3450
|
+
stripeConnectedAccountId String? // Org-level Stripe account for wallet display
|
|
3184
3451
|
inheritBrandingFromParent Boolean @default(true)
|
|
3185
3452
|
latitude Float?
|
|
3186
3453
|
longitude Float?
|
|
@@ -3246,24 +3513,24 @@ enum GameStatus {
|
|
|
3246
3513
|
|
|
3247
3514
|
/// A scheduled or completed game between two team organizations within a league season.
|
|
3248
3515
|
model Game {
|
|
3249
|
-
id
|
|
3250
|
-
seasonId
|
|
3251
|
-
season
|
|
3252
|
-
homeTeamId
|
|
3253
|
-
awayTeamId
|
|
3254
|
-
homeTeam
|
|
3255
|
-
awayTeam
|
|
3256
|
-
scheduledAt
|
|
3257
|
-
venueName
|
|
3258
|
-
venueStreet
|
|
3259
|
-
venueCity
|
|
3260
|
-
venueState
|
|
3516
|
+
id String @id @default(cuid())
|
|
3517
|
+
seasonId String
|
|
3518
|
+
season Season @relation(fields: [seasonId], references: [id], onDelete: Cascade)
|
|
3519
|
+
homeTeamId String
|
|
3520
|
+
awayTeamId String
|
|
3521
|
+
homeTeam Organization @relation("HomeTeamGames", fields: [homeTeamId], references: [id], onDelete: Restrict)
|
|
3522
|
+
awayTeam Organization @relation("AwayTeamGames", fields: [awayTeamId], references: [id], onDelete: Restrict)
|
|
3523
|
+
scheduledAt DateTime
|
|
3524
|
+
venueName String?
|
|
3525
|
+
venueStreet String?
|
|
3526
|
+
venueCity String?
|
|
3527
|
+
venueState String?
|
|
3261
3528
|
venueZipCode String?
|
|
3262
|
-
homeScore
|
|
3263
|
-
awayScore
|
|
3264
|
-
status
|
|
3265
|
-
createdAt
|
|
3266
|
-
updatedAt
|
|
3529
|
+
homeScore Int?
|
|
3530
|
+
awayScore Int?
|
|
3531
|
+
status GameStatus @default(Scheduled)
|
|
3532
|
+
createdAt DateTime @default(now())
|
|
3533
|
+
updatedAt DateTime @updatedAt
|
|
3267
3534
|
|
|
3268
3535
|
@@index([seasonId])
|
|
3269
3536
|
@@index([homeTeamId])
|
|
@@ -3272,31 +3539,31 @@ model Game {
|
|
|
3272
3539
|
}
|
|
3273
3540
|
|
|
3274
3541
|
model OrganizationMember {
|
|
3275
|
-
id
|
|
3276
|
-
organizationId
|
|
3277
|
-
userId
|
|
3278
|
-
role
|
|
3279
|
-
membershipTier
|
|
3280
|
-
status
|
|
3281
|
-
joinedAt
|
|
3282
|
-
approvedAt
|
|
3283
|
-
approvedBy
|
|
3284
|
-
paidUntil
|
|
3285
|
-
paymentStatus
|
|
3286
|
-
guestLimit
|
|
3287
|
-
canInvite
|
|
3288
|
-
canCreateEvents
|
|
3289
|
-
canManageBudgets
|
|
3290
|
-
engagementScore
|
|
3291
|
-
lastActiveAt
|
|
3292
|
-
totalEventsAttended
|
|
3293
|
-
firstEventAttendedAt
|
|
3294
|
-
stripeSubscriptionId
|
|
3295
|
-
jerseyNumber
|
|
3296
|
-
position
|
|
3297
|
-
organization
|
|
3298
|
-
user
|
|
3299
|
-
eventRSVPs
|
|
3542
|
+
id String @id @default(cuid())
|
|
3543
|
+
organizationId String
|
|
3544
|
+
userId String
|
|
3545
|
+
role String @default("Member") // Owner, Admin, Coordinator, EventOrganizer, Treasurer, Member
|
|
3546
|
+
membershipTier String @default("Base") // Base, Premium
|
|
3547
|
+
status String @default("Pending") // Pending, Active, Suspended, Removed
|
|
3548
|
+
joinedAt DateTime @default(now())
|
|
3549
|
+
approvedAt DateTime?
|
|
3550
|
+
approvedBy String?
|
|
3551
|
+
paidUntil DateTime?
|
|
3552
|
+
paymentStatus String? @default("Current") // Current, Overdue, Cancelled
|
|
3553
|
+
guestLimit Int?
|
|
3554
|
+
canInvite Boolean @default(true)
|
|
3555
|
+
canCreateEvents Boolean @default(false)
|
|
3556
|
+
canManageBudgets Boolean @default(false)
|
|
3557
|
+
engagementScore Float? // Computed: weighted formula (events, recency, points, referrals)
|
|
3558
|
+
lastActiveAt DateTime? // Last event attended
|
|
3559
|
+
totalEventsAttended Int @default(0)
|
|
3560
|
+
firstEventAttendedAt DateTime?
|
|
3561
|
+
stripeSubscriptionId String? @unique // Stripe subscription ID for recurring org membership dues
|
|
3562
|
+
jerseyNumber String?
|
|
3563
|
+
position String?
|
|
3564
|
+
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
|
|
3565
|
+
user User @relation("OrganizationMemberUser", fields: [userId], references: [id], onDelete: Cascade)
|
|
3566
|
+
eventRSVPs EventRSVP[]
|
|
3300
3567
|
notificationPreferences OrganizationMemberPreferences?
|
|
3301
3568
|
|
|
3302
3569
|
@@unique([organizationId, userId])
|
|
@@ -3308,20 +3575,20 @@ model OrganizationMember {
|
|
|
3308
3575
|
|
|
3309
3576
|
/// Per-member notification toggles for organization channels (1:1 with OrganizationMember).
|
|
3310
3577
|
model OrganizationMemberPreferences {
|
|
3311
|
-
id
|
|
3312
|
-
organizationMemberId
|
|
3313
|
-
announcements
|
|
3314
|
-
eventReminders
|
|
3315
|
-
eventUpdates
|
|
3316
|
-
budgetAlerts
|
|
3317
|
-
proposalNotifications
|
|
3318
|
-
taskAssignments
|
|
3319
|
-
membershipUpdates
|
|
3320
|
-
emailNotifications
|
|
3321
|
-
pushNotifications
|
|
3322
|
-
createdAt
|
|
3323
|
-
updatedAt
|
|
3324
|
-
organizationMember
|
|
3578
|
+
id String @id @default(cuid())
|
|
3579
|
+
organizationMemberId String @unique
|
|
3580
|
+
announcements Boolean @default(true)
|
|
3581
|
+
eventReminders Boolean @default(true)
|
|
3582
|
+
eventUpdates Boolean @default(true)
|
|
3583
|
+
budgetAlerts Boolean @default(true)
|
|
3584
|
+
proposalNotifications Boolean @default(true)
|
|
3585
|
+
taskAssignments Boolean @default(true)
|
|
3586
|
+
membershipUpdates Boolean @default(true)
|
|
3587
|
+
emailNotifications Boolean @default(true)
|
|
3588
|
+
pushNotifications Boolean @default(true)
|
|
3589
|
+
createdAt DateTime @default(now())
|
|
3590
|
+
updatedAt DateTime @updatedAt
|
|
3591
|
+
organizationMember OrganizationMember @relation(fields: [organizationMemberId], references: [id], onDelete: Cascade)
|
|
3325
3592
|
|
|
3326
3593
|
@@index([organizationMemberId])
|
|
3327
3594
|
}
|
|
@@ -3377,6 +3644,8 @@ model Budget {
|
|
|
3377
3644
|
clubId String?
|
|
3378
3645
|
departmentId String?
|
|
3379
3646
|
userId String? // For personal event budgets
|
|
3647
|
+
/// Optional: budgets tied to a service profile (vendor/exhibitor/sponsor owner costs).
|
|
3648
|
+
serviceId String?
|
|
3380
3649
|
|
|
3381
3650
|
// Budget details
|
|
3382
3651
|
totalAllocatedCents Int
|
|
@@ -3409,6 +3678,7 @@ model Budget {
|
|
|
3409
3678
|
club Club? @relation("ClubBudgets", fields: [clubId], references: [id], onDelete: Cascade)
|
|
3410
3679
|
department Department? @relation("DepartmentBudgets", fields: [departmentId], references: [id], onDelete: Cascade)
|
|
3411
3680
|
user User? @relation("UserBudgets", fields: [userId], references: [id], onDelete: Cascade)
|
|
3681
|
+
service Service? @relation("ServiceBudgets", fields: [serviceId], references: [id], onDelete: Cascade)
|
|
3412
3682
|
submitter User? @relation("BudgetSubmitter", fields: [submittedBy], references: [id])
|
|
3413
3683
|
approver User? @relation("BudgetApprover", fields: [approverId], references: [id])
|
|
3414
3684
|
expenses Expense[]
|
|
@@ -3418,10 +3688,18 @@ model Budget {
|
|
|
3418
3688
|
@@index([clubId])
|
|
3419
3689
|
@@index([departmentId])
|
|
3420
3690
|
@@index([userId])
|
|
3691
|
+
@@index([serviceId])
|
|
3421
3692
|
@@index([status])
|
|
3422
3693
|
@@index([fiscalYear])
|
|
3423
3694
|
}
|
|
3424
3695
|
|
|
3696
|
+
enum ExpenseExtractionStatus {
|
|
3697
|
+
none
|
|
3698
|
+
pending
|
|
3699
|
+
complete
|
|
3700
|
+
failed
|
|
3701
|
+
}
|
|
3702
|
+
|
|
3425
3703
|
model Expense {
|
|
3426
3704
|
id String @id @default(cuid())
|
|
3427
3705
|
budgetId String
|
|
@@ -3437,6 +3715,29 @@ model Expense {
|
|
|
3437
3715
|
rejectionReason String?
|
|
3438
3716
|
createdAt DateTime @default(now())
|
|
3439
3717
|
updatedAt DateTime @updatedAt
|
|
3718
|
+
|
|
3719
|
+
/// Optional link to an event task (e.g. volunteer receipt for a specific task).
|
|
3720
|
+
eventTaskId String?
|
|
3721
|
+
eventTask EventTask? @relation(fields: [eventTaskId], references: [id], onDelete: SetNull)
|
|
3722
|
+
|
|
3723
|
+
/// User-confirmed or extracted metadata (Textract suggestions are confirmed before save).
|
|
3724
|
+
vendorName String?
|
|
3725
|
+
taxCents Int?
|
|
3726
|
+
subtotalCents Int?
|
|
3727
|
+
currency String? @default("USD")
|
|
3728
|
+
|
|
3729
|
+
extractionStatus ExpenseExtractionStatus @default(none)
|
|
3730
|
+
textractRaw Json?
|
|
3731
|
+
|
|
3732
|
+
/// Vendor invoice number (manual or extracted).
|
|
3733
|
+
invoiceNumber String?
|
|
3734
|
+
/// When payment is due (separate from expenseDate / receipt date).
|
|
3735
|
+
invoiceDueDate DateTime?
|
|
3736
|
+
/// Host marked invoice as paid outside the app — stops due-date reminders.
|
|
3737
|
+
invoicePaidAt DateTime?
|
|
3738
|
+
/// Tracks which invoice due reminders were sent: { dueSoon, dueDay, pastDue1, pastDue15 }.
|
|
3739
|
+
invoiceDueRemindersSent Json?
|
|
3740
|
+
|
|
3440
3741
|
budget Budget @relation(fields: [budgetId], references: [id], onDelete: Cascade)
|
|
3441
3742
|
submitter User @relation("ExpenseSubmitter", fields: [submittedBy], references: [id])
|
|
3442
3743
|
approver User? @relation("ExpenseApprover", fields: [approvedBy], references: [id])
|
|
@@ -3444,6 +3745,8 @@ model Expense {
|
|
|
3444
3745
|
@@index([budgetId])
|
|
3445
3746
|
@@index([submittedBy])
|
|
3446
3747
|
@@index([status])
|
|
3748
|
+
@@index([eventTaskId])
|
|
3749
|
+
@@index([invoiceDueDate])
|
|
3447
3750
|
}
|
|
3448
3751
|
|
|
3449
3752
|
model ServiceRange {
|
|
@@ -3707,47 +4010,47 @@ model ServiceBookingCheckout {
|
|
|
3707
4010
|
}
|
|
3708
4011
|
|
|
3709
4012
|
model ServiceBooking {
|
|
3710
|
-
id String
|
|
4013
|
+
id String @id @default(cuid())
|
|
3711
4014
|
creatorId String
|
|
3712
4015
|
forUserId String
|
|
3713
4016
|
daysTotalATBCents Int
|
|
3714
4017
|
serviceId String
|
|
3715
|
-
rateOption ServiceBookingRateOption
|
|
4018
|
+
rateOption ServiceBookingRateOption @default(TimeBased)
|
|
3716
4019
|
flatRateCents Int?
|
|
3717
|
-
status ServiceBookingStatus
|
|
3718
|
-
bookingType ServiceBookingType
|
|
4020
|
+
status ServiceBookingStatus @default(Pending)
|
|
4021
|
+
bookingType ServiceBookingType @default(Request)
|
|
3719
4022
|
timezone String
|
|
3720
4023
|
requestedOn DateTime?
|
|
3721
4024
|
requestDecisionOn DateTime?
|
|
3722
4025
|
bookedOn DateTime?
|
|
3723
4026
|
canceledOn DateTime?
|
|
3724
|
-
isFreeGuest Boolean
|
|
3725
|
-
allowPromiseToPay Boolean
|
|
4027
|
+
isFreeGuest Boolean @default(false)
|
|
4028
|
+
allowPromiseToPay Boolean @default(false)
|
|
3726
4029
|
totalATBCents Int
|
|
3727
|
-
subtotalATBCents Int
|
|
4030
|
+
subtotalATBCents Int @default(0)
|
|
3728
4031
|
bashEventId String?
|
|
3729
|
-
isVendorBid Boolean
|
|
4032
|
+
isVendorBid Boolean @default(false)
|
|
3730
4033
|
vendorBidAmountCents Int?
|
|
3731
4034
|
vendorEventDetails String?
|
|
3732
4035
|
bashPointsApplied Int? // BashPoints credits applied to this booking
|
|
3733
4036
|
bashPointsTransactionId String? // Link to BashCreditTransaction
|
|
3734
4037
|
// Settlement fields for percentage-based bookings (populated at event close)
|
|
3735
|
-
settlementBasis
|
|
3736
|
-
settlementPercentage
|
|
3737
|
-
settlementAmountCents
|
|
3738
|
-
settledAt
|
|
4038
|
+
settlementBasis ServiceBookingSettlementBasis?
|
|
4039
|
+
settlementPercentage Decimal?
|
|
4040
|
+
settlementAmountCents Int?
|
|
4041
|
+
settledAt DateTime?
|
|
3739
4042
|
notification Notification[]
|
|
3740
|
-
bashEvent BashEvent?
|
|
3741
|
-
creator User
|
|
3742
|
-
forUser User
|
|
3743
|
-
service Service
|
|
4043
|
+
bashEvent BashEvent? @relation(fields: [bashEventId], references: [id])
|
|
4044
|
+
creator User @relation("BookingCreator", fields: [creatorId], references: [id])
|
|
4045
|
+
forUser User @relation("BookingForUser", fields: [forUserId], references: [id])
|
|
4046
|
+
service Service @relation(fields: [serviceId], references: [id])
|
|
3744
4047
|
addOns ServiceBookingAddOn[]
|
|
3745
4048
|
checkout ServiceBookingCheckout?
|
|
3746
4049
|
bookedDays ServiceBookingDay[]
|
|
3747
4050
|
additionalFees ServiceBookingFee[]
|
|
3748
4051
|
messages ServiceBookingMessage[]
|
|
3749
4052
|
packages ServiceBookingPackage[]
|
|
3750
|
-
commissions BookingCommission[]
|
|
4053
|
+
commissions BookingCommission[] @relation("BookingCommissions")
|
|
3751
4054
|
sentReminders SentReminder[]
|
|
3752
4055
|
|
|
3753
4056
|
@@index([status])
|
|
@@ -4088,21 +4391,21 @@ model BashSlugHistory {
|
|
|
4088
4391
|
}
|
|
4089
4392
|
|
|
4090
4393
|
model BashEventTransferRequest {
|
|
4091
|
-
id
|
|
4092
|
-
bashEventId
|
|
4093
|
-
fromUserId
|
|
4094
|
-
toUserId
|
|
4095
|
-
toEmail
|
|
4096
|
-
inviteToken
|
|
4097
|
-
keepPayoutsWithMe
|
|
4098
|
-
status
|
|
4099
|
-
reason
|
|
4100
|
-
requestedAt
|
|
4101
|
-
respondedAt
|
|
4102
|
-
expiresAt
|
|
4103
|
-
bashEvent
|
|
4104
|
-
fromUser
|
|
4105
|
-
toUser
|
|
4394
|
+
id String @id @default(cuid())
|
|
4395
|
+
bashEventId String
|
|
4396
|
+
fromUserId String
|
|
4397
|
+
toUserId String? // null when transferring to a non-user by email
|
|
4398
|
+
toEmail String? // set when toUserId is null (non-user invite transfer)
|
|
4399
|
+
inviteToken String? @unique // secure token embedded in the signup/claim link
|
|
4400
|
+
keepPayoutsWithMe Boolean @default(false) // when true, creator keeps receiving payouts after transfer
|
|
4401
|
+
status TransferRequestStatus @default(Pending)
|
|
4402
|
+
reason String?
|
|
4403
|
+
requestedAt DateTime @default(now())
|
|
4404
|
+
respondedAt DateTime?
|
|
4405
|
+
expiresAt DateTime
|
|
4406
|
+
bashEvent BashEvent @relation(fields: [bashEventId], references: [id], onDelete: Cascade)
|
|
4407
|
+
fromUser User @relation("TransferRequestsFrom", fields: [fromUserId], references: [id], onDelete: Cascade)
|
|
4408
|
+
toUser User? @relation("TransferRequestsTo", fields: [toUserId], references: [id], onDelete: Cascade)
|
|
4106
4409
|
|
|
4107
4410
|
@@index([bashEventId])
|
|
4108
4411
|
@@index([toUserId, status])
|
|
@@ -4348,23 +4651,29 @@ enum NotificationType {
|
|
|
4348
4651
|
BashRatingMilestone
|
|
4349
4652
|
BashFeedPost
|
|
4350
4653
|
EventMilestone
|
|
4351
|
-
WaitlistRequested
|
|
4352
|
-
WaitlistApproved
|
|
4353
|
-
WaitlistDenied
|
|
4654
|
+
WaitlistRequested // Host: someone requested a spot on your waitlist
|
|
4655
|
+
WaitlistApproved // Attendee: host approved your waitlist request
|
|
4656
|
+
WaitlistDenied // Attendee: host denied your waitlist request
|
|
4354
4657
|
WaitlistSpotAvailable // Waitlister: a refund opened a spot — claim it now
|
|
4355
4658
|
WaitlistSpotMayBeOpen // Waitlister: someone left the venue — standby at door
|
|
4356
4659
|
// Group notifications
|
|
4357
|
-
GroupMemberPurchased
|
|
4358
|
-
GroupEveryoneConfirmed
|
|
4359
|
-
GroupEveryonePurchased
|
|
4360
|
-
GroupMemberJoined
|
|
4361
|
-
FriendsAttending
|
|
4362
|
-
GroupRewardProgress
|
|
4363
|
-
GroupUnlockOfferReceived
|
|
4364
|
-
HostSalesAccelerating
|
|
4365
|
-
HostTopPromoter
|
|
4366
|
-
HostSalesSlowing
|
|
4367
|
-
TicketSold
|
|
4660
|
+
GroupMemberPurchased // Owner: "Riley just bought a ticket — 2 more to go!"
|
|
4661
|
+
GroupEveryoneConfirmed // Owner: "All members want to attend. Buy tickets together?"
|
|
4662
|
+
GroupEveryonePurchased // Owner: "Your group is officially attending"
|
|
4663
|
+
GroupMemberJoined // Owner: "Alex joined your group"
|
|
4664
|
+
FriendsAttending // User: "3 of your friends are attending this bash"
|
|
4665
|
+
GroupRewardProgress // Member: "Only 2 more friends needed for your group reward"
|
|
4666
|
+
GroupUnlockOfferReceived // Member: "Special offer unlocked for your group"
|
|
4667
|
+
HostSalesAccelerating // Host: "Your event sales increased 38% today"
|
|
4668
|
+
HostTopPromoter // Host: "Top promoter: Alex (6 tickets today)"
|
|
4669
|
+
HostSalesSlowing // Host: "Sales slowed today. Try sharing your event."
|
|
4670
|
+
TicketSold // Host: a ticket was purchased for your event (debounced in webhook)
|
|
4671
|
+
BudgetExpenseSubmitted // Host/organizer: assignee or member submitted an expense
|
|
4672
|
+
BudgetLineThreshold // Host/organizer: budget line crossed a spend threshold (e.g. 80% / 100%)
|
|
4673
|
+
BudgetInvoiceDueSoon // Host/organizer: invoice due in ~3 days
|
|
4674
|
+
BudgetInvoiceDueToday // Host/organizer: invoice due today
|
|
4675
|
+
BudgetInvoicePastDue // Host/organizer: invoice 1 day past due
|
|
4676
|
+
BudgetInvoicePastDueFinal // Host/organizer: invoice 15+ days past due
|
|
4368
4677
|
}
|
|
4369
4678
|
|
|
4370
4679
|
enum NotificationPriority {
|
|
@@ -4392,7 +4701,7 @@ enum BashEventSource {
|
|
|
4392
4701
|
Meetup
|
|
4393
4702
|
Facebook
|
|
4394
4703
|
JamWith
|
|
4395
|
-
Partner
|
|
4704
|
+
Partner // Generic: use sourcePartnerId for partner key (e.g. 'mixlog', custom integrations)
|
|
4396
4705
|
}
|
|
4397
4706
|
|
|
4398
4707
|
enum TicketStatus {
|
|
@@ -4403,7 +4712,7 @@ enum TicketStatus {
|
|
|
4403
4712
|
LeftRadius
|
|
4404
4713
|
Pending
|
|
4405
4714
|
WaitlistPending // Requested a spot on a host-approval waitlist; awaiting decision
|
|
4406
|
-
RefundPending
|
|
4715
|
+
RefundPending // Refund requested; held while next waitlister is given a claim window
|
|
4407
4716
|
}
|
|
4408
4717
|
|
|
4409
4718
|
enum DayOfWeek {
|
|
@@ -4662,6 +4971,44 @@ enum BashStatus {
|
|
|
4662
4971
|
Archived // Unclaimed after expiration
|
|
4663
4972
|
}
|
|
4664
4973
|
|
|
4974
|
+
/// Minimum-age policy for a bash. Used by the BashCard pill, discover filters,
|
|
4975
|
+
/// and (when 18+/21+) age verification at ticket checkout.
|
|
4976
|
+
enum AgePolicy {
|
|
4977
|
+
AllAges
|
|
4978
|
+
EighteenPlus
|
|
4979
|
+
TwentyOnePlus
|
|
4980
|
+
}
|
|
4981
|
+
|
|
4982
|
+
/// Retention policy for a user's stored government-ID image (drives expireIdImages cron + GDPR consent record)
|
|
4983
|
+
enum GovIdRetentionPolicy {
|
|
4984
|
+
ThirtyDays
|
|
4985
|
+
UntilIdExpires
|
|
4986
|
+
Indefinite
|
|
4987
|
+
}
|
|
4988
|
+
|
|
4989
|
+
/// Whether the user's `schoolName` was extracted by the AI vision model or confirmed/edited by the user
|
|
4990
|
+
enum SchoolNameSource {
|
|
4991
|
+
AiInferred
|
|
4992
|
+
UserConfirmed
|
|
4993
|
+
}
|
|
4994
|
+
|
|
4995
|
+
/// Admin-gated custom-scope pricing flag for service providers needing variable/quote-based pricing
|
|
4996
|
+
enum CustomScopeStatus {
|
|
4997
|
+
None
|
|
4998
|
+
Pending
|
|
4999
|
+
Approved
|
|
5000
|
+
Rejected
|
|
5001
|
+
}
|
|
5002
|
+
|
|
5003
|
+
/// AI bash-approval reviewer verdict (see `bashApprovalAiService`).
|
|
5004
|
+
/// `Approve` and `Reject` are recommendations; whether the system acts on them
|
|
5005
|
+
/// vs. queues for a human depends on confidence + AI_BASH_APPROVAL_MODE.
|
|
5006
|
+
enum AiApprovalVerdict {
|
|
5007
|
+
Approve
|
|
5008
|
+
Flag
|
|
5009
|
+
Reject
|
|
5010
|
+
}
|
|
5011
|
+
|
|
4665
5012
|
/// How a user is associated with a bash (for BashFeedPost display: "Sarah attended...", "Mike is hosting...")
|
|
4666
5013
|
enum BashAssociationType {
|
|
4667
5014
|
Hosting
|
|
@@ -4944,6 +5291,7 @@ enum FoodAndBeverageSubType {
|
|
|
4944
5291
|
Bartenders
|
|
4945
5292
|
DessertBar
|
|
4946
5293
|
BeverageCart
|
|
5294
|
+
ConcessionStand
|
|
4947
5295
|
}
|
|
4948
5296
|
|
|
4949
5297
|
enum CleaningSubType {
|
|
@@ -4975,6 +5323,9 @@ enum RentalEquipmentSubType {
|
|
|
4975
5323
|
Generators
|
|
4976
5324
|
DanceFloor
|
|
4977
5325
|
PhotoBooth
|
|
5326
|
+
BounceHouse
|
|
5327
|
+
WaterSlide
|
|
5328
|
+
CarnivalGames
|
|
4978
5329
|
}
|
|
4979
5330
|
|
|
4980
5331
|
enum MediaProductionAndCreativeSubType {
|
|
@@ -6408,30 +6759,30 @@ enum ConsentType {
|
|
|
6408
6759
|
|
|
6409
6760
|
// Birthday offers from partner companies: users opt in once, we send minimal PII to partner APIs
|
|
6410
6761
|
model BirthdayOfferPartner {
|
|
6411
|
-
id
|
|
6412
|
-
name
|
|
6413
|
-
slug
|
|
6414
|
-
description
|
|
6415
|
-
apiEndpoint
|
|
6416
|
-
config
|
|
6417
|
-
requiresPhone
|
|
6418
|
-
isActive
|
|
6419
|
-
createdAt
|
|
6420
|
-
updatedAt
|
|
6421
|
-
optIns
|
|
6422
|
-
deliveries
|
|
6762
|
+
id String @id @default(cuid())
|
|
6763
|
+
name String
|
|
6764
|
+
slug String @unique
|
|
6765
|
+
description String? @db.Text
|
|
6766
|
+
apiEndpoint String // Partner API URL; API keys live in env (BIRTHDAY_PARTNER_<SLUG>_API_KEY)
|
|
6767
|
+
config Json? // Partner-specific: e.g. sendFullDob (bool), extra fields
|
|
6768
|
+
requiresPhone Boolean @default(false) // Part B: when true, share User.phone with partner
|
|
6769
|
+
isActive Boolean @default(true)
|
|
6770
|
+
createdAt DateTime @default(now())
|
|
6771
|
+
updatedAt DateTime @updatedAt
|
|
6772
|
+
optIns UserBirthdayOfferOptIn[]
|
|
6773
|
+
deliveries BirthdayOfferDelivery[]
|
|
6423
6774
|
catalogEntries BirthdayFreebieCatalog[]
|
|
6424
6775
|
|
|
6425
6776
|
@@index([isActive])
|
|
6426
6777
|
}
|
|
6427
6778
|
|
|
6428
6779
|
model UserBirthdayOfferOptIn {
|
|
6429
|
-
id String
|
|
6780
|
+
id String @id @default(cuid())
|
|
6430
6781
|
userId String
|
|
6431
6782
|
partnerId String
|
|
6432
|
-
optedInAt DateTime
|
|
6783
|
+
optedInAt DateTime @default(now())
|
|
6433
6784
|
lastSentAt DateTime? // Last time we sent this user to this partner (for idempotency)
|
|
6434
|
-
user User
|
|
6785
|
+
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
6435
6786
|
partner BirthdayOfferPartner @relation(fields: [partnerId], references: [id], onDelete: Cascade)
|
|
6436
6787
|
|
|
6437
6788
|
@@unique([userId, partnerId])
|
|
@@ -6440,12 +6791,12 @@ model UserBirthdayOfferOptIn {
|
|
|
6440
6791
|
}
|
|
6441
6792
|
|
|
6442
6793
|
model BirthdayOfferDelivery {
|
|
6443
|
-
id String
|
|
6794
|
+
id String @id @default(cuid())
|
|
6444
6795
|
userId String
|
|
6445
6796
|
partnerId String
|
|
6446
|
-
birthdayYear Int
|
|
6447
|
-
sentAt DateTime
|
|
6448
|
-
user User
|
|
6797
|
+
birthdayYear Int // Year when the send counted (for idempotency: one send per user/partner/year)
|
|
6798
|
+
sentAt DateTime @default(now())
|
|
6799
|
+
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
6449
6800
|
partner BirthdayOfferPartner @relation(fields: [partnerId], references: [id], onDelete: Cascade)
|
|
6450
6801
|
|
|
6451
6802
|
@@unique([userId, partnerId, birthdayYear])
|
|
@@ -6455,11 +6806,11 @@ model BirthdayOfferDelivery {
|
|
|
6455
6806
|
|
|
6456
6807
|
// Birthday Rewards focused scope (v1): annual BashPoints boost idempotency
|
|
6457
6808
|
model BirthdayBoostGrant {
|
|
6458
|
-
id
|
|
6459
|
-
userId
|
|
6460
|
-
birthdayYear Int
|
|
6461
|
-
grantedAt
|
|
6462
|
-
user
|
|
6809
|
+
id String @id @default(cuid())
|
|
6810
|
+
userId String
|
|
6811
|
+
birthdayYear Int // Year for which boost was granted
|
|
6812
|
+
grantedAt DateTime @default(now())
|
|
6813
|
+
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
6463
6814
|
|
|
6464
6815
|
@@unique([userId, birthdayYear])
|
|
6465
6816
|
@@index([userId])
|
|
@@ -6481,21 +6832,21 @@ model BirthdayRewardFavorite {
|
|
|
6481
6832
|
|
|
6482
6833
|
// User-recorded places where they picked up a birthday reward (with optional rating)
|
|
6483
6834
|
model BirthdayRewardRedemption {
|
|
6484
|
-
id String
|
|
6835
|
+
id String @id @default(cuid())
|
|
6485
6836
|
userId String
|
|
6486
|
-
placeName String
|
|
6487
|
-
redeemedAt DateTime
|
|
6837
|
+
placeName String // e.g. "Freddy's", "Starbucks"
|
|
6838
|
+
redeemedAt DateTime @default(now())
|
|
6488
6839
|
birthdayYear Int
|
|
6489
|
-
notes String?
|
|
6490
|
-
difficultyScore Int?
|
|
6491
|
-
qualityScore Int?
|
|
6492
|
-
ratingComment String?
|
|
6840
|
+
notes String? @db.Text
|
|
6841
|
+
difficultyScore Int? // 1-10
|
|
6842
|
+
qualityScore Int? // 1-10
|
|
6843
|
+
ratingComment String? @db.Text
|
|
6493
6844
|
ratedAt DateTime?
|
|
6494
|
-
offerId String?
|
|
6845
|
+
offerId String? // Part B: optional FK to structured BirthdayOffer
|
|
6495
6846
|
/// Catalog or national reward id when marked picked up from the freebies guide
|
|
6496
6847
|
catalogId String?
|
|
6497
|
-
user User
|
|
6498
|
-
offer BirthdayOffer?
|
|
6848
|
+
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
6849
|
+
offer BirthdayOffer? @relation(fields: [offerId], references: [id], onDelete: SetNull)
|
|
6499
6850
|
catalog BirthdayFreebieCatalog? @relation(fields: [catalogId], references: [id], onDelete: SetNull)
|
|
6500
6851
|
|
|
6501
6852
|
@@index([userId])
|
|
@@ -6506,13 +6857,13 @@ model BirthdayRewardRedemption {
|
|
|
6506
6857
|
|
|
6507
6858
|
/// Logged-in user's saved "My Birthday Plan" offer ids + location context (separate from Part B generated BirthdayPlan).
|
|
6508
6859
|
model BirthdayFreebiesSavedPlan {
|
|
6509
|
-
id
|
|
6510
|
-
userId
|
|
6511
|
-
planIds
|
|
6512
|
-
stateSlug
|
|
6513
|
-
citySlug
|
|
6514
|
-
updatedAt
|
|
6515
|
-
user
|
|
6860
|
+
id String @id @default(cuid())
|
|
6861
|
+
userId String @unique
|
|
6862
|
+
planIds String[] @default([])
|
|
6863
|
+
stateSlug String?
|
|
6864
|
+
citySlug String?
|
|
6865
|
+
updatedAt DateTime @updatedAt
|
|
6866
|
+
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
6516
6867
|
}
|
|
6517
6868
|
|
|
6518
6869
|
enum BirthdayDealSuggestionStatus {
|
|
@@ -6523,22 +6874,22 @@ enum BirthdayDealSuggestionStatus {
|
|
|
6523
6874
|
|
|
6524
6875
|
// User-suggested birthday deals (admin can approve and add to catalog later)
|
|
6525
6876
|
model BirthdayDealSuggestion {
|
|
6526
|
-
id
|
|
6527
|
-
userId
|
|
6528
|
-
brandOrPlaceName
|
|
6529
|
-
dealDescription
|
|
6530
|
-
sourceWhereHeard
|
|
6531
|
-
linkUrl
|
|
6532
|
-
suggestedQualityTier
|
|
6533
|
-
signupDaysInAdvance
|
|
6877
|
+
id String @id @default(cuid())
|
|
6878
|
+
userId String
|
|
6879
|
+
brandOrPlaceName String
|
|
6880
|
+
dealDescription String @db.Text
|
|
6881
|
+
sourceWhereHeard String? @db.Text
|
|
6882
|
+
linkUrl String? @db.Text
|
|
6883
|
+
suggestedQualityTier BirthdayOfferQualityTier? // Suggester's experience: Awesome, Okay, or Lame
|
|
6884
|
+
signupDaysInAdvance Int? // When requiresAdvanceSignup: how many days before birthday
|
|
6534
6885
|
/// User-selected expiration hint while the suggestion is pending (mirrors catalog enum)
|
|
6535
6886
|
suggestedExpirationType BirthdayFreebieExpirationType?
|
|
6536
|
-
status
|
|
6537
|
-
createdAt
|
|
6538
|
-
reviewedAt
|
|
6539
|
-
reviewedById
|
|
6540
|
-
user
|
|
6541
|
-
catalogEntry
|
|
6887
|
+
status BirthdayDealSuggestionStatus @default(Pending)
|
|
6888
|
+
createdAt DateTime @default(now())
|
|
6889
|
+
reviewedAt DateTime?
|
|
6890
|
+
reviewedById String?
|
|
6891
|
+
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
6892
|
+
catalogEntry BirthdayFreebieCatalog?
|
|
6542
6893
|
|
|
6543
6894
|
@@index([userId])
|
|
6544
6895
|
@@index([status])
|
|
@@ -6580,38 +6931,38 @@ enum BirthdayFreebieSector {
|
|
|
6580
6931
|
}
|
|
6581
6932
|
|
|
6582
6933
|
model BirthdayFreebieCatalog {
|
|
6583
|
-
id String
|
|
6934
|
+
id String @id @default(cuid())
|
|
6584
6935
|
brandOrPlaceName String
|
|
6585
|
-
description String?
|
|
6586
|
-
logoUrl String?
|
|
6587
|
-
sector BirthdayFreebieSector
|
|
6936
|
+
description String? @db.Text
|
|
6937
|
+
logoUrl String? @db.Text
|
|
6938
|
+
sector BirthdayFreebieSector @default(Other)
|
|
6588
6939
|
category BirthdayFreebieCategory
|
|
6589
6940
|
expirationType BirthdayFreebieExpirationType
|
|
6590
6941
|
lastVerifiedAt DateTime
|
|
6591
|
-
requiresAdvanceSignup Boolean?
|
|
6942
|
+
requiresAdvanceSignup Boolean? @default(false)
|
|
6592
6943
|
source BirthdayFreebieSource
|
|
6593
6944
|
partnerId String?
|
|
6594
|
-
suggestionId String?
|
|
6945
|
+
suggestionId String? @unique // one-to-one: at most one catalog entry per suggestion
|
|
6595
6946
|
stateSlug String
|
|
6596
6947
|
citySlug String?
|
|
6597
|
-
isActive Boolean
|
|
6598
|
-
signupUrl String?
|
|
6599
|
-
sourceUrl String?
|
|
6600
|
-
appRequired Boolean
|
|
6601
|
-
priority Int
|
|
6948
|
+
isActive Boolean @default(true)
|
|
6949
|
+
signupUrl String? @db.Text // Official "how to redeem" / terms link
|
|
6950
|
+
sourceUrl String? @db.Text // Optional: reference source (e.g. NerdWallet, Krazy Coupon Lady)
|
|
6951
|
+
appRequired Boolean @default(false)
|
|
6952
|
+
priority Int @default(0) // Tie-break sort
|
|
6602
6953
|
qualityTier BirthdayOfferQualityTier? // Awesome / Okay / Lame — set by super users on approve
|
|
6603
|
-
address String?
|
|
6604
|
-
redemptionNotes String?
|
|
6605
|
-
expirationDays
|
|
6606
|
-
isNational
|
|
6607
|
-
createdAt DateTime
|
|
6608
|
-
updatedAt DateTime
|
|
6609
|
-
|
|
6610
|
-
partner
|
|
6611
|
-
suggestion
|
|
6612
|
-
rewardReports
|
|
6954
|
+
address String? @db.Text // For Maps and display
|
|
6955
|
+
redemptionNotes String? @db.Text // Conditions, limitations
|
|
6956
|
+
expirationDays Int? // when Valid30Days with custom count
|
|
6957
|
+
isNational Boolean @default(false)
|
|
6958
|
+
createdAt DateTime @default(now())
|
|
6959
|
+
updatedAt DateTime @updatedAt
|
|
6960
|
+
|
|
6961
|
+
partner BirthdayOfferPartner? @relation(fields: [partnerId], references: [id], onDelete: SetNull)
|
|
6962
|
+
suggestion BirthdayDealSuggestion? @relation(fields: [suggestionId], references: [id], onDelete: SetNull)
|
|
6963
|
+
rewardReports RewardReport[]
|
|
6613
6964
|
/// User quality votes (Awesome / Okay / Lame); one row per user per catalog entry.
|
|
6614
|
-
votes
|
|
6965
|
+
votes BirthdayFreebieVote[]
|
|
6615
6966
|
birthdayRewardRedemptions BirthdayRewardRedemption[]
|
|
6616
6967
|
|
|
6617
6968
|
@@index([stateSlug, citySlug])
|
|
@@ -6622,12 +6973,12 @@ model BirthdayFreebieCatalog {
|
|
|
6622
6973
|
|
|
6623
6974
|
/// User quality vote on a catalog entry (Awesome / Okay / Lame). Drives aggregate counts and optional qualityTier updates.
|
|
6624
6975
|
model BirthdayFreebieVote {
|
|
6625
|
-
id String
|
|
6976
|
+
id String @id @default(cuid())
|
|
6626
6977
|
catalogId String
|
|
6627
6978
|
userId String
|
|
6628
6979
|
tier BirthdayOfferQualityTier
|
|
6629
|
-
createdAt DateTime
|
|
6630
|
-
updatedAt DateTime
|
|
6980
|
+
createdAt DateTime @default(now())
|
|
6981
|
+
updatedAt DateTime @updatedAt
|
|
6631
6982
|
|
|
6632
6983
|
catalog BirthdayFreebieCatalog @relation(fields: [catalogId], references: [id], onDelete: Cascade)
|
|
6633
6984
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
@@ -6645,15 +6996,15 @@ enum BirthdayCityResourceType {
|
|
|
6645
6996
|
}
|
|
6646
6997
|
|
|
6647
6998
|
model BirthdayCityResource {
|
|
6648
|
-
id
|
|
6649
|
-
stateSlug
|
|
6650
|
-
citySlug
|
|
6651
|
-
type
|
|
6652
|
-
label
|
|
6653
|
-
url
|
|
6654
|
-
sortOrder
|
|
6655
|
-
createdAt
|
|
6656
|
-
updatedAt
|
|
6999
|
+
id String @id @default(cuid())
|
|
7000
|
+
stateSlug String
|
|
7001
|
+
citySlug String? // null = state-level resource
|
|
7002
|
+
type BirthdayCityResourceType
|
|
7003
|
+
label String // e.g. "Visit Salt Lake events"
|
|
7004
|
+
url String @db.Text
|
|
7005
|
+
sortOrder Int @default(0)
|
|
7006
|
+
createdAt DateTime @default(now())
|
|
7007
|
+
updatedAt DateTime @updatedAt
|
|
6657
7008
|
suggestionCreatedFor BirthdayCityResourceSuggestion? @relation("CityResourceFromSuggestion")
|
|
6658
7009
|
|
|
6659
7010
|
@@index([stateSlug, citySlug])
|
|
@@ -6667,21 +7018,21 @@ enum BirthdayCityResourceSuggestionStatus {
|
|
|
6667
7018
|
|
|
6668
7019
|
// User-suggested "free things to do" links — admin approves into BirthdayCityResource
|
|
6669
7020
|
model BirthdayCityResourceSuggestion {
|
|
6670
|
-
id String
|
|
7021
|
+
id String @id @default(cuid())
|
|
6671
7022
|
stateSlug String
|
|
6672
7023
|
citySlug String
|
|
6673
|
-
url String
|
|
6674
|
-
label String?
|
|
6675
|
-
notes String?
|
|
6676
|
-
contactEmail String?
|
|
7024
|
+
url String @db.Text
|
|
7025
|
+
label String? @db.Text
|
|
7026
|
+
notes String? @db.Text
|
|
7027
|
+
contactEmail String? @db.Text
|
|
6677
7028
|
userId String?
|
|
6678
7029
|
status BirthdayCityResourceSuggestionStatus @default(Pending)
|
|
6679
|
-
createdAt DateTime
|
|
7030
|
+
createdAt DateTime @default(now())
|
|
6680
7031
|
reviewedAt DateTime?
|
|
6681
7032
|
reviewedById String?
|
|
6682
|
-
createdResourceId String?
|
|
6683
|
-
user User?
|
|
6684
|
-
createdResource BirthdayCityResource?
|
|
7033
|
+
createdResourceId String? @unique
|
|
7034
|
+
user User? @relation(fields: [userId], references: [id], onDelete: SetNull)
|
|
7035
|
+
createdResource BirthdayCityResource? @relation("CityResourceFromSuggestion", fields: [createdResourceId], references: [id], onDelete: SetNull)
|
|
6685
7036
|
|
|
6686
7037
|
@@index([status])
|
|
6687
7038
|
@@index([stateSlug, citySlug])
|
|
@@ -6694,18 +7045,18 @@ enum RewardReportStatus {
|
|
|
6694
7045
|
}
|
|
6695
7046
|
|
|
6696
7047
|
model RewardReport {
|
|
6697
|
-
id
|
|
6698
|
-
catalogId
|
|
6699
|
-
userId
|
|
6700
|
-
reportedAt
|
|
6701
|
-
reason
|
|
6702
|
-
suggestedChanges String?
|
|
6703
|
-
status
|
|
6704
|
-
reviewedAt
|
|
6705
|
-
reviewedById
|
|
6706
|
-
catalog
|
|
6707
|
-
user
|
|
6708
|
-
reviewedBy
|
|
7048
|
+
id String @id @default(cuid())
|
|
7049
|
+
catalogId String
|
|
7050
|
+
userId String
|
|
7051
|
+
reportedAt DateTime @default(now())
|
|
7052
|
+
reason String @db.Text
|
|
7053
|
+
suggestedChanges String? @db.Text
|
|
7054
|
+
status RewardReportStatus @default(Pending)
|
|
7055
|
+
reviewedAt DateTime?
|
|
7056
|
+
reviewedById String?
|
|
7057
|
+
catalog BirthdayFreebieCatalog @relation(fields: [catalogId], references: [id], onDelete: Cascade)
|
|
7058
|
+
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
7059
|
+
reviewedBy User? @relation("RewardReportReviewedBy", fields: [reviewedById], references: [id], onDelete: SetNull)
|
|
6709
7060
|
|
|
6710
7061
|
@@index([catalogId])
|
|
6711
7062
|
@@index([userId])
|
|
@@ -6714,18 +7065,18 @@ model RewardReport {
|
|
|
6714
7065
|
|
|
6715
7066
|
/// Reports on hard-coded national chains (nationalBirthdayRewards.ts). Super users review and update the file.
|
|
6716
7067
|
model NationalChainReport {
|
|
6717
|
-
id
|
|
6718
|
-
nationalBrandId
|
|
6719
|
-
nationalBrandName String
|
|
6720
|
-
userId
|
|
6721
|
-
reportedAt
|
|
6722
|
-
reason
|
|
6723
|
-
suggestedChanges
|
|
6724
|
-
status
|
|
6725
|
-
reviewedAt
|
|
6726
|
-
reviewedById
|
|
6727
|
-
user
|
|
6728
|
-
reviewedBy
|
|
7068
|
+
id String @id @default(cuid())
|
|
7069
|
+
nationalBrandId String // e.g. "national-starbucks" — id from NATIONAL_BIRTHDAY_REWARDS
|
|
7070
|
+
nationalBrandName String // Denormalized for display
|
|
7071
|
+
userId String
|
|
7072
|
+
reportedAt DateTime @default(now())
|
|
7073
|
+
reason String @db.Text
|
|
7074
|
+
suggestedChanges String? @db.Text
|
|
7075
|
+
status RewardReportStatus @default(Pending)
|
|
7076
|
+
reviewedAt DateTime?
|
|
7077
|
+
reviewedById String?
|
|
7078
|
+
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
7079
|
+
reviewedBy User? @relation("NationalChainReportReviewedBy", fields: [reviewedById], references: [id], onDelete: SetNull)
|
|
6729
7080
|
|
|
6730
7081
|
@@index([nationalBrandId])
|
|
6731
7082
|
@@index([userId])
|
|
@@ -6734,22 +7085,22 @@ model NationalChainReport {
|
|
|
6734
7085
|
|
|
6735
7086
|
// Part B: User saved locations (birthday home base, etc.)
|
|
6736
7087
|
model UserLocation {
|
|
6737
|
-
id
|
|
6738
|
-
userId
|
|
6739
|
-
label
|
|
6740
|
-
address1
|
|
6741
|
-
address2
|
|
6742
|
-
city
|
|
6743
|
-
state
|
|
6744
|
-
zip
|
|
6745
|
-
country
|
|
6746
|
-
lat
|
|
6747
|
-
lng
|
|
6748
|
-
isDefault
|
|
6749
|
-
createdAt
|
|
6750
|
-
updatedAt
|
|
6751
|
-
user
|
|
6752
|
-
usersWithBirthdayLocation User[]
|
|
7088
|
+
id String @id @default(cuid())
|
|
7089
|
+
userId String
|
|
7090
|
+
label String? // e.g. "Home", "Work"
|
|
7091
|
+
address1 String
|
|
7092
|
+
address2 String?
|
|
7093
|
+
city String
|
|
7094
|
+
state String
|
|
7095
|
+
zip String
|
|
7096
|
+
country String? @default("US")
|
|
7097
|
+
lat Float?
|
|
7098
|
+
lng Float?
|
|
7099
|
+
isDefault Boolean? @default(false)
|
|
7100
|
+
createdAt DateTime @default(now())
|
|
7101
|
+
updatedAt DateTime @updatedAt
|
|
7102
|
+
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
7103
|
+
usersWithBirthdayLocation User[] @relation("UserBirthdayLocation")
|
|
6753
7104
|
|
|
6754
7105
|
@@index([userId])
|
|
6755
7106
|
}
|
|
@@ -6763,7 +7114,7 @@ enum RedemptionMethod {
|
|
|
6763
7114
|
}
|
|
6764
7115
|
|
|
6765
7116
|
enum BirthdayOfferExpirationType {
|
|
6766
|
-
DAY_OF
|
|
7117
|
+
DAY_OF // End of birthday day
|
|
6767
7118
|
DAYS_FROM_BDAY
|
|
6768
7119
|
END_OF_MONTH
|
|
6769
7120
|
VARIABLE
|
|
@@ -6784,14 +7135,14 @@ enum OfferClaimStatus {
|
|
|
6784
7135
|
}
|
|
6785
7136
|
|
|
6786
7137
|
model Brand {
|
|
6787
|
-
id String
|
|
7138
|
+
id String @id @default(cuid())
|
|
6788
7139
|
name String
|
|
6789
|
-
websiteUrl String?
|
|
6790
|
-
logoUrl String?
|
|
6791
|
-
categoryDefault String?
|
|
6792
|
-
isNational Boolean
|
|
6793
|
-
createdAt DateTime
|
|
6794
|
-
updatedAt DateTime
|
|
7140
|
+
websiteUrl String? @db.Text
|
|
7141
|
+
logoUrl String? @db.Text
|
|
7142
|
+
categoryDefault String? // restaurant, coffee, dessert, retail, entertainment
|
|
7143
|
+
isNational Boolean @default(true)
|
|
7144
|
+
createdAt DateTime @default(now())
|
|
7145
|
+
updatedAt DateTime @updatedAt
|
|
6795
7146
|
offers BirthdayOffer[]
|
|
6796
7147
|
locations BrandLocation[]
|
|
6797
7148
|
|
|
@@ -6799,28 +7150,28 @@ model Brand {
|
|
|
6799
7150
|
}
|
|
6800
7151
|
|
|
6801
7152
|
model BirthdayOffer {
|
|
6802
|
-
id String
|
|
7153
|
+
id String @id @default(cuid())
|
|
6803
7154
|
brandId String
|
|
6804
|
-
title String
|
|
6805
|
-
descriptionShort String?
|
|
6806
|
-
purchaseRequired Boolean
|
|
6807
|
-
signupRequired Boolean
|
|
6808
|
-
appRequired Boolean
|
|
6809
|
-
requiresPhone Boolean
|
|
7155
|
+
title String // e.g. "Free burger reward"
|
|
7156
|
+
descriptionShort String? @db.Text
|
|
7157
|
+
purchaseRequired Boolean @default(false)
|
|
7158
|
+
signupRequired Boolean @default(false)
|
|
7159
|
+
appRequired Boolean @default(false)
|
|
7160
|
+
requiresPhone Boolean @default(false)
|
|
6810
7161
|
redemptionMethod RedemptionMethod
|
|
6811
7162
|
expirationType BirthdayOfferExpirationType
|
|
6812
|
-
expirationDays Int?
|
|
6813
|
-
windowStartOffsetDays Int
|
|
6814
|
-
termsUrl String?
|
|
6815
|
-
termsNotes String?
|
|
7163
|
+
expirationDays Int? // when expirationType = DAYS_FROM_BDAY
|
|
7164
|
+
windowStartOffsetDays Int @default(0)
|
|
7165
|
+
termsUrl String? @db.Text
|
|
7166
|
+
termsNotes String? @db.Text
|
|
6816
7167
|
sourceType BirthdayOfferSourceType
|
|
6817
7168
|
lastVerifiedAt DateTime?
|
|
6818
|
-
isActive Boolean
|
|
6819
|
-
priorityScore Int
|
|
6820
|
-
featuredUntil
|
|
6821
|
-
createdAt DateTime
|
|
6822
|
-
updatedAt DateTime
|
|
6823
|
-
brand Brand
|
|
7169
|
+
isActive Boolean @default(true)
|
|
7170
|
+
priorityScore Int @default(0)
|
|
7171
|
+
featuredUntil DateTime?
|
|
7172
|
+
createdAt DateTime @default(now())
|
|
7173
|
+
updatedAt DateTime @updatedAt
|
|
7174
|
+
brand Brand @relation(fields: [brandId], references: [id], onDelete: Cascade)
|
|
6824
7175
|
claims OfferClaim[]
|
|
6825
7176
|
redemptions BirthdayRewardRedemption[]
|
|
6826
7177
|
|
|
@@ -6849,15 +7200,15 @@ model BrandLocation {
|
|
|
6849
7200
|
}
|
|
6850
7201
|
|
|
6851
7202
|
model OfferClaim {
|
|
6852
|
-
id
|
|
6853
|
-
userId
|
|
6854
|
-
birthdayOfferId
|
|
6855
|
-
claimedAt
|
|
6856
|
-
birthdayYear
|
|
6857
|
-
status
|
|
6858
|
-
meta
|
|
6859
|
-
user
|
|
6860
|
-
birthdayOffer
|
|
7203
|
+
id String @id @default(cuid())
|
|
7204
|
+
userId String
|
|
7205
|
+
birthdayOfferId String
|
|
7206
|
+
claimedAt DateTime @default(now())
|
|
7207
|
+
birthdayYear Int
|
|
7208
|
+
status OfferClaimStatus
|
|
7209
|
+
meta Json?
|
|
7210
|
+
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
7211
|
+
birthdayOffer BirthdayOffer @relation(fields: [birthdayOfferId], references: [id], onDelete: Cascade)
|
|
6861
7212
|
|
|
6862
7213
|
@@index([userId])
|
|
6863
7214
|
@@index([birthdayOfferId])
|
|
@@ -6865,15 +7216,15 @@ model OfferClaim {
|
|
|
6865
7216
|
}
|
|
6866
7217
|
|
|
6867
7218
|
model BirthdayPlan {
|
|
6868
|
-
id
|
|
6869
|
-
userId
|
|
6870
|
-
birthdayYear
|
|
6871
|
-
generatedAt
|
|
6872
|
-
preferencesSnapshot
|
|
6873
|
-
items
|
|
6874
|
-
validFrom
|
|
6875
|
-
validTo
|
|
6876
|
-
user
|
|
7219
|
+
id String @id @default(cuid())
|
|
7220
|
+
userId String
|
|
7221
|
+
birthdayYear Int
|
|
7222
|
+
generatedAt DateTime @default(now())
|
|
7223
|
+
preferencesSnapshot Json // distance, filters, optimizeFor
|
|
7224
|
+
items Json // ordered stops: plannedDate, brandId, offerId, locationId?, distanceFromHome, deadline, purchaseRequired
|
|
7225
|
+
validFrom DateTime
|
|
7226
|
+
validTo DateTime
|
|
7227
|
+
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
6877
7228
|
|
|
6878
7229
|
@@index([userId])
|
|
6879
7230
|
@@index([userId, birthdayYear])
|
|
@@ -6881,12 +7232,12 @@ model BirthdayPlan {
|
|
|
6881
7232
|
|
|
6882
7233
|
// Part B: Geocoding cache to avoid repeated API calls (birthday rewards, UserLocation, etc.)
|
|
6883
7234
|
model GeocodeCache {
|
|
6884
|
-
id
|
|
7235
|
+
id String @id @default(cuid())
|
|
6885
7236
|
addressQuery String @unique // Normalized query string (trimmed, collapsed whitespace)
|
|
6886
7237
|
lat Float
|
|
6887
7238
|
lng Float
|
|
6888
7239
|
normalizedAddress String @db.Text // formatted_address from provider
|
|
6889
|
-
createdAt
|
|
7240
|
+
createdAt DateTime @default(now())
|
|
6890
7241
|
|
|
6891
7242
|
@@index([addressQuery])
|
|
6892
7243
|
}
|
|
@@ -7576,7 +7927,7 @@ model BashAvailability {
|
|
|
7576
7927
|
window BashAvailabilityWindow
|
|
7577
7928
|
city String
|
|
7578
7929
|
state String?
|
|
7579
|
-
customAt DateTime?
|
|
7930
|
+
customAt DateTime? // When window is Custom: specific date/time
|
|
7580
7931
|
expiresAt DateTime
|
|
7581
7932
|
createdAt DateTime @default(now())
|
|
7582
7933
|
updatedAt DateTime @updatedAt
|
|
@@ -7592,7 +7943,7 @@ model BashAvailability {
|
|
|
7592
7943
|
model BashEventPageView {
|
|
7593
7944
|
id String @id @default(cuid())
|
|
7594
7945
|
bashEventId String
|
|
7595
|
-
sessionHash String
|
|
7946
|
+
sessionHash String // hashed IP+UA for dedup
|
|
7596
7947
|
viewedAt DateTime @default(now())
|
|
7597
7948
|
|
|
7598
7949
|
bashEvent BashEvent @relation(fields: [bashEventId], references: [id], onDelete: Cascade)
|
|
@@ -7603,16 +7954,16 @@ model BashEventPageView {
|
|
|
7603
7954
|
// ─── Phase 1: Bash Groups ────────────────────────────────────────────────────
|
|
7604
7955
|
|
|
7605
7956
|
enum GroupVisibility {
|
|
7606
|
-
Private
|
|
7957
|
+
Private // Default: owner curates members
|
|
7607
7958
|
OpenLink // Anyone with the group link can self-join as WantsToGo
|
|
7608
7959
|
}
|
|
7609
7960
|
|
|
7610
7961
|
enum GroupMemberStatus {
|
|
7611
|
-
Going
|
|
7612
|
-
WantsToGo
|
|
7613
|
-
Maybe
|
|
7614
|
-
NotGoing
|
|
7615
|
-
Invited
|
|
7962
|
+
Going // Ticket purchased / attending
|
|
7963
|
+
WantsToGo // Interested, no ticket yet
|
|
7964
|
+
Maybe // Maybe attending (aligns with Invitation maybeDate)
|
|
7965
|
+
NotGoing // Not attending (aligns with Invitation rejectedDate)
|
|
7966
|
+
Invited // Invited by owner, not yet responded
|
|
7616
7967
|
}
|
|
7617
7968
|
|
|
7618
7969
|
// A group of attendees for a specific event
|
|
@@ -7620,11 +7971,11 @@ model EventGroup {
|
|
|
7620
7971
|
id String @id @default(cuid())
|
|
7621
7972
|
bashEventId String
|
|
7622
7973
|
ownerId String
|
|
7623
|
-
name String?
|
|
7624
|
-
maxMembers Int?
|
|
7974
|
+
name String? // e.g. "Steve's Birthday Group", "Weber State Crew"
|
|
7975
|
+
maxMembers Int? // null = unlimited
|
|
7625
7976
|
visibility GroupVisibility @default(Private)
|
|
7626
7977
|
allowAutoJoin Boolean @default(false) // When true, anyone can join instantly; when false, requests require approval
|
|
7627
|
-
promoterId String?
|
|
7978
|
+
promoterId String? // Optional: links to event promoter for display context
|
|
7628
7979
|
createdAt DateTime @default(now())
|
|
7629
7980
|
updatedAt DateTime @updatedAt
|
|
7630
7981
|
|
|
@@ -7644,11 +7995,11 @@ model GroupMember {
|
|
|
7644
7995
|
groupId String
|
|
7645
7996
|
userId String
|
|
7646
7997
|
status GroupMemberStatus @default(Invited)
|
|
7647
|
-
ticketId String?
|
|
7998
|
+
ticketId String? // Set when status = Going
|
|
7648
7999
|
joinedAt DateTime @default(now())
|
|
7649
8000
|
|
|
7650
|
-
group
|
|
7651
|
-
user
|
|
8001
|
+
group EventGroup @relation(fields: [groupId], references: [id], onDelete: Cascade)
|
|
8002
|
+
user User @relation("GroupMemberships", fields: [userId], references: [id], onDelete: Cascade)
|
|
7652
8003
|
|
|
7653
8004
|
@@unique([groupId, userId])
|
|
7654
8005
|
@@index([groupId])
|
|
@@ -7662,18 +8013,18 @@ model GroupMember {
|
|
|
7662
8013
|
|
|
7663
8014
|
// Host-created time-limited offer targeting a specific group
|
|
7664
8015
|
model GroupUnlockOffer {
|
|
7665
|
-
id String
|
|
8016
|
+
id String @id @default(cuid())
|
|
7666
8017
|
bashEventId String
|
|
7667
|
-
ticketTierId String?
|
|
7668
|
-
minGroupSize Int
|
|
7669
|
-
rewardLabel String
|
|
7670
|
-
rewardType String
|
|
8018
|
+
ticketTierId String? // Optional: scoped to a specific tier
|
|
8019
|
+
minGroupSize Int // Minimum members who must buy
|
|
8020
|
+
rewardLabel String // "Free drink", "VIP upgrade", "Free table"
|
|
8021
|
+
rewardType String // FreeDrink | VIPUpgrade | Merch | Custom
|
|
7671
8022
|
expiresAt DateTime
|
|
7672
|
-
maxGroups Int?
|
|
7673
|
-
createdAt DateTime
|
|
8023
|
+
maxGroups Int? // null = unlimited
|
|
8024
|
+
createdAt DateTime @default(now())
|
|
7674
8025
|
|
|
7675
|
-
bashEvent BashEvent
|
|
7676
|
-
ticketTier TicketTier?
|
|
8026
|
+
bashEvent BashEvent @relation(fields: [bashEventId], references: [id], onDelete: Cascade)
|
|
8027
|
+
ticketTier TicketTier? @relation(fields: [ticketTierId], references: [id])
|
|
7677
8028
|
unlocks GroupUnlock[]
|
|
7678
8029
|
|
|
7679
8030
|
@@index([bashEventId])
|
|
@@ -7703,38 +8054,38 @@ enum PartnerTier {
|
|
|
7703
8054
|
}
|
|
7704
8055
|
|
|
7705
8056
|
model PartnerBrand {
|
|
7706
|
-
id
|
|
7707
|
-
name
|
|
7708
|
-
logoUrl
|
|
7709
|
-
websiteUrl
|
|
7710
|
-
description
|
|
7711
|
-
tier
|
|
7712
|
-
isActive
|
|
7713
|
-
affiliateBaseUrl
|
|
7714
|
-
listingFeeMonthly
|
|
7715
|
-
createdAt
|
|
7716
|
-
products
|
|
7717
|
-
adSlots
|
|
8057
|
+
id String @id @default(cuid())
|
|
8058
|
+
name String
|
|
8059
|
+
logoUrl String?
|
|
8060
|
+
websiteUrl String?
|
|
8061
|
+
description String? @db.Text
|
|
8062
|
+
tier PartnerTier @default(Standard)
|
|
8063
|
+
isActive Boolean @default(true)
|
|
8064
|
+
affiliateBaseUrl String?
|
|
8065
|
+
listingFeeMonthly Int? // cents; null = affiliate-only
|
|
8066
|
+
createdAt DateTime @default(now())
|
|
8067
|
+
products PartnerProduct[]
|
|
8068
|
+
adSlots PartnerAdSlot[]
|
|
7718
8069
|
|
|
7719
8070
|
@@index([isActive, tier])
|
|
7720
8071
|
}
|
|
7721
8072
|
|
|
7722
8073
|
model PartnerProduct {
|
|
7723
|
-
id
|
|
7724
|
-
brandId
|
|
7725
|
-
brand
|
|
7726
|
-
name
|
|
7727
|
-
description
|
|
7728
|
-
imageUrl
|
|
7729
|
-
priceSummary
|
|
7730
|
-
affiliateUrl
|
|
7731
|
-
categories
|
|
7732
|
-
isActive
|
|
7733
|
-
sortOrder
|
|
7734
|
-
impressions
|
|
7735
|
-
clicks
|
|
7736
|
-
createdAt
|
|
7737
|
-
adSlots
|
|
8074
|
+
id String @id @default(cuid())
|
|
8075
|
+
brandId String
|
|
8076
|
+
brand PartnerBrand @relation(fields: [brandId], references: [id], onDelete: Cascade)
|
|
8077
|
+
name String
|
|
8078
|
+
description String? @db.Text
|
|
8079
|
+
imageUrl String?
|
|
8080
|
+
priceSummary String?
|
|
8081
|
+
affiliateUrl String
|
|
8082
|
+
categories String[]
|
|
8083
|
+
isActive Boolean @default(true)
|
|
8084
|
+
sortOrder Int @default(0)
|
|
8085
|
+
impressions Int @default(0)
|
|
8086
|
+
clicks Int @default(0)
|
|
8087
|
+
createdAt DateTime @default(now())
|
|
8088
|
+
adSlots PartnerAdSlot[]
|
|
7738
8089
|
|
|
7739
8090
|
@@index([brandId, isActive])
|
|
7740
8091
|
}
|