@bash-app/bash-common 30.433.0 → 30.435.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 (111) hide show
  1. package/dist/__tests__/appleIapProducts.test.js +1 -0
  2. package/dist/__tests__/appleIapProducts.test.js.map +1 -1
  3. package/dist/__tests__/promoCodeScope.test.js +9 -2
  4. package/dist/__tests__/promoCodeScope.test.js.map +1 -1
  5. package/dist/__tests__/statusEnums.test.js +1 -0
  6. package/dist/__tests__/statusEnums.test.js.map +1 -1
  7. package/dist/appleIapProducts.d.ts +12 -2
  8. package/dist/appleIapProducts.d.ts.map +1 -1
  9. package/dist/appleIapProducts.js +13 -0
  10. package/dist/appleIapProducts.js.map +1 -1
  11. package/dist/index.d.ts +1 -0
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +1 -0
  14. package/dist/index.js.map +1 -1
  15. package/dist/intros/__tests__/introsReleaseGates.test.d.ts +2 -0
  16. package/dist/intros/__tests__/introsReleaseGates.test.d.ts.map +1 -0
  17. package/dist/intros/__tests__/introsReleaseGates.test.js +140 -0
  18. package/dist/intros/__tests__/introsReleaseGates.test.js.map +1 -0
  19. package/dist/intros/__tests__/psychExperiment.test.d.ts +2 -0
  20. package/dist/intros/__tests__/psychExperiment.test.d.ts.map +1 -0
  21. package/dist/intros/__tests__/psychExperiment.test.js +63 -0
  22. package/dist/intros/__tests__/psychExperiment.test.js.map +1 -0
  23. package/dist/intros/__tests__/reasons.test.d.ts +2 -0
  24. package/dist/intros/__tests__/reasons.test.d.ts.map +1 -0
  25. package/dist/intros/__tests__/reasons.test.js +72 -0
  26. package/dist/intros/__tests__/reasons.test.js.map +1 -0
  27. package/dist/intros/__tests__/sharedNotes.test.d.ts +2 -0
  28. package/dist/intros/__tests__/sharedNotes.test.d.ts.map +1 -0
  29. package/dist/intros/__tests__/sharedNotes.test.js +19 -0
  30. package/dist/intros/__tests__/sharedNotes.test.js.map +1 -0
  31. package/dist/intros/__tests__/transitions.test.d.ts +2 -0
  32. package/dist/intros/__tests__/transitions.test.d.ts.map +1 -0
  33. package/dist/intros/__tests__/transitions.test.js +43 -0
  34. package/dist/intros/__tests__/transitions.test.js.map +1 -0
  35. package/dist/intros/__tests__/warmDisclosure.test.d.ts +2 -0
  36. package/dist/intros/__tests__/warmDisclosure.test.d.ts.map +1 -0
  37. package/dist/intros/__tests__/warmDisclosure.test.js +10 -0
  38. package/dist/intros/__tests__/warmDisclosure.test.js.map +1 -0
  39. package/dist/intros/age.d.ts +4 -0
  40. package/dist/intros/age.d.ts.map +1 -0
  41. package/dist/intros/age.js +14 -0
  42. package/dist/intros/age.js.map +1 -0
  43. package/dist/intros/attendance.d.ts +11 -0
  44. package/dist/intros/attendance.d.ts.map +1 -0
  45. package/dist/intros/attendance.js +27 -0
  46. package/dist/intros/attendance.js.map +1 -0
  47. package/dist/intros/attributeCatalog.d.ts +17 -0
  48. package/dist/intros/attributeCatalog.d.ts.map +1 -0
  49. package/dist/intros/attributeCatalog.js +96 -0
  50. package/dist/intros/attributeCatalog.js.map +1 -0
  51. package/dist/intros/index.d.ts +10 -0
  52. package/dist/intros/index.d.ts.map +1 -0
  53. package/dist/intros/index.js +10 -0
  54. package/dist/intros/index.js.map +1 -0
  55. package/dist/intros/intents.d.ts +8 -0
  56. package/dist/intros/intents.d.ts.map +1 -0
  57. package/dist/intros/intents.js +44 -0
  58. package/dist/intros/intents.js.map +1 -0
  59. package/dist/intros/psychExperiment.d.ts +29 -0
  60. package/dist/intros/psychExperiment.d.ts.map +1 -0
  61. package/dist/intros/psychExperiment.js +82 -0
  62. package/dist/intros/psychExperiment.js.map +1 -0
  63. package/dist/intros/reasons.d.ts +38 -0
  64. package/dist/intros/reasons.d.ts.map +1 -0
  65. package/dist/intros/reasons.js +162 -0
  66. package/dist/intros/reasons.js.map +1 -0
  67. package/dist/intros/sharedNotes.d.ts +10 -0
  68. package/dist/intros/sharedNotes.d.ts.map +1 -0
  69. package/dist/intros/sharedNotes.js +56 -0
  70. package/dist/intros/sharedNotes.js.map +1 -0
  71. package/dist/intros/transitions.d.ts +29 -0
  72. package/dist/intros/transitions.d.ts.map +1 -0
  73. package/dist/intros/transitions.js +128 -0
  74. package/dist/intros/transitions.js.map +1 -0
  75. package/dist/intros/validation.d.ts +50 -0
  76. package/dist/intros/validation.d.ts.map +1 -0
  77. package/dist/intros/validation.js +212 -0
  78. package/dist/intros/validation.js.map +1 -0
  79. package/dist/mirroredPrismaEnums.d.ts +1 -0
  80. package/dist/mirroredPrismaEnums.d.ts.map +1 -1
  81. package/dist/mirroredPrismaEnums.js +1 -0
  82. package/dist/mirroredPrismaEnums.js.map +1 -1
  83. package/dist/promoCodeScope.d.ts +7 -1
  84. package/dist/promoCodeScope.d.ts.map +1 -1
  85. package/dist/promoCodeScope.js +13 -4
  86. package/dist/promoCodeScope.js.map +1 -1
  87. package/package.json +1 -1
  88. package/prisma/schema.prisma +321 -2
  89. package/src/__tests__/appleIapProducts.test.ts +3 -0
  90. package/src/__tests__/promoCodeScope.test.ts +16 -3
  91. package/src/__tests__/statusEnums.test.ts +1 -0
  92. package/src/appleIapProducts.ts +29 -2
  93. package/src/index.ts +1 -0
  94. package/src/intros/__tests__/introsReleaseGates.test.ts +181 -0
  95. package/src/intros/__tests__/psychExperiment.test.ts +99 -0
  96. package/src/intros/__tests__/reasons.test.ts +122 -0
  97. package/src/intros/__tests__/sharedNotes.test.ts +20 -0
  98. package/src/intros/__tests__/transitions.test.ts +61 -0
  99. package/src/intros/__tests__/warmDisclosure.test.ts +10 -0
  100. package/src/intros/age.ts +13 -0
  101. package/src/intros/attendance.ts +33 -0
  102. package/src/intros/attributeCatalog.ts +113 -0
  103. package/src/intros/index.ts +9 -0
  104. package/src/intros/intents.ts +49 -0
  105. package/src/intros/psychExperiment.ts +130 -0
  106. package/src/intros/reasons.ts +187 -0
  107. package/src/intros/sharedNotes.ts +59 -0
  108. package/src/intros/transitions.ts +172 -0
  109. package/src/intros/validation.ts +248 -0
  110. package/src/mirroredPrismaEnums.ts +1 -0
  111. package/src/promoCodeScope.ts +20 -4
