@bash-app/bash-common 30.118.0 → 30.119.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/dist/definitions.d.ts +3 -0
  2. package/dist/definitions.d.ts.map +1 -1
  3. package/dist/definitions.js.map +1 -1
  4. package/dist/index.d.ts +1 -1
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +1 -1
  7. package/dist/index.js.map +1 -1
  8. package/dist/membershipDefinitions.d.ts +9 -5
  9. package/dist/membershipDefinitions.d.ts.map +1 -1
  10. package/dist/membershipDefinitions.js +28 -24
  11. package/dist/membershipDefinitions.js.map +1 -1
  12. package/dist/utils/bashPointsPaymentUtils.d.ts +55 -0
  13. package/dist/utils/bashPointsPaymentUtils.d.ts.map +1 -0
  14. package/dist/utils/bashPointsPaymentUtils.js +79 -0
  15. package/dist/utils/bashPointsPaymentUtils.js.map +1 -0
  16. package/dist/utils/index.d.ts +1 -1
  17. package/dist/utils/index.d.ts.map +1 -1
  18. package/dist/utils/index.js +1 -1
  19. package/dist/utils/index.js.map +1 -1
  20. package/dist/utils/ticketListUtils.d.ts +2 -1
  21. package/dist/utils/ticketListUtils.d.ts.map +1 -1
  22. package/dist/utils/ticketListUtils.js +61 -11
  23. package/dist/utils/ticketListUtils.js.map +1 -1
  24. package/package.json +1 -1
  25. package/prisma/migrations/add_bashcash_pricing_to_ticket_tier.sql +15 -0
  26. package/prisma/migrations/add_bashpoints_purchase_tracking.sql +33 -0
  27. package/prisma/migrations/add_pricing_type_enum.sql +88 -0
  28. package/prisma/migrations/diagnostic_bashcash_columns.sql +157 -0
  29. package/prisma/migrations/fix_bashcash_referral_code_schema_mismatch.sql +81 -0
  30. package/prisma/migrations/rename_bashcash_to_bashpoints.sql +183 -0
  31. package/prisma/migrations/rename_bashcredits_to_bashpoints.sql +96 -0
  32. package/prisma/schema.prisma +432 -317
  33. package/src/definitions.ts +3 -0
  34. package/src/index.ts +1 -1
  35. package/src/membershipDefinitions.ts +29 -25
  36. package/src/utils/bashPointsPaymentUtils.ts +107 -0
  37. package/src/utils/index.ts +1 -1
  38. package/src/utils/ticketListUtils.ts +64 -10
  39. package/src/utils/bashCashPaymentUtils.ts +0 -146
