@bash-app/bash-common 30.275.0 → 30.277.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 (68) hide show
  1. package/dist/__tests__/groupTicketUtils.test.d.ts +2 -0
  2. package/dist/__tests__/groupTicketUtils.test.d.ts.map +1 -0
  3. package/dist/__tests__/groupTicketUtils.test.js +38 -0
  4. package/dist/__tests__/groupTicketUtils.test.js.map +1 -0
  5. package/dist/competitionIdeas.d.ts +19 -0
  6. package/dist/competitionIdeas.d.ts.map +1 -0
  7. package/dist/competitionIdeas.js +405 -0
  8. package/dist/competitionIdeas.js.map +1 -0
  9. package/dist/competitionValidation.d.ts +10 -0
  10. package/dist/competitionValidation.d.ts.map +1 -0
  11. package/dist/competitionValidation.js +29 -0
  12. package/dist/competitionValidation.js.map +1 -0
  13. package/dist/definitions.d.ts +6 -0
  14. package/dist/definitions.d.ts.map +1 -1
  15. package/dist/definitions.js.map +1 -1
  16. package/dist/extendedSchemas.d.ts +356 -1
  17. package/dist/extendedSchemas.d.ts.map +1 -1
  18. package/dist/extendedSchemas.js +15 -0
  19. package/dist/extendedSchemas.js.map +1 -1
  20. package/dist/groupTicketUtils.d.ts +19 -0
  21. package/dist/groupTicketUtils.d.ts.map +1 -0
  22. package/dist/groupTicketUtils.js +74 -0
  23. package/dist/groupTicketUtils.js.map +1 -0
  24. package/dist/index.d.ts +4 -0
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/index.js +4 -0
  27. package/dist/index.js.map +1 -1
  28. package/dist/utils/__tests__/paymentUtils.test.js +80 -8
  29. package/dist/utils/__tests__/paymentUtils.test.js.map +1 -1
  30. package/dist/utils/__tests__/recurrenceUtils.test.js +82 -1
  31. package/dist/utils/__tests__/recurrenceUtils.test.js.map +1 -1
  32. package/dist/utils/__tests__/ticketListUtils.test.js +10 -0
  33. package/dist/utils/__tests__/ticketListUtils.test.js.map +1 -1
  34. package/dist/utils/groupTicketCartUtils.d.ts +12 -0
  35. package/dist/utils/groupTicketCartUtils.d.ts.map +1 -0
  36. package/dist/utils/groupTicketCartUtils.js +30 -0
  37. package/dist/utils/groupTicketCartUtils.js.map +1 -0
  38. package/dist/utils/paymentUtils.d.ts +56 -0
  39. package/dist/utils/paymentUtils.d.ts.map +1 -1
  40. package/dist/utils/paymentUtils.js +114 -18
  41. package/dist/utils/paymentUtils.js.map +1 -1
  42. package/dist/utils/recurrenceUtils.d.ts +18 -0
  43. package/dist/utils/recurrenceUtils.d.ts.map +1 -1
  44. package/dist/utils/recurrenceUtils.js +70 -0
  45. package/dist/utils/recurrenceUtils.js.map +1 -1
  46. package/dist/utils/service/serviceBookingTypes.d.ts +1 -1
  47. package/dist/utils/service/serviceBookingTypes.d.ts.map +1 -1
  48. package/dist/utils/ticketListUtils.d.ts.map +1 -1
  49. package/dist/utils/ticketListUtils.js +15 -3
  50. package/dist/utils/ticketListUtils.js.map +1 -1
  51. package/package.json +1 -1
  52. package/prisma/migrations/competition-prize-catalog-entry-tier.sql +39 -0
  53. package/prisma/schema.prisma +118 -8
  54. package/src/__tests__/groupTicketUtils.test.ts +53 -0
  55. package/src/competitionIdeas.ts +429 -0
  56. package/src/competitionValidation.ts +42 -0
  57. package/src/definitions.ts +7 -0
  58. package/src/extendedSchemas.ts +52 -0
  59. package/src/groupTicketUtils.ts +101 -0
  60. package/src/index.ts +4 -0
  61. package/src/utils/__tests__/paymentUtils.test.ts +123 -8
  62. package/src/utils/__tests__/recurrenceUtils.test.ts +99 -0
  63. package/src/utils/__tests__/ticketListUtils.test.ts +12 -0
  64. package/src/utils/groupTicketCartUtils.ts +36 -0
  65. package/src/utils/paymentUtils.ts +165 -21
  66. package/src/utils/recurrenceUtils.ts +104 -0
  67. package/src/utils/service/serviceBookingTypes.ts +3 -0
  68. package/src/utils/ticketListUtils.ts +19 -5