@@ -1298,6 +1298,10 @@ model BashEvent {
1298
1298
  albumModerationEnabled Boolean @default(false)
1299
1299
  /// Opt-in post-event attendee networking
1300
1300
  postEventNetworkingEnabled Boolean @default(false)
1301
+ /// Intros at this bash. Off until the host turns it on.
1302
+ introsMode IntrosEventMode @default(Off)
1303
+ introsParticipations IntrosEventParticipation[]
1304
+ introductions Introduction[]
1301
1305
 
1302
1306
  // Host broadcast fields
1303
1307
  postEventMessageSent Boolean @default(false)
@@ -4724,11 +4728,15 @@ model User {
4724
4728
  /// App Store originalTransactionId when membership is billed via StoreKit IAP.
4725
4729
  membershipAppleOriginalTransactionId String? @unique
4726
4730
  /// Which provider owns the active membership billing relationship.
4727
- membershipBillingProvider String? // "stripe" | "apple" | null
4731
+ membershipBillingProvider String? // "stripe" | "apple" | "google" | null
4732
+ /// Current Google Play purchase token when membership is billed via Play Billing.
4733
+ membershipGooglePurchaseToken String? @unique
4728
4734
  /// Optional consumer BashPass subscription (waives guest platform fee on tickets; monthly BashPoints).
4729
4735
  bashPassStripeSubscriptionId String? @unique
4730
4736
  /// App Store originalTransactionId when BashPass is billed via StoreKit IAP.
4731
4737
  bashPassAppleOriginalTransactionId String? @unique
4738
+ /// Current Google Play purchase token when BashPass is billed via Play Billing.
4739
+ bashPassGooglePurchaseToken String? @unique
4732
4740
  bashPassCurrentPeriodEnd DateTime?
4733
4741
  /// Stripe price tier for standalone BashPass; effective tier may also come from membership bundle.
4734
4742
  bashPassTier BashPassTier?
@@ -4788,6 +4796,7 @@ model User {
4788
4796
  birthdayOfferOptIns UserBirthdayOfferOptIn[]
4789
4797
  birthdayOfferDeliveries BirthdayOfferDelivery[]
4790
4798
  birthdayBoostGrants BirthdayBoostGrant[]
4799
+ playPurchases PlayPurchase[]
4791
4800
  birthdayRewardRedemptions BirthdayRewardRedemption[]
4792
4801
  birthdayRewardFavorites BirthdayRewardFavorite[]
4793
4802
  birthdayDealSuggestions BirthdayDealSuggestion[]
@@ -4933,6 +4942,11 @@ model User {
4933
4942
  connectionRequestsReceived UserConnection[] @relation("ConnectionRequestsReceived")
4934
4943
  interestExpressedByMe InterestExpression[] @relation("InterestExpressedByMe")
4935
4944
  interestExpressedToMe InterestExpression[] @relation("InterestExpressedToMe")
4945
+ introsProfile IntrosProfile?
4946
+ introsAttributes IntrosProfileAttribute[]
4947
+ introsEventParticipations IntrosEventParticipation[]
4948
+ warmSuggestionsMade WarmIntroSuggestion[] @relation("WarmSuggestionFacilitator")
4949
+ facilitatedIntroductions Introduction[] @relation("IntroFacilitator")
4936
4950
  links UserLink[]
4937
4951
  preferences UserPreferences?
4938
4952
  rankings UserRankings?
@@ -5177,6 +5191,8 @@ model UserPreferences {
5177
5191
  personalityType String?
5178
5192
  /// Self-reported locus of control: internal | external | mixed
5179
5193
  locusOfControl String?
5194
+ /// Warm Intro invitations from connections. Null means the person has not chosen.
5195
+ warmIntroInvites WarmIntroInvitePref?
5180
5196
  blockSearchEngineIndex Boolean @default(false)
5181
5197
  autoAddEventAttendees Boolean @default(true)
5182
5198
  trackFirstEventAttended Boolean @default(true)
@@ -5513,6 +5529,262 @@ model InterestExpression {
5513
5529
  @@index([targetId])
5514
5530
  }
5515
5531
 
5532
+ enum IntrosStatus {
5533
+ Off
5534
+ Active
5535
+ Paused
5536
+ }
5537
+
5538
+ enum IntrosIntent {
5539
+ Friends
5540
+ Professional
5541
+ MentorSeek
5542
+ MentorOffer
5543
+ Collaborator
5544
+ Romance
5545
+ }
5546
+
5547
+ enum IntrosWarmAudience {
5548
+ None
5549
+ Connections
5550
+ ConnectionsAndHosts
5551
+ }
5552
+
5553
+ enum WarmIntroInvitePref {
5554
+ Off
5555
+ Anonymous
5556
+ Named
5557
+ }
5558
+
5559
+ enum IntrosEventMode {
5560
+ Off
5561
+ Platonic
5562
+ All
5563
+ }
5564
+
5565
+ enum IntrosAttributeKind {
5566
+ BigFive
5567
+ MyersBriggs
5568
+ LocusOfControl
5569
+ CliftonStrengths
5570
+ EmotionalIntelligence
5571
+ HumanDesign
5572
+ }
5573
+
5574
+ enum IntrosVisibility {
5575
+ OnlyMe
5576
+ RevealedIntros
5577
+ }
5578
+
5579
+ enum IntroductionSource {
5580
+ BashSuggested
5581
+ Warm
5582
+ }
5583
+
5584
+ enum IntroductionMode {
5585
+ Mystery
5586
+ Known
5587
+ }
5588
+
5589
+ enum IntroductionState {
5590
+ Open
5591
+ Mutual
5592
+ Revealed
5593
+ Closed
5594
+ }
5595
+
5596
+ enum IntroductionClosedReason {
5597
+ Declined
5598
+ Withdrawn
5599
+ Expired
5600
+ NotRegistered
5601
+ Blocked
5602
+ EventCancelled
5603
+ IntrosDisabled
5604
+ ConsentRevoked
5605
+ }
5606
+
5607
+ enum IntroInterest {
5608
+ Pending
5609
+ Interested
5610
+ Declined
5611
+ Postponed
5612
+ Withdrawn
5613
+ }
5614
+
5615
+ enum RevealSource {
5616
+ EventStart
5617
+ EarlyReveal
5618
+ Warm
5619
+ }
5620
+
5621
+ enum EarlyRevealStatus {
5622
+ Requested
5623
+ Approved
5624
+ Completed
5625
+ Declined
5626
+ Expired
5627
+ Cancelled
5628
+ Refunded
5629
+ }
5630
+
5631
+ enum EarlyRevealPaymentMethod {
5632
+ Stripe
5633
+ AppleIap
5634
+ BashPoints
5635
+ }
5636
+
5637
+ model IntrosProfile {
5638
+ id String @id @default(cuid())
5639
+ userId String @unique
5640
+ status IntrosStatus @default(Off)
5641
+ pausedUntil DateTime?
5642
+ consentVersion Int @default(1)
5643
+ activatedAt DateTime?
5644
+ globalMatchingAt DateTime?
5645
+ romanceAt DateTime?
5646
+ psychologyExperimentAt DateTime?
5647
+ warmSuggestionAudience IntrosWarmAudience @default(Connections)
5648
+ intents IntrosIntent[]
5649
+ shortIntro String? @db.VarChar(140)
5650
+ conversationTopics String[] @default([])
5651
+ professionalInterests String[] @default([])
5652
+ travelRadiusMiles Int?
5653
+ romanceSeekingGenders String[] @default([])
5654
+ romanceAgeMin Int?
5655
+ romanceAgeMax Int?
5656
+ shareRegistrationStatus Boolean @default(false)
5657
+ revealOnlyAfterCheckIn Boolean @default(false)
5658
+ notifyIntros Boolean @default(true)
5659
+ legacyImportedAt DateTime?
5660
+ createdAt DateTime @default(now())
5661
+ updatedAt DateTime @updatedAt
5662
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
5663
+ }
5664
+
5665
+ model IntrosProfileAttribute {
5666
+ id String @id @default(cuid())
5667
+ userId String
5668
+ kind IntrosAttributeKind
5669
+ value Json
5670
+ source String
5671
+ visibility IntrosVisibility @default(OnlyMe)
5672
+ allowExperimentalMatching Boolean @default(false)
5673
+ updatedAt DateTime @updatedAt
5674
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
5675
+
5676
+ @@unique([userId, kind])
5677
+ }
5678
+
5679
+ model IntrosEventParticipation {
5680
+ id String @id @default(cuid())
5681
+ userId String
5682
+ bashEventId String
5683
+ optedInAt DateTime @default(now())
5684
+ optedOutAt DateTime?
5685
+ bashEvent BashEvent @relation(fields: [bashEventId], references: [id], onDelete: Cascade)
5686
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
5687
+
5688
+ @@unique([userId, bashEventId])
5689
+ @@index([bashEventId])
5690
+ }
5691
+
5692
+ model IntrosPair {
5693
+ id String @id @default(cuid())
5694
+ userLowId String
5695
+ userHighId String
5696
+ lastSuggestedAt DateTime?
5697
+ revealCount Int @default(0)
5698
+ lastRevealedAt DateTime?
5699
+ cooldownUntil DateTime?
5700
+ hiddenByLowAt DateTime?
5701
+ hiddenByHighAt DateTime?
5702
+ introductions Introduction[]
5703
+
5704
+ @@unique([userLowId, userHighId])
5705
+ }
5706
+
5707
+ model Introduction {
5708
+ id String @id @default(cuid())
5709
+ pairId String
5710
+ bashEventId String?
5711
+ source IntroductionSource
5712
+ mode IntroductionMode
5713
+ matchedIntent IntrosIntent?
5714
+ state IntroductionState @default(Open)
5715
+ closedReason IntroductionClosedReason?
5716
+ interestLow IntroInterest @default(Pending)
5717
+ interestHigh IntroInterest @default(Pending)
5718
+ interestLowAt DateTime?
5719
+ interestHighAt DateTime?
5720
+ mutedLow Boolean @default(false)
5721
+ mutedHigh Boolean @default(false)
5722
+ saidHiLowAt DateTime?
5723
+ saidHiHighAt DateTime?
5724
+ facilitationOkLowAt DateTime?
5725
+ facilitationOkHighAt DateTime?
5726
+ facilitatorId String?
5727
+ facilitatorNote String? @db.VarChar(280)
5728
+ facilitatorMadeAt DateTime?
5729
+ revealAt DateTime?
5730
+ revealedAt DateTime?
5731
+ revealSource RevealSource?
5732
+ nudgedAt DateTime?
5733
+ explanationCodes String[] @default([])
5734
+ scoreComponents Json?
5735
+ ruleVersion Int @default(1)
5736
+ expiresAt DateTime?
5737
+ version Int @default(0)
5738
+ createdAt DateTime @default(now())
5739
+ pair IntrosPair @relation(fields: [pairId], references: [id], onDelete: Cascade)
5740
+ bashEvent BashEvent? @relation(fields: [bashEventId], references: [id], onDelete: SetNull)
5741
+ facilitator User? @relation("IntroFacilitator", fields: [facilitatorId], references: [id], onDelete: SetNull)
5742
+ earlyReveals EarlyRevealRequest[]
5743
+
5744
+ @@index([bashEventId, state])
5745
+ @@index([facilitatorId])
5746
+ @@index([state, revealAt])
5747
+ }
5748
+
5749
+ model WarmIntroSuggestion {
5750
+ id String @id @default(cuid())
5751
+ facilitatorId String
5752
+ pairId String
5753
+ bashEventId String?
5754
+ linkedIntroductionId String?
5755
+ reasonCodes String[] @default([])
5756
+ madeAt DateTime?
5757
+ dismissedAt DateTime?
5758
+ offeredIntroductionId String?
5759
+ createdAt DateTime @default(now())
5760
+ facilitator User @relation("WarmSuggestionFacilitator", fields: [facilitatorId], references: [id], onDelete: Cascade)
5761
+
5762
+ @@unique([facilitatorId, pairId, bashEventId])
5763
+ @@index([facilitatorId, createdAt])
5764
+ }
5765
+
5766
+ model EarlyRevealRequest {
5767
+ id String @id @default(cuid())
5768
+ introductionId String
5769
+ requesterId String
5770
+ status EarlyRevealStatus @default(Requested)
5771
+ priceCents Int
5772
+ currency String @default("usd")
5773
+ paymentMethod EarlyRevealPaymentMethod?
5774
+ stripePaymentIntentId String? @unique
5775
+ appleTransactionId String? @unique
5776
+ bashCreditTransactionId String?
5777
+ idempotencyKey String @unique
5778
+ approvedAt DateTime?
5779
+ expiresAt DateTime
5780
+ createdAt DateTime @default(now())
5781
+ updatedAt DateTime @updatedAt
5782
+ introduction Introduction @relation(fields: [introductionId], references: [id], onDelete: Cascade)
5783
+
5784
+ @@index([introductionId])
5785
+ @@index([status, updatedAt])
5786
+ }
5787
+
5516
5788
  model BiometricCredential {
5517
5789
  id String @id @default(cuid())
5518
5790
  userId String
@@ -5677,6 +5949,33 @@ model ServiceSubscriptionCounts {
5677
5949
  subscriptionCount UserSubscription? @relation("subscriptionCount")
5678
5950
  }
5679
5951
 
5952
+ /// One row per Google Play purchase token. Renewals update the same row.
5953
+ /// A subscription replacement inserts a new row and keeps the previous token.
5954
+ model PlayPurchase {
5955
+ id String @id @default(cuid())
5956
+ purchaseToken String @unique
5957
+ linkedPurchaseToken String?
5958
+ productId String
5959
+ userId String
5960
+ family String
5961
+ purchaseState String
5962
+ expiryTime DateTime?
5963
+ orderId String?
5964
+ grantedAt DateTime?
5965
+ acknowledgedAt DateTime?
5966
+ consumedAt DateTime?
5967
+ finishError String?
5968
+ boostTargetType String?
5969
+ boostTargetId String?
5970
+ featuredUntil DateTime?
5971
+ createdAt DateTime @default(now())
5972
+ updatedAt DateTime @updatedAt
5973
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
5974
+
5975
+ @@index([userId])
5976
+ @@index([linkedPurchaseToken])
5977
+ }
5978
+
5680
5979
  model UserSubscription {
5681
5980
  id String @id @default(cuid())
5682
5981
  ownerId String @unique
@@ -5685,6 +5984,8 @@ model UserSubscription {
5685
5984
  stripeCheckoutSessionId String? @unique
5686
5985
  /// App Store originalTransactionId when listing seats are billed via StoreKit IAP.
5687
5986
  appleOriginalTransactionId String? @unique
5987
+ /// Current Google Play purchase token when listing seats are billed via Play Billing.
5988
+ googlePurchaseToken String? @unique
5688
5989
  type MembershipTier?
5689
5990
  status UserSubscriptionStatus?
5690
5991
  subscriptionCountId String @unique
@@ -5698,6 +5999,7 @@ model UserSubscription {
5698
5999
  @@index([stripeCheckoutSessionId])
5699
6000
  @@index([stripeSubscriptionId])
5700
6001
  @@index([appleOriginalTransactionId])
6002
+ @@index([googlePurchaseToken])
5701
6003
  }
5702
6004
 
5703
6005
  model Service {
@@ -6168,7 +6470,7 @@ model VendorSpaceRequirements {
6168
6470
  vendorId String @unique
6169
6471
  boothSize String @default("10x10")
6170
6472
  customSize String?
6171
- hasTent Boolean @default(false)
6473
+ hasTent Boolean @default(true)
6172
6474
  tableCount String @default("1")
6173
6475
  hasChairs Boolean @default(false)
6174
6476
  needsElectricity Boolean @default(false)
@@ -8597,6 +8899,8 @@ model UserReport {
8597
8899
  reporterId String
8598
8900
  reportedId String
8599
8901
  bashEventId String?
8902
+ /// Optional Intros introduction this report is about. The reporter may not know the other person yet.
8903
+ introductionId String?
8600
8904
  reason String
8601
8905
  details String
8602
8906
  createdAt DateTime @default(now())
@@ -9049,6 +9353,12 @@ enum NotificationType {
9049
9353
  InterestExpressedAnonymous
9050
9354
  /// Intros: both people sent a signal — unlocks chat
9051
9355
  IntroMutual
9356
+ /// Intros V2: never identifies anyone before a reveal
9357
+ IntrosUpdate
9358
+ /// Intros V2: identities, sent only to the two people
9359
+ IntrosRevealed
9360
+ /// Intros V2: warm invitations and facilitator suggestions
9361
+ IntrosWarm
9052
9362
  }
9053
9363
 
9054
9364
  /// Opt-in reminder for a scheduled tier release (v1.5).
@@ -11698,6 +12008,7 @@ enum CreditSourceType {
11698
12008
  CompetitionFinalist // Adventures reward for reaching a finalist placement
11699
12009
  CompetitionWin // Adventures reward for winning a competition prize
11700
12010
  HornClear // Stuff the horn: 5 points per clear, 100 per UTC day
12011
+ IntrosEarlyReveal // BashPoints spent on a paid early identity reveal
11701
12012
  }
11702
12013
 
11703
12014
  enum ReferralTier {
@@ -12556,6 +12867,13 @@ enum AuditAction {
12556
12867
  ORG_TAX_DOCUMENT_REVIEWED
12557
12868
  ORG_INSURANCE_CERTIFICATE_SUBMITTED
12558
12869
  ORG_INSURANCE_CERTIFICATE_REVIEWED
12870
+ INTROS_REVEALED
12871
+ INTROS_REVEAL_BLOCKED
12872
+ INTROS_WARM_ACCEPTED
12873
+ INTROS_EARLY_REVEAL_APPROVED
12874
+ INTROS_EARLY_REVEAL_PAID
12875
+ INTROS_REFUND_ISSUED
12876
+ INTROS_PAYMENT_RECONCILED
12559
12877
  }
12560
12878
 
12561
12879
  enum AuditCategory {
@@ -12571,6 +12889,7 @@ enum AuditCategory {
12571
12889
  Compliance
12572
12890
  Security
12573
12891
  Organization
12892
+ Intros
12574
12893
  }
12575
12894
 
12576
12895
  enum AuditSeverity {
@@ -41,6 +41,9 @@ describe("appleIapProducts", () => {
41
41
  expect(
42
42
  getAppleIapProduct("community.bash.us.boost.7d")?.family
43
43
  ).toBe("feature_boost");
44
+ expect(getAppleIapProduct("community.bash.us.intros.earlyreveal")?.family).toBe(
45
+ "early_reveal"
46
+ );
44
47
  });
45
48
 
46
49
  it("listAppleIapProductIds filters by family", () => {
@@ -76,9 +76,14 @@ describe("promoterCodeInputErrors", () => {
76
76
  it("accepts an attribution-only all-tiers code", () => {
77
77
  expect(promoterCodeInputErrors(ok, ["ga"])).toEqual([]);
78
78
  });
79
- it("validates guest percentage 1-100 separately from promoter commission 0-100", () => {
80
- expect(promoterCodeInputErrors({ ...ok, discountType: "PERCENT", discountValue: 0 }, [])).toContain(
81
- "Guest discount must be between 1% and 100%."
79
+ it("allows a guest discount of 0 and rejects negatives, separately from promoter commission", () => {
80
+ expect(promoterCodeInputErrors({ ...ok, discountType: "PERCENT", discountValue: 0 }, [])).toEqual([]);
81
+ expect(promoterCodeInputErrors({ ...ok, discountType: "FIXED_CASH", discountValue: 0 }, [])).toEqual([]);
82
+ expect(promoterCodeInputErrors({ ...ok, discountType: "PERCENT", discountValue: -1 }, [])).toContain(
83
+ "Guest discount must be between 0% and 100%."
84
+ );
85
+ expect(promoterCodeInputErrors({ ...ok, discountType: "FIXED_CASH", discountValue: -100 }, [])).toContain(
86
+ "Enter a fixed discount of $0 or more."
82
87
  );
83
88
  expect(promoterCodeInputErrors({ ...ok, discountType: "PERCENT", discountValue: 100 }, [])).toEqual([]);
84
89
  expect(promoterCodeInputErrors({ ...ok, promoterCommissionBps: 0 }, [])).toEqual([]);
@@ -103,4 +108,12 @@ describe("promoterCodeInputErrors", () => {
103
108
  promoterCodeInputErrors({ ...ok, promoterEmail: "p@x.com", promoterRewardReviewed: true }, [])
104
109
  ).toEqual([]);
105
110
  });
111
+ it("accepts BashPoints as a compensation method", () => {
112
+ expect(
113
+ promoterCodeInputErrors({ ...ok, compensationMethod: "BashPoints" }, [])
114
+ ).toEqual([]);
115
+ expect(
116
+ promoterCodeInputErrors({ ...ok, compensationMethod: "Wire" as "Venmo" }, [])
117
+ ).toContain("Choose Venmo, Zelle, Cash App, or BashPoints.");
118
+ });
106
119
  });
@@ -148,6 +148,7 @@ describe("status enum value sets", () => {
148
148
  "CompetitionFinalist",
149
149
  "CompetitionWin",
150
150
  "HornClear",
151
+ "IntrosEarlyReveal",
151
152
  ].sort(),
152
153
  );
153
154
  });
@@ -15,7 +15,8 @@ export type AppleIapProductFamily =
15
15
  | "membership"
16
16
  | "listing"
17
17
  | "bashpass"
18
- | "feature_boost";
18
+ | "feature_boost"
19
+ | "early_reveal";
19
20
 
20
21
  export type AppleMembershipInterval = "monthly" | "yearly" | "lifetime";
21
22
 
@@ -54,11 +55,19 @@ export interface AppleFeatureBoostProduct {
54
55
  priceCents: number;
55
56
  }
56
57
 
58
+ /** Consumable. App Store Connect must exist before a live iOS purchase can complete. */
59
+ export interface AppleEarlyRevealProduct {
60
+ productId: string;
61
+ family: "early_reveal";
62
+ priceCents: number;
63
+ }
64
+
57
65
  export type AppleIapProduct =
58
66
  | AppleMembershipProduct
59
67
  | AppleListingProduct
60
68
  | AppleBashPassProduct
61
- | AppleFeatureBoostProduct;
69
+ | AppleFeatureBoostProduct
70
+ | AppleEarlyRevealProduct;
62
71
 
63
72
  const MEMBERSHIP_TIERS = [
64
73
  MembershipTier.Premium,
@@ -145,11 +154,18 @@ export const APPLE_FEATURE_BOOST_PRODUCTS: readonly AppleFeatureBoostProduct[] =
145
154
  priceCents: d.priceCents,
146
155
  }));
147
156
 
157
+ export const APPLE_EARLY_REVEAL_PRODUCT: AppleEarlyRevealProduct = {
158
+ productId: "community.bash.us.intros.earlyreveal",
159
+ family: "early_reveal",
160
+ priceCents: 500,
161
+ };
162
+
148
163
  export const APPLE_IAP_PRODUCTS: readonly AppleIapProduct[] = [
149
164
  ...APPLE_MEMBERSHIP_PRODUCTS,
150
165
  ...APPLE_LISTING_PRODUCTS,
151
166
  ...APPLE_BASHPASS_PRODUCTS,
152
167
  ...APPLE_FEATURE_BOOST_PRODUCTS,
168
+ APPLE_EARLY_REVEAL_PRODUCT,
153
169
  ];
154
170
 
155
171
  const BY_PRODUCT_ID: ReadonlyMap<string, AppleIapProduct> = new Map(
@@ -164,6 +180,13 @@ export function isAppleIapProductId(productId: string): boolean {
164
180
  return BY_PRODUCT_ID.has(productId);
165
181
  }
166
182
 
183
+ /** Play Console product IDs for this release. Early reveal is excluded. */
184
+ export function listPlayBillingProductIds(): string[] {
185
+ return APPLE_IAP_PRODUCTS.filter((p) => p.family !== "early_reveal").map(
186
+ (p) => p.productId
187
+ );
188
+ }
189
+
167
190
  export function listAppleIapProductIds(family?: AppleIapProductFamily): string[] {
168
191
  if (!family) {
169
192
  return APPLE_IAP_PRODUCTS.map((p) => p.productId);
@@ -198,6 +221,10 @@ export function findAppleFeatureBoostProduct(
198
221
  return APPLE_FEATURE_BOOST_PRODUCTS.find((p) => p.durationId === durationId);
199
222
  }
200
223
 
224
+ export function findAppleEarlyRevealProduct(): AppleEarlyRevealProduct {
225
+ return APPLE_EARLY_REVEAL_PRODUCT;
226
+ }
227
+
201
228
  /** Apple subscription management deep link (Settings → Subscriptions). */
202
229
  export const APPLE_SUBSCRIPTIONS_MANAGEMENT_URL =
203
230
  "https://apps.apple.com/account/subscriptions";
package/src/index.ts CHANGED
@@ -57,6 +57,7 @@ export * from "./audienceImport.js";
57
57
  export * from "./eventStaffRoles.js";
58
58
  export * from "./bashEventCancellationPolicy.js";
59
59
  export * from "./userReportTypes.js";
60
+ export * from "./intros/index.js";
60
61
  export * from "./mirroredPrismaEnums.js";
61
62
  export * from "./locationShare.js";
62
63
  export * from "./seatMap.js";