@@ -342,7 +342,7 @@ model EventTask {
342
342
  neededCount Int? // Number of volunteers needed
343
343
  estimatedDuration Int? // Estimated duration in minutes
344
344
  createdAt DateTime? @default(now())
345
- organizationId String? // Organization association
345
+ organizationId String? // Organization association
346
346
  assignedTo User? @relation("TasksAssignedToMe", fields: [assignedToId], references: [id], onDelete: Cascade)
347
347
  bashEvent BashEvent @relation(fields: [bashEventId], references: [id], onDelete: Cascade)
348
348
  creator User @relation(fields: [creatorId], references: [id], onDelete: Cascade)
@@ -552,99 +552,99 @@ model Invitation {
552
552
  }
553
553
 
554
554
  model BashEvent {
555
- id String @id @default(cuid())
556
- source BashEventSource @default(Bash)
557
- title String
558
- slug String? @unique
559
- creatorId String
560
- createdAt DateTime? @default(now())
561
- isApproved Boolean? @default(false)
562
- description String?
563
- eventType String @default("Other")
564
- timezone String?
565
- startDateTime DateTime?
566
- endDateTime DateTime?
567
- waiverUrl String?
568
- waiverRequired Boolean @default(false)
569
- waiverDisplayType String? @default("inline")
570
- targetAudienceId String? @unique
571
- amountOfGuestsId String? @unique
572
- vibe String?
573
- occasion String?
574
- dress String?
575
- allowed String?
576
- notAllowed String?
577
- eventFormat EventFormat? // Derived from location and videoLink: In-Person, Virtual, or Hybrid
578
- nonProfit Boolean?
579
- nonProfitId String?
580
- privacy Privacy @default(Public)
581
- capacity Int?
582
- location String?
583
- street String?
584
- city String?
585
- state String?
586
- zipCode String?
587
- country String?
588
- status BashStatus @default(Draft)
589
- tags String[]
590
- coverPhoto String?
591
- clubId String?
592
- dateTimePublished DateTime?
593
- includedItems String[]
594
- videoLink String?
595
- subtitle String?
596
- isFeatured Boolean?
597
- isTrending Boolean?
598
- venueId String?
599
- averageRating Float? @default(0)
600
- totalRatings Int? @default(0) // Total count of all ratings (Review + BashFeedRating)
601
- totalReviews Int? @default(0) // Count of Review records (anonymous quick ratings)
602
- totalFeedRatings Int? @default(0) // Count of BashFeedRating records (from posts)
603
- allowDonations Boolean? @default(true)
604
- suggestedDonationAmount Int?
605
- donationDetails String?
606
- absorbDonationFees Boolean @default(false)
607
- absorbTicketFees Boolean @default(false)
608
- showAttendees Boolean @default(true)
609
- servicePreferences Json? // New tiered status: { "Entertainment": "need", "Sponsors": "booked_closed", ... }
610
- bookedServices Json? // Booked service details: { "Entertainment": { serviceId: "...", providerId: "...", bookedAt: "..." }, ... }
611
- serviceVisibility Json? // DEPRECATED: Use servicePreferences instead. Kept for backward compatibility during migration.
612
- originalCreatorId String?
613
- transferredAt DateTime?
614
- transferredFromId String?
615
- transferCount Int @default(0)
616
- startTimeLocked Boolean @default(false)
617
- p2pPaymentMethod String?
618
- venmoUsername String?
619
- venmoQRCodeUrl String?
620
- zelleEmail String?
621
- zellePhone String?
622
- zelleQRCodeUrl String?
623
- externalTicketUrl String? // URL to external ticket purchase page (for imported events)
624
- externalPriceMin Int? // Minimum ticket price in cents (for imported events)
625
- externalPriceMax Int? // Maximum ticket price in cents (for imported events)
626
- externalPriceSummary String? // Human-readable price summary e.g., "$50 - $150" or "$75"
627
- customTermsAndConditions String?
628
- itinerary Json? // Array of { id: string, title: string, startTime: string, endTime: string, description?: string }
629
-
555
+ id String @id @default(cuid())
556
+ source BashEventSource @default(Bash)
557
+ title String
558
+ slug String? @unique
559
+ creatorId String
560
+ createdAt DateTime? @default(now())
561
+ isApproved Boolean? @default(false)
562
+ description String?
563
+ eventType String @default("Other")
564
+ timezone String?
565
+ startDateTime DateTime?
566
+ endDateTime DateTime?
567
+ waiverUrl String?
568
+ waiverRequired Boolean @default(false)
569
+ waiverDisplayType String? @default("inline")
570
+ targetAudienceId String? @unique
571
+ amountOfGuestsId String? @unique
572
+ vibe String?
573
+ occasion String?
574
+ dress String?
575
+ allowed String?
576
+ notAllowed String?
577
+ eventFormat EventFormat? // Derived from location and videoLink: In-Person, Virtual, or Hybrid
578
+ nonProfit Boolean?
579
+ nonProfitId String?
580
+ privacy Privacy @default(Public)
581
+ capacity Int?
582
+ location String?
583
+ street String?
584
+ city String?
585
+ state String?
586
+ zipCode String?
587
+ country String?
588
+ status BashStatus @default(Draft)
589
+ tags String[]
590
+ coverPhoto String?
591
+ clubId String?
592
+ dateTimePublished DateTime?
593
+ includedItems String[]
594
+ videoLink String?
595
+ subtitle String?
596
+ isFeatured Boolean?
597
+ isTrending Boolean?
598
+ venueId String?
599
+ averageRating Float? @default(0)
600
+ totalRatings Int? @default(0) // Total count of all ratings (Review + BashFeedRating)
601
+ totalReviews Int? @default(0) // Count of Review records (anonymous quick ratings)
602
+ totalFeedRatings Int? @default(0) // Count of BashFeedRating records (from posts)
603
+ allowDonations Boolean? @default(true)
604
+ suggestedDonationAmount Int?
605
+ donationDetails String?
606
+ absorbDonationFees Boolean @default(false)
607
+ absorbTicketFees Boolean @default(false)
608
+ showAttendees Boolean @default(true)
609
+ servicePreferences Json? // New tiered status: { "Entertainment": "need", "Sponsors": "booked_closed", ... }
610
+ bookedServices Json? // Booked service details: { "Entertainment": { serviceId: "...", providerId: "...", bookedAt: "..." }, ... }
611
+ serviceVisibility Json? // DEPRECATED: Use servicePreferences instead. Kept for backward compatibility during migration.
612
+ originalCreatorId String?
613
+ transferredAt DateTime?
614
+ transferredFromId String?
615
+ transferCount Int @default(0)
616
+ startTimeLocked Boolean @default(false)
617
+ p2pPaymentMethod String?
618
+ venmoUsername String?
619
+ venmoQRCodeUrl String?
620
+ zelleEmail String?
621
+ zellePhone String?
622
+ zelleQRCodeUrl String?
623
+ externalTicketUrl String? // URL to external ticket purchase page (for imported events)
624
+ externalPriceMin Int? // Minimum ticket price in cents (for imported events)
625
+ externalPriceMax Int? // Maximum ticket price in cents (for imported events)
626
+ externalPriceSummary String? // Human-readable price summary e.g., "$50 - $150" or "$75"
627
+ customTermsAndConditions String?
628
+ itinerary Json? // Array of { id: string, title: string, startTime: string, endTime: string, description?: string }
629
+
630
630
  // Idea-specific fields (only used when status = 'Idea')
631
- ideaExpiresAt DateTime?
632
- ideaInterestThreshold Int? @default(35)
633
- hideInterestCount Boolean @default(false)
634
- isAutoApprovable Boolean @default(false)
635
- autoApprovedAt DateTime?
636
- lastEngagementAt DateTime? // Track last interest/share for decay
637
-
631
+ ideaExpiresAt DateTime?
632
+ ideaInterestThreshold Int? @default(35)
633
+ hideInterestCount Boolean @default(false)
634
+ isAutoApprovable Boolean @default(false)
635
+ autoApprovedAt DateTime?
636
+ lastEngagementAt DateTime? // Track last interest/share for decay
637
+
638
638
  // Organization field
639
- organizationId String?
640
- organization Organization? @relation("OrganizationBashEvents", fields: [organizationId], references: [id])
641
-
639
+ organizationId String?
640
+ organization Organization? @relation("OrganizationBashEvents", fields: [organizationId], references: [id])
641
+
642
642
  // Organization access controls (only apply when organizationId is set)
643
- requiresOrgMembership Boolean @default(false) // Must be member to attend/RSVP
644
- allowMemberGuests Boolean @default(false) // Members can bring +1s
645
- maxGuestsPerMember Int? // Guest limit per member (null = unlimited)
646
- restrictToOrgDepartments String[] @default([]) // Empty = all departments can see/join
647
-
643
+ requiresOrgMembership Boolean @default(false) // Must be member to attend/RSVP
644
+ allowMemberGuests Boolean @default(false) // Members can bring +1s
645
+ maxGuestsPerMember Int? // Guest limit per member (null = unlimited)
646
+ restrictToOrgDepartments String[] @default([]) // Empty = all departments can see/join
647
+
648
648
  associatedBashesReferencingMe AssociatedBash[]
649
649
  comments BashComment[]
650
650
  amountOfGuests AmountOfGuests? @relation(fields: [amountOfGuestsId], references: [id], onDelete: Cascade)
@@ -697,17 +697,17 @@ model BashEvent {
697
697
  bashFeedPosts BashFeedPost[]
698
698
  bashFeedRatings BashFeedRating[]
699
699
  eventRankings EventRankings?
700
-
700
+
701
701
  // Idea Relations
702
- interests IdeaInterest[]
703
- configurations IdeaConfiguration[]
702
+ interests IdeaInterest[]
703
+ configurations IdeaConfiguration[]
704
704
 
705
705
  // Analytics Relations
706
706
  analyticsPredictions AnalyticsPrediction[]
707
-
707
+
708
708
  // Organization Relations
709
- budgets Budget[] @relation("EventBudgets")
710
- rsvps EventRSVP[] @relation("EventRSVPs")
709
+ budgets Budget[] @relation("EventBudgets")
710
+ rsvps EventRSVP[] @relation("EventRSVPs")
711
711
 
712
712
  @@index([templateId])
713
713
  @@index([parentEventId])
@@ -719,22 +719,22 @@ model BashEvent {
719
719
  // ============================================
720
720
 
721
721
  model IdeaInterest {
722
- id String @id @default(cuid())
722
+ id String @id @default(cuid())
723
723
  bashEventId String
724
724
  email String
725
725
  phone String?
726
- source String? // 'tiktok_bio', 'bashfeed', 'share', 'direct'
727
- ipAddress String? // For fraud prevention
726
+ source String? // 'tiktok_bio', 'bashfeed', 'share', 'direct'
727
+ ipAddress String? // For fraud prevention
728
728
  userAgent String?
729
- convertedToUserId String? // If they later create account
730
- createdAt DateTime @default(now())
731
- updatedAt DateTime @updatedAt
732
-
729
+ convertedToUserId String? // If they later create account
730
+ createdAt DateTime @default(now())
731
+ updatedAt DateTime @updatedAt
732
+
733
733
  // Relationships
734
- bashEvent BashEvent @relation(fields: [bashEventId], references: [id], onDelete: Cascade)
735
- user User? @relation(fields: [convertedToUserId], references: [id])
736
- responses IdeaInterestResponse[]
737
-
734
+ bashEvent BashEvent @relation(fields: [bashEventId], references: [id], onDelete: Cascade)
735
+ user User? @relation(fields: [convertedToUserId], references: [id])
736
+ responses IdeaInterestResponse[]
737
+
738
738
  @@unique([bashEventId, email])
739
739
  @@index([bashEventId])
740
740
  @@index([email])
@@ -742,38 +742,38 @@ model IdeaInterest {
742
742
  }
743
743
 
744
744
  model IdeaInterestResponse {
745
- id String @id @default(cuid())
745
+ id String @id @default(cuid())
746
746
  interestId String
747
- questionType String // 'base_price', 'configuration_price', 'preferred_date', 'must_have'
748
- questionText String? // For custom host questions
749
- responseValue String // JSON: {min: 20, max: 50} or "Yes" or date string
750
- configurationId String? // Links to specific configuration if applicable
751
- createdAt DateTime @default(now())
752
-
747
+ questionType String // 'base_price', 'configuration_price', 'preferred_date', 'must_have'
748
+ questionText String? // For custom host questions
749
+ responseValue String // JSON: {min: 20, max: 50} or "Yes" or date string
750
+ configurationId String? // Links to specific configuration if applicable
751
+ createdAt DateTime @default(now())
752
+
753
753
  // Relationships
754
- interest IdeaInterest @relation(fields: [interestId], references: [id], onDelete: Cascade)
755
- configuration IdeaConfiguration? @relation(fields: [configurationId], references: [id], onDelete: SetNull)
756
-
754
+ interest IdeaInterest @relation(fields: [interestId], references: [id], onDelete: Cascade)
755
+ configuration IdeaConfiguration? @relation(fields: [configurationId], references: [id], onDelete: SetNull)
756
+
757
757
  @@index([interestId])
758
758
  @@index([configurationId])
759
759
  @@index([questionType])
760
760
  }
761
761
 
762
762
  model IdeaConfiguration {
763
- id String @id @default(cuid())
764
- bashEventId String
765
- name String // "Premium Open Bar", "Food Truck", "Live DJ"
766
- description String?
767
- estimatedCost Int? // In cents - helps host with pricing
768
- isActive Boolean @default(true)
769
- sortOrder Int @default(0)
770
- createdAt DateTime @default(now())
771
- updatedAt DateTime @updatedAt
772
-
763
+ id String @id @default(cuid())
764
+ bashEventId String
765
+ name String // "Premium Open Bar", "Food Truck", "Live DJ"
766
+ description String?
767
+ estimatedCost Int? // In cents - helps host with pricing
768
+ isActive Boolean @default(true)
769
+ sortOrder Int @default(0)
770
+ createdAt DateTime @default(now())
771
+ updatedAt DateTime @updatedAt
772
+
773
773
  // Relationships
774
- bashEvent BashEvent @relation(fields: [bashEventId], references: [id], onDelete: Cascade)
775
- responses IdeaInterestResponse[]
776
-
774
+ bashEvent BashEvent @relation(fields: [bashEventId], references: [id], onDelete: Cascade)
775
+ responses IdeaInterestResponse[]
776
+
777
777
  @@index([bashEventId])
778
778
  @@index([isActive])
779
779
  }
@@ -944,12 +944,16 @@ model TicketTier {
944
944
  waitList User[] @relation("TicketTierToUser")
945
945
  specialOffers SpecialOffer[] // NEW - Special offers for this tier
946
946
  appliedDiscounts AppliedDiscount[] // NEW - Discounts applied to this tier
947
-
947
+
948
+ // BashPoints Pricing (peer-to-peer economy)
949
+ pricingType PricingType @default(USD) // 'USD' or 'BASHPOINTS'
950
+ priceBashPoints Int? // Price in BashPoints (if pricingType='BASHPOINTS')
951
+
948
952
  // Organization member restrictions (for org events)
949
- restrictedToRoles String[] @default([]) // ["Admin", "Owner"] - empty = all roles
950
- restrictedToDepartments String[] @default([]) // [deptId1, deptId2] - empty = all departments
953
+ restrictedToRoles String[] @default([]) // ["Admin", "Owner"] - empty = all roles
954
+ restrictedToDepartments String[] @default([]) // [deptId1, deptId2] - empty = all departments
951
955
  restrictedToMembershipTiers String[] @default([]) // ["Premium"] - empty = all membership tiers
952
- isGuestTier Boolean @default(false) // Ticket for member +1s
956
+ isGuestTier Boolean @default(false) // Ticket for member +1s
953
957
 
954
958
  @@unique([bashEventId, title])
955
959
  }
@@ -985,6 +989,12 @@ model Ticket {
985
989
  lastValidationAttempt DateTime?
986
990
  lastValidatedBy String?
987
991
  waitlistUserId String?
992
+
993
+ // BashPoints Purchase Tracking
994
+ purchaseType String? // "USD", "BashPoints", "Free", "Comp"
995
+ pointsPaid Int? // BashPoints amount paid (if purchaseType="BashPoints")
996
+ stripePurchaseId String? // Stripe payment ID (if purchaseType="USD")
997
+
988
998
  bashEvent BashEvent @relation(fields: [bashEventId], references: [id])
989
999
  checkout Checkout? @relation(fields: [checkoutId], references: [id])
990
1000
  forUser User? @relation("TicketsISent", fields: [forUserId], references: [id])
@@ -1201,29 +1211,29 @@ model Prize {
1201
1211
  claimedAt DateTime? // When the prize was claimed
1202
1212
 
1203
1213
  // Automatic payment fields
1204
- autoPayEnabled Boolean @default(false)
1205
- paymentMethod PrizePaymentMethod?
1206
- paymentStatus PrizePaymentStatus @default(Pending)
1207
- bashCashTransactionId String?
1208
- venmoTransactionId String?
1209
- zelleTransactionId String?
1210
- paidAmount Float?
1211
- paidAt DateTime?
1212
- paymentError String? @db.Text
1213
- paymentNotes String? @db.Text
1214
+ autoPayEnabled Boolean @default(false)
1215
+ paymentMethod PrizePaymentMethod?
1216
+ paymentStatus PrizePaymentStatus @default(Pending)
1217
+ bashPointsTransactionId String?
1218
+ venmoTransactionId String?
1219
+ zelleTransactionId String?
1220
+ paidAmount Float?
1221
+ paidAt DateTime?
1222
+ paymentError String? @db.Text
1223
+ paymentNotes String? @db.Text
1214
1224
 
1215
1225
  // Winner payment info (for P2P)
1216
1226
  winnerVenmoUsername String?
1217
1227
  winnerZelleEmail String?
1218
1228
  winnerZellePhone String?
1219
1229
 
1220
- competition Competition? @relation(fields: [competitionId], references: [id], onDelete: Cascade)
1221
- winner User? @relation(fields: [winnerUserId], references: [id], onDelete: Cascade)
1222
- bashCashTransaction BashCreditTransaction? @relation(fields: [bashCashTransactionId], references: [id], onDelete: SetNull)
1230
+ competition Competition? @relation(fields: [competitionId], references: [id], onDelete: Cascade)
1231
+ winner User? @relation(fields: [winnerUserId], references: [id], onDelete: Cascade)
1232
+ bashPointsTransaction BashCreditTransaction? @relation(fields: [bashPointsTransactionId], references: [id], onDelete: SetNull)
1223
1233
 
1224
1234
  @@index([competitionId])
1225
1235
  @@index([winnerUserId]) // For fetching user's wins
1226
- @@index([bashCashTransactionId])
1236
+ @@index([bashPointsTransactionId])
1227
1237
  }
1228
1238
 
1229
1239
  model Review {
@@ -1388,11 +1398,11 @@ model User {
1388
1398
  totalServiceReferrals Int @default(0)
1389
1399
  fcmTokens String[] @default([]) // Firebase Cloud Messaging tokens for push notifications
1390
1400
 
1391
- // BashCash System Fields
1392
- bashCreditsBalance Int @default(0)
1393
- bashCreditsEarnedLifetime Int @default(0)
1394
- bashCreditsSpentLifetime Int @default(0)
1395
- bashCashReferralCode String? @unique
1401
+ // BashPoints System Fields
1402
+ bashPointsBalance Int @default(0)
1403
+ bashPointsEarnedLifetime Int @default(0)
1404
+ bashPointsSpentLifetime Int @default(0)
1405
+ bashPointsReferralCode String? @unique
1396
1406
  referredById String?
1397
1407
  referralPurchaseCredited Boolean @default(false)
1398
1408
 
@@ -1513,7 +1523,7 @@ model User {
1513
1523
  // Special Offers - Discount Attribution
1514
1524
  discountAttributions AppliedDiscount[] @relation("DiscountAttribution")
1515
1525
 
1516
- // BashCash Referral Relations
1526
+ // BashPoints Referral Relations
1517
1527
  referredBy User? @relation("Referrals", fields: [referredById], references: [id])
1518
1528
  referrals User[] @relation("Referrals")
1519
1529
 
@@ -1533,21 +1543,26 @@ model User {
1533
1543
  nominationsGiven Nomination[] @relation("NominatingUser")
1534
1544
  votesGiven NominationVote[]
1535
1545
  categoriesCreated NominationCategory[]
1536
-
1546
+
1537
1547
  // Idea Interest Relations
1538
1548
  ideaInterests IdeaInterest[]
1539
-
1549
+
1540
1550
  // Organization Relations
1541
- ownedOrganizations Organization[] @relation("OrganizationOwner")
1542
- organizationMemberships OrganizationMember[] @relation("OrganizationMemberUser")
1543
- organizationEventRSVPs EventRSVP[] @relation("OrganizationEventRSVP")
1544
- submittedExpenses Expense[] @relation("ExpenseSubmitter")
1545
- approvedExpenses Expense[] @relation("ExpenseApprover")
1546
- approvedBudgets Budget[] @relation("BudgetApprover")
1547
- submittedBudgets Budget[] @relation("BudgetSubmitter")
1548
- ownedBudgets Budget[] @relation("UserBudgets")
1549
- departmentsHeaded Department[] @relation("DepartmentHead")
1550
- favoriteOrganizations Organization[] @relation("FavoriteOrganizations")
1551
+ ownedOrganizations Organization[] @relation("OrganizationOwner")
1552
+ organizationMemberships OrganizationMember[] @relation("OrganizationMemberUser")
1553
+ organizationEventRSVPs EventRSVP[] @relation("OrganizationEventRSVP")
1554
+ submittedExpenses Expense[] @relation("ExpenseSubmitter")
1555
+ approvedExpenses Expense[] @relation("ExpenseApprover")
1556
+ approvedBudgets Budget[] @relation("BudgetApprover")
1557
+ submittedBudgets Budget[] @relation("BudgetSubmitter")
1558
+ ownedBudgets Budget[] @relation("UserBudgets")
1559
+ departmentsHeaded Department[] @relation("DepartmentHead")
1560
+ favoriteOrganizations Organization[] @relation("FavoriteOrganizations")
1561
+
1562
+ // Service Includes & Add-On Requests
1563
+ suggestedIncludes ServiceInclude[] @relation("SuggestedIncludes")
1564
+ includeVotes ServiceIncludeVote[]
1565
+ requestedAddons ServiceAddonRequest[] @relation("RequestedAddons")
1551
1566
  }
1552
1567
 
1553
1568
  model UserPreferences {
@@ -1989,7 +2004,7 @@ model Service {
1989
2004
  isFreeFirstListing Boolean @default(false)
1990
2005
  monthlyPrice Decimal @default(0)
1991
2006
  serviceListingStripeSubscriptionId String?
1992
- acceptsBashCash Boolean @default(true) // NEW: Allow BashCash payments
2007
+ acceptsBashPoints Boolean @default(true) // NEW: Allow BashPoints payments
1993
2008
  isVerified Boolean @default(false) // Service owner verified
1994
2009
  isLicensed Boolean @default(false) // Has required licenses
1995
2010
  verifiedAt DateTime? // When verification was approved
@@ -2028,6 +2043,8 @@ model Service {
2028
2043
  bookingCommissions BookingCommission[] @relation("CommissionServiceProfile")
2029
2044
  venueMatches VenueEntertainmentMatch[] @relation("VenueMatches")
2030
2045
  entertainerMatches VenueEntertainmentMatch[] @relation("EntertainerMatches")
2046
+ includes ServiceInclude[]
2047
+ addonRequests ServiceAddonRequest[]
2031
2048
 
2032
2049
  @@index([serviceListingStripeSubscriptionId])
2033
2050
  @@index([isFreeFirstListing])
@@ -2364,53 +2381,53 @@ model UserPromoCodeRedemption {
2364
2381
  }
2365
2382
 
2366
2383
  model Organization {
2367
- id String @id @default(cuid())
2368
- name String
2369
- slug String @unique
2370
- organizationType OrganizationType[]
2371
- bio String?
2372
- mission String?
2373
- pocName String?
2374
- pocEmail String?
2375
- pocPhone String?
2376
- street String?
2377
- city String?
2378
- state String?
2379
- zipCode String?
2380
- country String? @default("US")
2381
- coverPhoto String?
2382
- logoUrl String?
2383
- websiteUrl String?
2384
- socialLinks Json?
2385
- goodsOrServices String[]
2386
- venueTypes String[]
2387
- secondaryVenueTypes String[] @default([])
2388
- baseMembershipPriceCents Int?
2389
- premiumMembershipPriceCents Int?
2390
- allowGuestsByDefault Boolean @default(false)
2391
- defaultGuestLimit Int @default(0)
2392
- visibility String @default("Public")
2393
- requiresApproval Boolean @default(true)
2394
- memberAutoApproval Boolean @default(false)
2395
- ownerId String
2396
- parentOrganizationId String?
2397
- departmentName String?
2398
- hierarchyLevel Int @default(0)
2399
- subscriptionTier String?
2400
- subscriptionStatus String?
2401
- stripeSubscriptionId String? @unique
2402
- stripeCustomerId String?
2403
- createdAt DateTime @default(now())
2404
- updatedAt DateTime @updatedAt
2405
- service Service?
2406
- owner User @relation("OrganizationOwner", fields: [ownerId], references: [id], onDelete: Restrict)
2407
- parentOrganization Organization? @relation("OrganizationHierarchy", fields: [parentOrganizationId], references: [id])
2408
- childOrganizations Organization[] @relation("OrganizationHierarchy")
2409
- members OrganizationMember[]
2410
- budgets Budget[] @relation("OrganizationBudgets")
2411
- departments Department[]
2412
- bashEvents BashEvent[] @relation("OrganizationBashEvents")
2413
- favoriteBy User[] @relation("FavoriteOrganizations")
2384
+ id String @id @default(cuid())
2385
+ name String
2386
+ slug String @unique
2387
+ organizationType OrganizationType[]
2388
+ bio String?
2389
+ mission String?
2390
+ pocName String?
2391
+ pocEmail String?
2392
+ pocPhone String?
2393
+ street String?
2394
+ city String?
2395
+ state String?
2396
+ zipCode String?
2397
+ country String? @default("US")
2398
+ coverPhoto String?
2399
+ logoUrl String?
2400
+ websiteUrl String?
2401
+ socialLinks Json?
2402
+ goodsOrServices String[]
2403
+ venueTypes String[]
2404
+ secondaryVenueTypes String[] @default([])
2405
+ baseMembershipPriceCents Int?
2406
+ premiumMembershipPriceCents Int?
2407
+ allowGuestsByDefault Boolean @default(false)
2408
+ defaultGuestLimit Int @default(0)
2409
+ visibility String @default("Public")
2410
+ requiresApproval Boolean @default(true)
2411
+ memberAutoApproval Boolean @default(false)
2412
+ ownerId String
2413
+ parentOrganizationId String?
2414
+ departmentName String?
2415
+ hierarchyLevel Int @default(0)
2416
+ subscriptionTier String?
2417
+ subscriptionStatus String?
2418
+ stripeSubscriptionId String? @unique
2419
+ stripeCustomerId String?
2420
+ createdAt DateTime @default(now())
2421
+ updatedAt DateTime @updatedAt
2422
+ service Service?
2423
+ owner User @relation("OrganizationOwner", fields: [ownerId], references: [id], onDelete: Restrict)
2424
+ parentOrganization Organization? @relation("OrganizationHierarchy", fields: [parentOrganizationId], references: [id])
2425
+ childOrganizations Organization[] @relation("OrganizationHierarchy")
2426
+ members OrganizationMember[]
2427
+ budgets Budget[] @relation("OrganizationBudgets")
2428
+ departments Department[]
2429
+ bashEvents BashEvent[] @relation("OrganizationBashEvents")
2430
+ favoriteBy User[] @relation("FavoriteOrganizations")
2414
2431
 
2415
2432
  @@index([ownerId])
2416
2433
  @@index([slug])
@@ -2444,40 +2461,39 @@ model OrganizationMember {
2444
2461
  }
2445
2462
 
2446
2463
  model Department {
2447
- id String @id @default(cuid())
2448
- organizationId String
2449
- name String
2450
- description String?
2451
- parentDeptId String?
2452
- headUserId String?
2453
- budgetCents Int?
2454
- createdAt DateTime @default(now())
2455
- updatedAt DateTime @updatedAt
2456
- organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
2457
- parentDept Department? @relation("DepartmentHierarchy", fields: [parentDeptId], references: [id])
2458
- childDepts Department[] @relation("DepartmentHierarchy")
2459
- head User? @relation("DepartmentHead", fields: [headUserId], references: [id])
2460
- budgets Budget[] @relation("DepartmentBudgets")
2464
+ id String @id @default(cuid())
2465
+ organizationId String
2466
+ name String
2467
+ description String?
2468
+ parentDeptId String?
2469
+ headUserId String?
2470
+ budgetCents Int?
2471
+ createdAt DateTime @default(now())
2472
+ updatedAt DateTime @updatedAt
2473
+ organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
2474
+ parentDept Department? @relation("DepartmentHierarchy", fields: [parentDeptId], references: [id])
2475
+ childDepts Department[] @relation("DepartmentHierarchy")
2476
+ head User? @relation("DepartmentHead", fields: [headUserId], references: [id])
2477
+ budgets Budget[] @relation("DepartmentBudgets")
2461
2478
 
2462
2479
  @@index([organizationId])
2463
2480
  @@index([parentDeptId])
2464
2481
  }
2465
2482
 
2466
-
2467
2483
  model EventRSVP {
2468
- id String @id @default(cuid())
2469
- eventId String
2470
- memberId String
2471
- userId String
2472
- status String @default("Going") // Going, Maybe, NotGoing
2473
- guestsCount Int @default(0)
2474
- checkedIn Boolean @default(false)
2475
- checkedInAt DateTime?
2476
- createdAt DateTime @default(now())
2477
- updatedAt DateTime @updatedAt
2478
- event BashEvent @relation("EventRSVPs", fields: [eventId], references: [id], onDelete: Cascade)
2479
- member OrganizationMember @relation(fields: [memberId], references: [id], onDelete: Cascade)
2480
- user User @relation("OrganizationEventRSVP", fields: [userId], references: [id])
2484
+ id String @id @default(cuid())
2485
+ eventId String
2486
+ memberId String
2487
+ userId String
2488
+ status String @default("Going") // Going, Maybe, NotGoing
2489
+ guestsCount Int @default(0)
2490
+ checkedIn Boolean @default(false)
2491
+ checkedInAt DateTime?
2492
+ createdAt DateTime @default(now())
2493
+ updatedAt DateTime @updatedAt
2494
+ event BashEvent @relation("EventRSVPs", fields: [eventId], references: [id], onDelete: Cascade)
2495
+ member OrganizationMember @relation(fields: [memberId], references: [id], onDelete: Cascade)
2496
+ user User @relation("OrganizationEventRSVP", fields: [userId], references: [id])
2481
2497
 
2482
2498
  @@unique([eventId, userId])
2483
2499
  @@index([eventId])
@@ -2485,50 +2501,50 @@ model EventRSVP {
2485
2501
  }
2486
2502
 
2487
2503
  model Budget {
2488
- id String @id @default(cuid())
2489
- name String
2490
-
2504
+ id String @id @default(cuid())
2505
+ name String
2506
+
2491
2507
  // Flexible ownership - at least ONE should be set
2492
- organizationId String?
2493
- bashEventId String?
2494
- clubId String?
2495
- departmentId String?
2496
- userId String? // For personal event budgets
2497
-
2508
+ organizationId String?
2509
+ bashEventId String?
2510
+ clubId String?
2511
+ departmentId String?
2512
+ userId String? // For personal event budgets
2513
+
2498
2514
  // Budget details
2499
- totalAllocatedCents Int
2500
- totalBudgetCents Int? // Alias for backward compatibility
2501
- spentCents Int @default(0)
2502
- remainingCents Int? // Can be computed: totalAllocatedCents - spentCents
2503
-
2515
+ totalAllocatedCents Int
2516
+ totalBudgetCents Int? // Alias for backward compatibility
2517
+ spentCents Int @default(0)
2518
+ remainingCents Int? // Can be computed: totalAllocatedCents - spentCents
2519
+
2504
2520
  // Categorization
2505
- category String? // "Marketing", "Catering", "Venue", "Annual", "Activities"
2506
- fiscalYear String? // Keep as String for flexibility ("2026", "2026-Q1", "FY2026")
2507
-
2521
+ category String? // "Marketing", "Catering", "Venue", "Annual", "Activities"
2522
+ fiscalYear String? // Keep as String for flexibility ("2026", "2026-Q1", "FY2026")
2523
+
2508
2524
  // Approval workflow
2509
- status String? @default("Draft") // Draft, Submitted, Approved, Active, Closed, Archived
2510
- submittedBy String?
2511
- approverId String?
2512
- approvedBy String? // Alias for approverId
2513
- approvedAt DateTime?
2514
-
2525
+ status String? @default("Draft") // Draft, Submitted, Approved, Active, Closed, Archived
2526
+ submittedBy String?
2527
+ approverId String?
2528
+ approvedBy String? // Alias for approverId
2529
+ approvedAt DateTime?
2530
+
2515
2531
  // Date ranges
2516
- startDate DateTime?
2517
- endDate DateTime?
2518
-
2532
+ startDate DateTime?
2533
+ endDate DateTime?
2534
+
2519
2535
  // Timestamps
2520
- createdAt DateTime @default(now())
2521
- updatedAt DateTime @updatedAt
2522
-
2536
+ createdAt DateTime @default(now())
2537
+ updatedAt DateTime @updatedAt
2538
+
2523
2539
  // Relations
2524
- organization Organization? @relation("OrganizationBudgets", fields: [organizationId], references: [id], onDelete: Cascade)
2525
- bashEvent BashEvent? @relation("EventBudgets", fields: [bashEventId], references: [id], onDelete: Cascade)
2526
- club Club? @relation("ClubBudgets", fields: [clubId], references: [id], onDelete: Cascade)
2527
- department Department? @relation("DepartmentBudgets", fields: [departmentId], references: [id], onDelete: Cascade)
2528
- user User? @relation("UserBudgets", fields: [userId], references: [id], onDelete: Cascade)
2529
- submitter User? @relation("BudgetSubmitter", fields: [submittedBy], references: [id])
2530
- approver User? @relation("BudgetApprover", fields: [approverId], references: [id])
2531
- expenses Expense[]
2540
+ organization Organization? @relation("OrganizationBudgets", fields: [organizationId], references: [id], onDelete: Cascade)
2541
+ bashEvent BashEvent? @relation("EventBudgets", fields: [bashEventId], references: [id], onDelete: Cascade)
2542
+ club Club? @relation("ClubBudgets", fields: [clubId], references: [id], onDelete: Cascade)
2543
+ department Department? @relation("DepartmentBudgets", fields: [departmentId], references: [id], onDelete: Cascade)
2544
+ user User? @relation("UserBudgets", fields: [userId], references: [id], onDelete: Cascade)
2545
+ submitter User? @relation("BudgetSubmitter", fields: [submittedBy], references: [id])
2546
+ approver User? @relation("BudgetApprover", fields: [approverId], references: [id])
2547
+ expenses Expense[]
2532
2548
 
2533
2549
  @@index([organizationId])
2534
2550
  @@index([bashEventId])
@@ -2540,23 +2556,23 @@ model Budget {
2540
2556
  }
2541
2557
 
2542
2558
  model Expense {
2543
- id String @id @default(cuid())
2544
- budgetId String
2545
- submittedBy String
2546
- description String
2547
- amountCents Int
2548
- category String?
2549
- receiptUrl String?
2550
- expenseDate DateTime? // When the expense occurred
2551
- status String @default("Pending") // Pending, Approved, Rejected
2552
- approvedBy String?
2553
- approvedAt DateTime?
2554
- rejectionReason String?
2555
- createdAt DateTime @default(now())
2556
- updatedAt DateTime @updatedAt
2557
- budget Budget @relation(fields: [budgetId], references: [id], onDelete: Cascade)
2558
- submitter User @relation("ExpenseSubmitter", fields: [submittedBy], references: [id])
2559
- approver User? @relation("ExpenseApprover", fields: [approvedBy], references: [id])
2559
+ id String @id @default(cuid())
2560
+ budgetId String
2561
+ submittedBy String
2562
+ description String
2563
+ amountCents Int
2564
+ category String?
2565
+ receiptUrl String?
2566
+ expenseDate DateTime? // When the expense occurred
2567
+ status String @default("Pending") // Pending, Approved, Rejected
2568
+ approvedBy String?
2569
+ approvedAt DateTime?
2570
+ rejectionReason String?
2571
+ createdAt DateTime @default(now())
2572
+ updatedAt DateTime @updatedAt
2573
+ budget Budget @relation(fields: [budgetId], references: [id], onDelete: Cascade)
2574
+ submitter User @relation("ExpenseSubmitter", fields: [submittedBy], references: [id])
2575
+ approver User? @relation("ExpenseApprover", fields: [approvedBy], references: [id])
2560
2576
 
2561
2577
  @@index([budgetId])
2562
2578
  @@index([submittedBy])
@@ -2582,11 +2598,87 @@ model ServiceAddon {
2582
2598
  priceCents Int
2583
2599
  quantity Int
2584
2600
  status ServiceAddonStatus @default(Enabled)
2601
+ imageUrl String? // Add-on image URL
2602
+ imageAlt String? // Alt text for accessibility
2585
2603
  servicePackageId String?
2586
2604
  serviceRatesAssociationId String?
2587
2605
  servicePackage ServicePackage? @relation(fields: [servicePackageId], references: [id], onDelete: Cascade)
2588
2606
  serviceRatesAssociation ServiceRatesAssociation? @relation(fields: [serviceRatesAssociationId], references: [id], onDelete: Cascade)
2589
2607
  ServiceBookingAddOn ServiceBookingAddOn[]
2608
+ convertedFromInclude ServiceInclude[] @relation("IncludeConvertedToAddon")
2609
+ convertedFromRequest ServiceAddonRequest[] @relation("RequestConvertedToAddon")
2610
+
2611
+ @@index([imageUrl])
2612
+ }
2613
+
2614
+ model ServiceInclude {
2615
+ id String @id @default(cuid())
2616
+ serviceId String
2617
+ suggestedByUserId String? // Who suggested it (null if anonymous)
2618
+ name String // e.g., "Tables and Chairs"
2619
+ description String? // Optional details
2620
+ status ServiceIncludeStatus @default(Pending)
2621
+ providerResponse ServiceIncludeResponse? // How provider responded
2622
+ responseNote String? // Optional note from provider
2623
+ convertedToAddonId String? // If converted to paid add-on
2624
+ voteCount Int @default(0) // Net votes (upvotes - downvotes)
2625
+ upvoteCount Int @default(0)
2626
+ downvoteCount Int @default(0)
2627
+ isActuallyIncluded Boolean @default(false) // Provider confirmed it IS included
2628
+ createdAt DateTime @default(now())
2629
+ updatedAt DateTime @updatedAt
2630
+
2631
+ service Service @relation(fields: [serviceId], references: [id], onDelete: Cascade)
2632
+ suggestedBy User? @relation("SuggestedIncludes", fields: [suggestedByUserId], references: [id], onDelete: SetNull)
2633
+ convertedToAddon ServiceAddon? @relation("IncludeConvertedToAddon", fields: [convertedToAddonId], references: [id], onDelete: SetNull)
2634
+ votes ServiceIncludeVote[]
2635
+
2636
+ @@unique([serviceId, name]) // Prevent duplicate suggestions for same service
2637
+ @@index([serviceId])
2638
+ @@index([status])
2639
+ @@index([voteCount])
2640
+ @@index([createdAt])
2641
+ }
2642
+
2643
+ model ServiceIncludeVote {
2644
+ id String @id @default(cuid())
2645
+ serviceIncludeId String
2646
+ userId String
2647
+ voteType VoteType // Upvote or Downvote
2648
+ createdAt DateTime @default(now())
2649
+ updatedAt DateTime @updatedAt
2650
+
2651
+ serviceInclude ServiceInclude @relation(fields: [serviceIncludeId], references: [id], onDelete: Cascade)
2652
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
2653
+
2654
+ @@unique([serviceIncludeId, userId]) // One vote per user per include
2655
+ @@index([serviceIncludeId])
2656
+ @@index([userId])
2657
+ }
2658
+
2659
+ model ServiceAddonRequest {
2660
+ id String @id @default(cuid())
2661
+ serviceId String
2662
+ userId String? // null if anonymous
2663
+ name String // e.g., "Specialty Lighting Package"
2664
+ description String? // Optional details
2665
+ status ServiceAddonRequestStatus @default(Pending)
2666
+ providerNote String? // Provider's response/notes
2667
+ notifyOnAvailable Boolean @default(false) // Customer wants notification
2668
+ convertedToAddonId String? // Links to actual ServiceAddon if created
2669
+ requestCount Int @default(1) // How many customers requested this
2670
+ createdAt DateTime @default(now())
2671
+ updatedAt DateTime @updatedAt
2672
+
2673
+ service Service @relation(fields: [serviceId], references: [id], onDelete: Cascade)
2674
+ user User? @relation("RequestedAddons", fields: [userId], references: [id], onDelete: SetNull)
2675
+ convertedToAddon ServiceAddon? @relation("RequestConvertedToAddon", fields: [convertedToAddonId], references: [id], onDelete: SetNull)
2676
+
2677
+ @@index([serviceId])
2678
+ @@index([status])
2679
+ @@index([userId])
2680
+ @@index([requestCount])
2681
+ @@index([createdAt])
2590
2682
  }
2591
2683
 
2592
2684
  model ServicePackage {
@@ -3647,7 +3739,7 @@ enum UserIntent {
3647
3739
  }
3648
3740
 
3649
3741
  enum BashStatus {
3650
- Idea // Pre-event idea gauging interest
3742
+ Idea // Pre-event idea gauging interest
3651
3743
  Draft
3652
3744
  Pending
3653
3745
  PreSale
@@ -5006,25 +5098,14 @@ enum OrganizationType {
5006
5098
  GreekLife
5007
5099
  SocialClub
5008
5100
  Nonprofit
5009
- Corporation
5010
- EducationalInstitution
5011
- Sports
5012
- Government
5013
- Cultural
5014
- Lifestyle
5015
- Political
5016
- Tourism
5017
- Youth
5018
- Senior
5019
- Tradeshow
5101
+ Other
5020
5102
  Professional
5021
5103
  RecordLabel
5022
5104
  School
5023
5105
  StudentClub
5024
- Conference
5025
- FoodAndBeverage
5026
- TechAndStartups
5027
- Other
5106
+ Sports
5107
+ Youth
5108
+ Cultural
5028
5109
  }
5029
5110
 
5030
5111
  enum YearsOfExperience {
@@ -5045,6 +5126,34 @@ enum ServiceAddonStatus {
5045
5126
  Disabled
5046
5127
  }
5047
5128
 
5129
+ enum ServiceIncludeStatus {
5130
+ Pending // Customer suggested, awaiting provider review
5131
+ Approved // Provider confirmed it IS included
5132
+ Declined // Provider says not possible/won't include
5133
+ Duplicate // Same as another suggestion
5134
+ }
5135
+
5136
+ enum ServiceIncludeResponse {
5137
+ NotPossible // Can't offer this
5138
+ Added // Now included in base package
5139
+ AlreadyIncluded // Was already included
5140
+ AvailableAsAddOn // Can offer but as paid add-on
5141
+ UnderConsideration // Thinking about it
5142
+ }
5143
+
5144
+ enum VoteType {
5145
+ Upvote
5146
+ Downvote
5147
+ }
5148
+
5149
+ enum ServiceAddonRequestStatus {
5150
+ Pending // New request
5151
+ Acknowledged // Provider saw it
5152
+ Added // Provider created the add-on
5153
+ Declined // Provider won't offer this
5154
+ Duplicate // Same as another request
5155
+ }
5156
+
5048
5157
  enum ServiceBookingFeeType {
5049
5158
  CleaningFee
5050
5159
  ProcessingFee
@@ -5173,6 +5282,11 @@ enum PricingModel {
5173
5282
  CUSTOM // Custom pricing structure with base rate + notes for negotiation
5174
5283
  }
5175
5284
 
5285
+ enum PricingType {
5286
+ USD // Ticket priced in USD (paid with credit card, earns BashPoints cashback)
5287
+ BASHPOINTS // Ticket priced in BashPoints (peer-to-peer loyalty points transfer)
5288
+ }
5289
+
5176
5290
  enum EntityType {
5177
5291
  EVENT_SERVICE
5178
5292
  ENTERTAINMENT_SERVICE
@@ -5242,9 +5356,10 @@ enum CreditTransactionStatus {
5242
5356
  }
5243
5357
 
5244
5358
  enum CreditSourceType {
5245
- MembershipReward // Monthly membership credits
5246
- TicketPurchase // 5% cashback on ticket
5247
- ServiceBooking // 3% cashback on service
5359
+ MembershipReward // Monthly membership points
5360
+ TicketPurchase // Cashback on ticket
5361
+ TicketSale // Host receives BashPoints from ticket sales (peer-to-peer)
5362
+ ServiceBooking // Cashback on service
5248
5363
  ReferralBonus // 10% of referee's first purchase
5249
5364
  AdminAdjustment // Manual credit by admin
5250
5365
  PromotionalBonus // Marketing campaigns
@@ -5709,7 +5824,7 @@ enum EventFormat {
5709
5824
  enum DiscountSourceType {
5710
5825
  PROMO_CODE
5711
5826
  SPECIAL_OFFER
5712
- PLATFORM_CREDIT // For future BashCash integration
5827
+ PLATFORM_CREDIT // For future BashPoints integration
5713
5828
  MANUAL_OVERRIDE // Admin adjustments
5714
5829
  }
5715
5830