@@ -65,7 +65,10 @@ export function ticketListToString(ticketList) {
65
65
  dateTimeStr = dateTime.toISO() || dateTimeStr;
66
66
  }
67
67
  }
68
- ticketArgs.push(`${ticketNumAndDates.numberOfTickets}${URL_PARAMS_TICKETS_DATE_DELIM}${dateTimeStr}`);
68
+ ticketArgs.push(`${ticketNumAndDates.numberOfTickets}${URL_PARAMS_TICKETS_DATE_DELIM}${dateTimeStr}${ticketNumAndDates.unitPriceCents != null &&
69
+ ticketNumAndDates.unitPriceCents > 0
70
+ ? `${URL_PARAMS_TICKETS_DATE_DELIM}${ticketNumAndDates.unitPriceCents}`
71
+ : ""}`);
69
72
  }
70
73
  }
71
74
  // Only include this tier if we found at least one ticket > 0
@@ -114,16 +117,25 @@ export function ticketListStrToTicketList(ticketListStr) {
114
117
  .split(URL_PARAMS_NUMBER_OF_TICKETS_TICKETS_DATE_DELIM)
115
118
  .filter((ticketNumAndDateStr) => !!ticketNumAndDateStr);
116
119
  for (const ticketNumAndDateStr of ticketNumAndDates) {
117
- // [numberOfTickets];;[date]
118
- const [numberOfTickets, ticketDateTimeStr] = ticketNumAndDateStr.split(URL_PARAMS_TICKETS_DATE_DELIM);
120
+ // [numberOfTickets];;[date];;[unitPriceCents?]
121
+ const segments = ticketNumAndDateStr.split(URL_PARAMS_TICKETS_DATE_DELIM);
122
+ const numberOfTickets = segments[0];
123
+ const ticketDateTimeStr = segments[1];
124
+ const unitPriceCentsRaw = segments[2];
119
125
  const ticketDateTime = DateTime.fromISO(ticketDateTimeStr);
120
126
  let ticketDateTimeFormattedStr = undefined;
121
127
  if (ticketDateTime.isValid) {
122
128
  ticketDateTimeFormattedStr = ticketDateTime.toISO() ?? undefined;
123
129
  }
130
+ const unitPriceCents = unitPriceCentsRaw != null && unitPriceCentsRaw !== ""
131
+ ? parseInt(unitPriceCentsRaw, 10)
132
+ : undefined;
124
133
  ticketNumAndDatesArr.push({
125
134
  numberOfTickets: parseInt(numberOfTickets),
126
135
  ticketDateTime: ticketDateTimeFormattedStr,
136
+ ...(unitPriceCents != null && !Number.isNaN(unitPriceCents)
137
+ ? { unitPriceCents }
138
+ : {}),
127
139
  });
128
140
  }
129
141
  ticketList.set(ticketTierId, ticketNumAndDatesArr);
@@ -1 +1 @@
1
- {"version":3,"file":"ticketListUtils.js","sourceRoot":"","sources":["../../src/utils/ticketListUtils.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ticketListUtils.js","sourceRoot":"","sources":["../../src/utils/ticketListUtils.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bash-app/bash-common",
3
- "version": "30.275.0",
3
+ "version": "30.277.0",
4
4
  "description": "Common data and scripts to use on the frontend and backend",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -0,0 +1,39 @@
1
+ -- Competition prize catalog + entry ticket tier link
2
+ -- Safe additive migration — preserves all data
3
+ BEGIN;
4
+
5
+ -- Prize catalog fields
6
+ ALTER TABLE "Prize" ADD COLUMN IF NOT EXISTS "sponsorLabel" TEXT;
7
+ ALTER TABLE "Prize" ADD COLUMN IF NOT EXISTS "imageUrl" TEXT;
8
+
9
+ -- Competition entry ticket tier + host promotions acknowledgment
10
+ ALTER TABLE "Competition" ADD COLUMN IF NOT EXISTS "entryTicketTierId" TEXT;
11
+ ALTER TABLE "Competition" ADD COLUMN IF NOT EXISTS "hostPromotionsAckAt" TIMESTAMP(3);
12
+
13
+ DO $$
14
+ BEGIN
15
+ IF NOT EXISTS (
16
+ SELECT 1 FROM pg_constraint WHERE conname = 'Competition_entryTicketTierId_key'
17
+ ) THEN
18
+ ALTER TABLE "Competition"
19
+ ADD CONSTRAINT "Competition_entryTicketTierId_key" UNIQUE ("entryTicketTierId");
20
+ END IF;
21
+ END $$;
22
+
23
+ DO $$
24
+ BEGIN
25
+ IF NOT EXISTS (
26
+ SELECT 1 FROM pg_constraint WHERE conname = 'Competition_entryTicketTierId_fkey'
27
+ ) THEN
28
+ ALTER TABLE "Competition"
29
+ ADD CONSTRAINT "Competition_entryTicketTierId_fkey"
30
+ FOREIGN KEY ("entryTicketTierId") REFERENCES "TicketTier"("id")
31
+ ON DELETE SET NULL ON UPDATE CASCADE;
32
+ END IF;
33
+ END $$;
34
+
35
+ COMMIT;
36
+
37
+ -- Verification
38
+ -- SELECT column_name FROM information_schema.columns WHERE table_name = 'Prize' AND column_name IN ('sponsorLabel', 'imageUrl');
39
+ -- SELECT column_name FROM information_schema.columns WHERE table_name = 'Competition' AND column_name IN ('entryTicketTierId', 'hostPromotionsAckAt');
@@ -239,12 +239,25 @@ model Competition {
239
239
  bracketData Json? // Store bracket structure/metadata
240
240
  bracketVisible Boolean @default(true)
241
241
 
242
+ /// Optional ticket tier required for competition entry (participation fee / game entry)
243
+ entryTicketTierId String? @unique
244
+ entryTicketTier TicketTier? @relation("CompetitionEntryTicketTier", fields: [entryTicketTierId], references: [id], onDelete: SetNull)
245
+ /// When the host acknowledged contests/promotions Terms at setup
246
+ hostPromotionsAckAt DateTime?
247
+ /// Minimum event donation (cents) that qualifies for game entry when no linked tier (or OR with tier).
248
+ entryMinDonationCents Int?
249
+ /// Optional fundraising goal for public progress display (participation revenue + donations).
250
+ fundraiserGoalCents Int?
251
+ /// Host accepts inbound prize contributions from users/businesses.
252
+ seekingPrizes Boolean @default(false)
253
+
242
254
  createdAt DateTime @default(now())
243
255
  updatedAt DateTime @updatedAt
244
256
  bashEvent BashEvent @relation(fields: [bashEventId], references: [id], onDelete: Cascade)
245
257
  owner User @relation(fields: [userId], references: [id], onDelete: Cascade)
246
258
  sponsor CompetitionSponsor[]
247
259
  prizes Prize[]
260
+ prizeOffers CompetitionPrizeOffer[]
248
261
  participants CompetitionParticipant[]
249
262
  votes CompetitionVote[]
250
263
  matches CompetitionMatch[]
@@ -289,13 +302,46 @@ model CompetitionJudgeScore {
289
302
  }
290
303
 
291
304
  model CompetitionSponsor {
292
- id String @id @default(cuid())
293
- competitionId String
294
- userId String
295
- description String
296
- paidOn String?
297
- competition Competition @relation(fields: [competitionId], references: [id], onDelete: Cascade)
298
- sponsor User @relation(fields: [userId], references: [id], onDelete: Cascade)
305
+ id String @id @default(cuid())
306
+ competitionId String
307
+ userId String?
308
+ /// Optional link to a Sponsor marketplace service for discovery/branding
309
+ sourceServiceId String?
310
+ /// Display name when sponsor is not a platform user
311
+ sponsorName String?
312
+ logoUrl String?
313
+ description String?
314
+ paidOn String?
315
+ competition Competition @relation(fields: [competitionId], references: [id], onDelete: Cascade)
316
+ sponsor User? @relation(fields: [userId], references: [id], onDelete: Cascade)
317
+ sourceService Service? @relation("CompetitionSponsorSourceService", fields: [sourceServiceId], references: [id], onDelete: SetNull)
318
+
319
+ @@index([sourceServiceId])
320
+ }
321
+
322
+ /// Inbound prize contribution proposal (Bash matchmaker — host accepts → Prize row).
323
+ model CompetitionPrizeOffer {
324
+ id String @id @default(cuid())
325
+ competitionId String
326
+ offeredByUserId String
327
+ status CompetitionPrizeOfferStatus @default(PENDING)
328
+ name String
329
+ description String @db.Text
330
+ imageUrl String?
331
+ sponsorLabel String?
332
+ sourceServiceId String?
333
+ sourceSku String?
334
+ hostNote String?
335
+ createdAt DateTime @default(now())
336
+ updatedAt DateTime @updatedAt
337
+ respondedAt DateTime?
338
+ competition Competition @relation(fields: [competitionId], references: [id], onDelete: Cascade)
339
+ offeredBy User @relation("CompetitionPrizeOffersSubmitted", fields: [offeredByUserId], references: [id], onDelete: Cascade)
340
+ sourceService Service? @relation("CompetitionPrizeOfferSourceService", fields: [sourceServiceId], references: [id], onDelete: SetNull)
341
+
342
+ @@index([competitionId])
343
+ @@index([offeredByUserId])
344
+ @@index([status])
299
345
  }
300
346
 
301
347
  model CompetitionParticipant {
@@ -658,6 +704,8 @@ model BashEvent {
658
704
  country String?
659
705
  /// When true, street/place/full location and map pin are hidden until public reveal or gated audience.
660
706
  hideLocation Boolean @default(false)
707
+ /// When false, the map is hidden on the bash detail page (address link may still show).
708
+ showMap Boolean @default(true)
661
709
  /// Freeform area hint shown to everyone when hideLocation (e.g. "Lower East Side").
662
710
  publicAreaHint String?
663
711
  locationRevealAudience LocationRevealAudience @default(TicketHolders)
@@ -687,7 +735,7 @@ model BashEvent {
687
735
  allowDonations Boolean? @default(false)
688
736
  suggestedDonationAmount Int?
689
737
  donationDetails String?
690
- absorbDonationFees Boolean @default(false)
738
+ absorbDonationFees Boolean @default(true)
691
739
  absorbTicketFees Boolean @default(false)
692
740
  /// Phase 1 of unified-pricing roadmap: governs where PER_BASHPOINTS_ATTENDEE
693
741
  /// settlements are paid from. `HostWallet` (default) pays directly from the
@@ -2034,8 +2082,13 @@ model TicketTier {
2034
2082
  bashPassEligible Boolean @default(false)
2035
2083
  /// Max BashPass redemptions for this tier (null = unlimited within tier capacity).
2036
2084
  bashPassMaxRedemptions Int?
2085
+ /// One checkout buys a fixed package (e.g. table); price is package total, not per-person.
2086
+ isGroupTicket Boolean @default(false)
2087
+ /// Headcount included per package when isGroupTicket (e.g. 6). Required when isGroupTicket.
2088
+ groupTicketSeatCount Int?
2037
2089
  ticketGiftGrants TicketGiftGrant[]
2038
2090
  tierReleaseReminders TierReleaseReminder[]
2091
+ entryCompetition Competition? @relation("CompetitionEntryTicketTier")
2039
2092
 
2040
2093
  @@unique([bashEventId, title])
2041
2094
  @@index([availableAt])
@@ -2113,6 +2166,8 @@ model Ticket {
2113
2166
  waitlistUserId String?
2114
2167
  /// Rotated when ticket is transferred; QR payload must match for check-in (null = legacy tickets, no strict check).
2115
2168
  qrToken String?
2169
+ /// Actual unit price paid at checkout in cents (PWYC tiers; null = use tier.price for legacy rows).
2170
+ paidUnitPriceCents Int?
2116
2171
 
2117
2172
  /// P2P Venmo/Zelle off-platform payment flow
2118
2173
  p2pPaymentMethod String?
@@ -2286,6 +2341,11 @@ model Recurrence {
2286
2341
  repeatOnDays DayOfWeek[]
2287
2342
  repeatOnDayOfMonth Int?
2288
2343
  repeatYearlyDate DateTime?
2344
+ // Per-occurrence exceptions for the computed series (no occurrence rows are materialized):
2345
+ // dates the host removed from the series (matched against the generated occurrence start instants).
2346
+ excludedDates DateTime[]
2347
+ // Per-occurrence date/time moves: JSON map of original-occurrence ISO start -> { startDateTime, endDateTime? }.
2348
+ occurrenceOverrides Json?
2289
2349
  createdAt DateTime @default(now())
2290
2350
  updatedAt DateTime @updatedAt
2291
2351
  bashEvent BashEvent @relation(fields: [bashEventId], references: [id], onDelete: Cascade)
@@ -2470,6 +2530,8 @@ model Prize {
2470
2530
  prizeType PrizeType
2471
2531
  name String // Prize name (e.g., "$100 Cash", "Backpack")
2472
2532
  placeName String? // Display name (e.g., "1st Place", "Winner")
2533
+ sponsorLabel String? // e.g. "Contributed by Acme Co"
2534
+ imageUrl String? // Optional prize photo
2473
2535
  prizeLevel Int
2474
2536
  description String
2475
2537
  competitionId String?
@@ -2477,6 +2539,16 @@ model Prize {
2477
2539
  winnerUserId String?
2478
2540
  wonAt DateTime? // When the prize was awarded
2479
2541
  claimedAt DateTime? // When the prize was claimed
2542
+ /// Platform user who donated this prize (optional)
2543
+ contributorUserId String?
2544
+ /// Sponsor marketplace service the prize was picked from (optional)
2545
+ sourceServiceId String?
2546
+ sourceSku String?
2547
+ /// Contributor marked their in-kind commitment fulfilled (off-platform delivery via host)
2548
+ contributorFulfilledAt DateTime?
2549
+ contributorFulfilledNote String?
2550
+ /// Host marked prize handed to winner
2551
+ hostDeliveredAt DateTime?
2480
2552
 
2481
2553
  // Automatic payment fields
2482
2554
  autoPayEnabled Boolean @default(false)
@@ -2497,10 +2569,14 @@ model Prize {
2497
2569
 
2498
2570
  competition Competition? @relation(fields: [competitionId], references: [id], onDelete: Cascade)
2499
2571
  winner User? @relation(fields: [winnerUserId], references: [id], onDelete: Cascade)
2572
+ contributor User? @relation("PrizeContributor", fields: [contributorUserId], references: [id], onDelete: SetNull)
2573
+ sourceService Service? @relation("PrizeSourceService", fields: [sourceServiceId], references: [id], onDelete: SetNull)
2500
2574
  bashPointsTransaction BashCreditTransaction? @relation(fields: [bashPointsTransactionId], references: [id], onDelete: SetNull)
2501
2575
 
2502
2576
  @@index([competitionId])
2503
2577
  @@index([winnerUserId]) // For fetching user's wins
2578
+ @@index([contributorUserId])
2579
+ @@index([sourceServiceId])
2504
2580
  @@index([bashPointsTransactionId])
2505
2581
  }
2506
2582
 
@@ -2601,6 +2677,8 @@ model User {
2601
2677
  /// Preferred processor for dual-rail onboarding (optional; legacy Stripe fields remain source of truth until fully migrated).
2602
2678
  paymentProvider PaymentProvider @default(STRIPE)
2603
2679
  isSuperUser Boolean @default(false)
2680
+ /// Enterprise: super-users may set event feeHandling to GuestPays/Split for this host.
2681
+ allowGuestFeePassThrough Boolean @default(false)
2604
2682
  isSuspended Boolean @default(false)
2605
2683
  intent UserIntent?
2606
2684
  signupSource String? // e.g. 'jamwith', 'mixlog', 'organic' for attribution
@@ -2819,6 +2897,8 @@ model User {
2819
2897
  clubMembers ClubMember[]
2820
2898
  competitions Competition[]
2821
2899
  competitionSponsorships CompetitionSponsor[]
2900
+ competitionPrizeOffersSubmitted CompetitionPrizeOffer[] @relation("CompetitionPrizeOffersSubmitted")
2901
+ prizesContributed Prize[] @relation("PrizeContributor")
2822
2902
  competitionParticipations CompetitionParticipant[]
2823
2903
  competitionVotes CompetitionVote[]
2824
2904
  competitionJudgeAssignments CompetitionJudgeAssignment[] @relation("CompetitionJudgeAssignments")
@@ -3084,6 +3164,8 @@ model UserPreferences {
3084
3164
  autoDetectLocation Boolean @default(false)
3085
3165
  recentSearches String[] @default([])
3086
3166
  expandedSections String[] @default([])
3167
+ /// Homepage event category rows pinned to the top of Upcoming Events (bashType keys)
3168
+ pinnedHomepageSections String[] @default([])
3087
3169
  preferredCurrency String @default("USD")
3088
3170
  savePaymentInfo Boolean @default(false)
3089
3171
  showEventPrices Boolean @default(true)
@@ -3555,6 +3637,9 @@ model Service {
3555
3637
  promotionBlastTemplates PromotionBlastTemplate[]
3556
3638
  promotionBlastEntitlements PromotionBlastEntitlement[]
3557
3639
  promotionBlasts PromotionBlast[]
3640
+ competitionPrizesSourced Prize[] @relation("PrizeSourceService")
3641
+ competitionSponsorCredits CompetitionSponsor[] @relation("CompetitionSponsorSourceService")
3642
+ competitionPrizeOffersSourced CompetitionPrizeOffer[] @relation("CompetitionPrizeOfferSourceService")
3558
3643
 
3559
3644
  @@index([serviceListingStripeSubscriptionId])
3560
3645
  @@index([paymentAccountId])
@@ -4947,6 +5032,14 @@ model ServiceBooking {
4947
5032
  settlementDisputedAt DateTime?
4948
5033
  // When the delta refund actually lands at the issuing bank.
4949
5034
  refundedOn DateTime?
5035
+ // Host-initiated reschedule: when the bash date/time changes we sync the booked
5036
+ // days to the new date (assume-accept) and ask the provider to confirm or reject.
5037
+ // Reject cancels the booking with a full host refund; silence keeps the new date.
5038
+ rescheduleStatus ServiceBookingRescheduleStatus @default(None)
5039
+ rescheduleRequestedOn DateTime?
5040
+ rescheduleDecisionOn DateTime?
5041
+ reschedulePrevStartDate DateTime?
5042
+ reschedulePrevEndDate DateTime?
4950
5043
  notification Notification[]
4951
5044
  bashEvent BashEvent? @relation(fields: [bashEventId], references: [id])
4952
5045
  creator User @relation("BookingCreator", fields: [creatorId], references: [id])
@@ -6108,6 +6201,13 @@ enum PrizePaymentMethod {
6108
6201
  Manual
6109
6202
  }
6110
6203
 
6204
+ enum CompetitionPrizeOfferStatus {
6205
+ PENDING
6206
+ ACCEPTED
6207
+ DECLINED
6208
+ WITHDRAWN
6209
+ }
6210
+
6111
6211
  enum PrizePaymentStatus {
6112
6212
  Pending
6113
6213
  AwaitingPayment
@@ -7470,6 +7570,14 @@ enum ServiceBookingStatus {
7470
7570
  Canceled
7471
7571
  }
7472
7572
 
7573
+ // Provider's response to a host-initiated bash date change.
7574
+ enum ServiceBookingRescheduleStatus {
7575
+ None
7576
+ Pending
7577
+ Accepted
7578
+ Rejected
7579
+ }
7580
+
7473
7581
  enum ServiceBookingType {
7474
7582
  Request
7475
7583
  Instant
@@ -9171,6 +9279,8 @@ model GroupMember {
9171
9279
  userId String
9172
9280
  status GroupMemberStatus @default(Invited)
9173
9281
  ticketId String? // Set when status = Going
9282
+ /// Group leader marked this member as having reimbursed their share off-platform (Venmo, etc.)
9283
+ reimbursedLeaderAt DateTime?
9174
9284
  joinedAt DateTime @default(now())
9175
9285
 
9176
9286
  group EventGroup @relation(fields: [groupId], references: [id], onDelete: Cascade)
@@ -0,0 +1,53 @@
1
+ import {
2
+ formatGroupPackagePerPersonUsd,
3
+ groupPackageShareCents,
4
+ isGroupTicketTier,
5
+ packagesSoldFromTicketCount,
6
+ validateGroupTicketTierInput,
7
+ } from "../groupTicketUtils.js";
8
+
9
+ describe("isGroupTicketTier", () => {
10
+ it("returns true when flag and seat count are valid", () => {
11
+ expect(
12
+ isGroupTicketTier({ isGroupTicket: true, groupTicketSeatCount: 6 })
13
+ ).toBe(true);
14
+ });
15
+
16
+ it("returns false when seat count is below minimum", () => {
17
+ expect(
18
+ isGroupTicketTier({ isGroupTicket: true, groupTicketSeatCount: 1 })
19
+ ).toBe(false);
20
+ });
21
+ });
22
+
23
+ describe("packagesSoldFromTicketCount", () => {
24
+ it("converts seat rows to package count", () => {
25
+ expect(packagesSoldFromTicketCount(12, 6)).toBe(2);
26
+ expect(packagesSoldFromTicketCount(7, 6)).toBe(2);
27
+ });
28
+ });
29
+
30
+ describe("groupPackageShareCents", () => {
31
+ it("splits package price evenly in cents", () => {
32
+ expect(groupPackageShareCents(60000, 6)).toBe(10000);
33
+ });
34
+ });
35
+
36
+ describe("formatGroupPackagePerPersonUsd", () => {
37
+ it("formats per-person USD", () => {
38
+ expect(formatGroupPackagePerPersonUsd(60000, 6)).toMatch(/\$100/);
39
+ });
40
+ });
41
+
42
+ describe("validateGroupTicketTierInput", () => {
43
+ it("rejects donation group packages", () => {
44
+ const result = validateGroupTicketTierInput({
45
+ isGroupTicket: true,
46
+ groupTicketSeatCount: 6,
47
+ isDonationTier: true,
48
+ isWaitlistTier: false,
49
+ pricingType: "USD",
50
+ });
51
+ expect(result.ok).toBe(false);
52
+ });
53
+ });