@bash-app/bash-common 30.97.0 → 30.98.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.
@@ -3,9 +3,8 @@ generator client {
3
3
  }
4
4
 
5
5
  datasource db {
6
- provider = "postgresql"
7
- url = env("POSTGRES_PRISMA_URL")
8
- directUrl = env("POSTGRES_URL_NON_POOLING")
6
+ provider = "postgresql"
7
+ url = env("POSTGRES_PRISMA_URL")
9
8
  }
10
9
 
11
10
  model Club {
@@ -54,16 +53,25 @@ model BashComment {
54
53
  }
55
54
 
56
55
  model Competition {
57
- id String @id @default(cuid())
58
- name String
59
- description String
60
- userId String
61
- bashEventId String
62
- numberOfPrizes Int
63
- bashEvent BashEvent @relation(fields: [bashEventId], references: [id], onDelete: Cascade)
64
- owner User @relation(fields: [userId], references: [id], onDelete: Cascade)
65
- sponsor CompetitionSponsor[]
66
- prizes Prize[]
56
+ id String @id @default(cuid())
57
+ name String
58
+ description String @db.Text
59
+ userId String
60
+ bashEventId String
61
+ numberOfPrizes Int
62
+ competitionType CompetitionType? // Main category
63
+ subtype String? // Subcategory
64
+ rules String? @db.Text // Detailed rules/disclaimers
65
+ judgingType JudgingType? // How winner is determined
66
+ createdAt DateTime @default(now())
67
+ updatedAt DateTime @updatedAt
68
+ bashEvent BashEvent @relation(fields: [bashEventId], references: [id], onDelete: Cascade)
69
+ owner User @relation(fields: [userId], references: [id], onDelete: Cascade)
70
+ sponsor CompetitionSponsor[]
71
+ prizes Prize[]
72
+
73
+ @@index([bashEventId])
74
+ @@index([competitionType])
67
75
  }
68
76
 
69
77
  model CompetitionSponsor {
@@ -366,6 +374,8 @@ model BashEvent {
366
374
  media Media[] @relation("BashEventToMedia")
367
375
  associatedServicesReferencingMe Service[] @relation("BashEventToService")
368
376
  userConnections UserConnection[]
377
+ aiRecommendationLogs AIRecommendationLog[]
378
+ aiRecommendationCaches AIRecommendationCache[]
369
379
  }
370
380
 
371
381
  model Coordinates {
@@ -732,14 +742,20 @@ model Prize {
732
742
  id String @id @default(cuid())
733
743
  prizeWorth Float?
734
744
  prizeType PrizeType
735
- name String
745
+ name String // Prize name (e.g., "$100 Cash", "Backpack")
746
+ placeName String? // Display name (e.g., "1st Place", "Winner")
736
747
  prizeLevel Int
737
748
  description String
738
749
  competitionId String?
739
750
  paidOn String?
740
751
  winnerUserId String?
741
- competition Competition? @relation(fields: [competitionId], references: [id])
752
+ wonAt DateTime? // When the prize was awarded
753
+ claimedAt DateTime? // When the prize was claimed
754
+ competition Competition? @relation(fields: [competitionId], references: [id], onDelete: Cascade)
742
755
  winner User? @relation(fields: [winnerUserId], references: [id], onDelete: Cascade)
756
+
757
+ @@index([competitionId])
758
+ @@index([winnerUserId]) // For fetching user's wins
743
759
  }
744
760
 
745
761
  model Review {
@@ -807,16 +823,22 @@ model SocialMediaProfile {
807
823
  }
808
824
 
809
825
  model User {
810
- id String @id @default(cuid())
811
- username String? @unique
812
- email String @unique
813
- createdOn DateTime @default(now())
814
- stripeCustomerId String? @unique
815
- stripeAccountId String? @unique
816
- isSuperUser Boolean @default(false)
817
- isSuspended Boolean @default(false)
818
- intent UserIntent?
819
- googleCalendarAccess String?
826
+ id String @id @default(cuid())
827
+ username String? @unique
828
+ email String @unique
829
+ createdOn DateTime @default(now())
830
+ stripeCustomerId String? @unique
831
+ stripeAccountId String? @unique
832
+ isSuperUser Boolean @default(false)
833
+ isSuspended Boolean @default(false)
834
+ intent UserIntent?
835
+ googleCalendarAccess String?
836
+
837
+ // Google OAuth tokens for API access (Contacts, Calendar, etc.)
838
+ googleAccessToken String?
839
+ googleRefreshToken String?
840
+ googleTokenExpiry DateTime?
841
+
820
842
  givenName String?
821
843
  familyName String?
822
844
  nameChangeCount Int @default(0)
@@ -901,8 +923,9 @@ model User {
901
923
 
902
924
  // Security Fields
903
925
  accountLockedUntil DateTime? // Account lockout timestamp for failed login protection
904
- auditLogs AuditLog[] @relation("UserAuditLogs")
905
- auditLogsPerformed AuditLog[] @relation("PerformedByUser")
926
+ revokedTokens RevokedToken[] @relation("RevokedTokens") // Revoked JWT tokens
927
+ auditLogs AuditLog[] @relation("UserAuditLogs")
928
+ auditLogsPerformed AuditLog[] @relation("PerformedByUser")
906
929
  consents UserConsent[]
907
930
 
908
931
  associatedBashes AssociatedBash[]
@@ -980,6 +1003,7 @@ model User {
980
1003
  connectionRequestsReceived UserConnection[] @relation("ConnectionRequestsReceived")
981
1004
  links UserLink[]
982
1005
  preferences UserPreferences?
1006
+ rankings UserRankings?
983
1007
  userPromoCodeRedemption UserPromoCodeRedemption[]
984
1008
  referralCode UserReferralCode?
985
1009
  referralTokens UserReferralToken[] @relation("UserReferralTokens")
@@ -990,6 +1014,7 @@ model User {
990
1014
  userSubscription UserSubscription?
991
1015
  vendorBid VendorBid[]
992
1016
  vendorBookingMessages VendorBookingMessage[] @relation("VendorMessageSender")
1017
+ serviceAnalytics ServiceAnalytics[] // Track service analytics for this user
993
1018
  vendorBookingRequestsAsHost VendorBookingRequest[] @relation("VendorBookingHost")
994
1019
  volunteerService VolunteerService[]
995
1020
  reviewedAmbashadorApps AmbashadorApplication[] @relation("AmbashadorReviewer")
@@ -999,6 +1024,7 @@ model User {
999
1024
  bashEventPromoCodesIUsed BashEventPromoCode[] @relation("BashEventPromoCodeToUser")
1000
1025
  ticketTiersWaitListsIveJoined TicketTier[] @relation("TicketTierToUser")
1001
1026
  scoutReferralsMade ScoutReferral[] @relation("ScoutReferrer")
1027
+ aiRecommendationLogs AIRecommendationLog[]
1002
1028
  scoutReferralsReceived ScoutReferral[] @relation("ScoutReferred")
1003
1029
  bookingCommissionsEarned BookingCommission[] @relation("CommissionReferrer")
1004
1030
 
@@ -1043,6 +1069,7 @@ model UserPreferences {
1043
1069
  showEmailPublicly Boolean @default(true)
1044
1070
  showPhonePublicly Boolean @default(false)
1045
1071
  showAddressPublicly Boolean @default(false)
1072
+ showCompetitionWins Boolean @default(true) // Display competition wins on public profile
1046
1073
  theme String @default("system")
1047
1074
  language String @default("en")
1048
1075
  timeZone String @default("America/New_York")
@@ -1098,6 +1125,9 @@ model UserPreferences {
1098
1125
  localEventsToCalendarSync Boolean @default(false)
1099
1126
  localEventsCity String @default("")
1100
1127
  localEventsState String @default("")
1128
+ showRankings Boolean @default(true) // Show rankings on profile
1129
+ showAttendeeRank Boolean @default(true) // Show attendee rank publicly
1130
+ showHostRank Boolean @default(true) // Show host rank publicly
1101
1131
  user User @relation(fields: [userId], references: [id], onDelete: Cascade)
1102
1132
  }
1103
1133
 
@@ -1116,6 +1146,42 @@ model UserFollowing {
1116
1146
  @@unique([userId, followingId])
1117
1147
  }
1118
1148
 
1149
+ model UserRankings {
1150
+ id String @id @default(cuid())
1151
+ userId String @unique
1152
+ attendeeScore Int @default(0) // Number of events attended
1153
+ hostScore Int @default(0) // Number of events hosted
1154
+ totalAttendeesScore Int @default(0) // Total attendees across all hosted events
1155
+ attendeeRankGlobal Int? // Global rank as attendee
1156
+ attendeeRankNational Int? // National rank as attendee
1157
+ attendeeRankCity Int? // City rank as attendee
1158
+ hostRankGlobal Int? // Global rank as host
1159
+ hostRankNational Int? // National rank as host
1160
+ hostRankCity Int? // City rank as host
1161
+ totalAttendeesRankGlobal Int? // Global rank by total attendees
1162
+ totalAttendeesRankNational Int? // National rank by total attendees
1163
+ totalAttendeesRankCity Int? // City rank by total attendees
1164
+ attendeePercentile Float? // Percentile rank as attendee (0-100)
1165
+ hostPercentile Float? // Percentile rank as host (0-100)
1166
+ totalAttendeesPercentile Float? // Percentile rank by total attendees (0-100)
1167
+ city String? // City for location-based rankings
1168
+ country String @default("US") // Country for location-based rankings
1169
+ lastScoreUpdate DateTime @default(now()) // When scores were last calculated
1170
+ lastCalculated DateTime @default(now()) // When ranks were last calculated
1171
+ createdAt DateTime @default(now())
1172
+ updatedAt DateTime @updatedAt
1173
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
1174
+
1175
+ @@index([userId])
1176
+ @@index([attendeeScore])
1177
+ @@index([hostScore])
1178
+ @@index([totalAttendeesScore])
1179
+ @@index([city])
1180
+ @@index([country])
1181
+ @@index([attendeeRankGlobal])
1182
+ @@index([hostRankGlobal])
1183
+ }
1184
+
1119
1185
  model UserConnection {
1120
1186
  id String @id @default(cuid())
1121
1187
  requesterId String // User who sent the request
@@ -1366,6 +1432,7 @@ model Service {
1366
1432
  associatedBashesReferencingMe AssociatedBash[] @relation("AssociatedBashToService")
1367
1433
  bashEvent BashEvent[] @relation("BashEventToService")
1368
1434
  media Media[] @relation("MediaToService")
1435
+ analytics ServiceAnalytics[] // Track service analytics
1369
1436
  scoutReferrals ScoutReferral[] @relation("ScoutServiceProfile")
1370
1437
  bookingCommissions BookingCommission[] @relation("CommissionServiceProfile")
1371
1438
 
@@ -1863,42 +1930,42 @@ model ServiceBookingCheckout {
1863
1930
  }
1864
1931
 
1865
1932
  model ServiceBooking {
1866
- id String @id @default(cuid())
1867
- creatorId String
1868
- forUserId String
1869
- daysTotalATBCents Int
1870
- serviceId String
1871
- rateOption ServiceBookingRateOption @default(TimeBased)
1872
- flatRateCents Int?
1873
- status ServiceBookingStatus @default(Pending)
1874
- bookingType ServiceBookingType @default(Request)
1875
- timezone String
1876
- requestedOn DateTime?
1877
- requestDecisionOn DateTime?
1878
- bookedOn DateTime?
1879
- canceledOn DateTime?
1880
- isFreeGuest Boolean @default(false)
1881
- allowPromiseToPay Boolean @default(false)
1882
- totalATBCents Int
1883
- subtotalATBCents Int @default(0)
1884
- bashEventId String?
1885
- isVendorBid Boolean @default(false)
1886
- vendorBidAmountCents Int?
1887
- vendorEventDetails String?
1888
- bashCashApplied Int? // BashCash credits applied to this booking
1889
- bashCashTransactionId String? // Link to BashCreditTransaction
1890
- notification Notification[]
1891
- bashEvent BashEvent? @relation(fields: [bashEventId], references: [id])
1892
- creator User @relation("BookingCreator", fields: [creatorId], references: [id])
1893
- forUser User @relation("BookingForUser", fields: [forUserId], references: [id])
1894
- service Service @relation(fields: [serviceId], references: [id])
1895
- addOns ServiceBookingAddOn[]
1896
- checkout ServiceBookingCheckout?
1897
- bookedDays ServiceBookingDay[]
1898
- additionalFees ServiceBookingFee[]
1899
- messages ServiceBookingMessage[]
1900
- packages ServiceBookingPackage[]
1901
- commissions BookingCommission[] @relation("BookingCommissions")
1933
+ id String @id @default(cuid())
1934
+ creatorId String
1935
+ forUserId String
1936
+ daysTotalATBCents Int
1937
+ serviceId String
1938
+ rateOption ServiceBookingRateOption @default(TimeBased)
1939
+ flatRateCents Int?
1940
+ status ServiceBookingStatus @default(Pending)
1941
+ bookingType ServiceBookingType @default(Request)
1942
+ timezone String
1943
+ requestedOn DateTime?
1944
+ requestDecisionOn DateTime?
1945
+ bookedOn DateTime?
1946
+ canceledOn DateTime?
1947
+ isFreeGuest Boolean @default(false)
1948
+ allowPromiseToPay Boolean @default(false)
1949
+ totalATBCents Int
1950
+ subtotalATBCents Int @default(0)
1951
+ bashEventId String?
1952
+ isVendorBid Boolean @default(false)
1953
+ vendorBidAmountCents Int?
1954
+ vendorEventDetails String?
1955
+ bashCashApplied Int? // BashCash credits applied to this booking
1956
+ bashCashTransactionId String? // Link to BashCreditTransaction
1957
+ notification Notification[]
1958
+ bashEvent BashEvent? @relation(fields: [bashEventId], references: [id])
1959
+ creator User @relation("BookingCreator", fields: [creatorId], references: [id])
1960
+ forUser User @relation("BookingForUser", fields: [forUserId], references: [id])
1961
+ service Service @relation(fields: [serviceId], references: [id])
1962
+ addOns ServiceBookingAddOn[]
1963
+ checkout ServiceBookingCheckout?
1964
+ bookedDays ServiceBookingDay[]
1965
+ additionalFees ServiceBookingFee[]
1966
+ messages ServiceBookingMessage[]
1967
+ packages ServiceBookingPackage[]
1968
+ commissions BookingCommission[] @relation("BookingCommissions")
1902
1969
 
1903
1970
  @@index([status])
1904
1971
  @@index([creatorId])
@@ -2795,6 +2862,31 @@ enum PrizeType {
2795
2862
  Combo
2796
2863
  }
2797
2864
 
2865
+ enum CompetitionType {
2866
+ RAFFLE // Raffles & Drawings
2867
+ SKILL // Skill-Based Contests
2868
+ PHYSICAL // Physical & Outdoor
2869
+ INTERACTIVE // Interactive Audience
2870
+ SOCIAL_MEDIA // Social Media-Driven
2871
+ KIDS_FAMILY // Kids & Family
2872
+ FOOD_DRINK // Food & Drink
2873
+ VENDOR_BOOTH // Vendor Booth
2874
+ BUSINESS_PROFESSIONAL // Business / Professional
2875
+ RANDOMIZED // Randomized Participation
2876
+ SEASONAL_HOLIDAY // Seasonal or Holiday
2877
+ AUDIENCE_VOTING // Audience Voting-Based
2878
+ }
2879
+
2880
+ enum JudgingType {
2881
+ RANDOM_DRAW // Raffle-style random selection
2882
+ JUDGES // Panel of judges decides
2883
+ AUDIENCE_VOTE // Attendees vote
2884
+ METRICS // Based on measurable metrics
2885
+ HOST_CHOOSES // Host/organizer picks winner
2886
+ FIRST_COME // First X people win
2887
+ HIGHEST_BID // Auction-style
2888
+ }
2889
+
2798
2890
  enum Sex {
2799
2891
  Male
2800
2892
  Female
@@ -4240,6 +4332,25 @@ model AuditLog {
4240
4332
  @@index([ipAddress])
4241
4333
  }
4242
4334
 
4335
+ /// Token Revocation System
4336
+ /// Tracks revoked JWT tokens to prevent their reuse
4337
+ /// Required for secure logout, password changes, and account termination
4338
+ model RevokedToken {
4339
+ id String @id @default(cuid())
4340
+ userId String // Owner of the revoked token
4341
+ jti String @unique // JWT ID from token payload
4342
+ revokedAt DateTime @default(now())
4343
+ expiresAt DateTime // When the original token would have expired (for cleanup)
4344
+ reason String? // Why it was revoked: "logout", "password_change", "suspicious_activity", etc.
4345
+
4346
+ // Relation to user
4347
+ user User @relation("RevokedTokens", fields: [userId], references: [id], onDelete: Cascade)
4348
+
4349
+ @@index([jti]) // Fast lookup for token validation
4350
+ @@index([userId, revokedAt]) // User-specific revocation history
4351
+ @@index([expiresAt]) // For cleanup of old expired tokens
4352
+ }
4353
+
4243
4354
  enum AuditAction {
4244
4355
  // Authentication
4245
4356
  LOGIN_SUCCESS
@@ -4300,6 +4411,11 @@ enum AuditAction {
4300
4411
  DATA_IMPORTED
4301
4412
  SENSITIVE_DATA_ACCESSED
4302
4413
 
4414
+ // Compliance
4415
+ CONSENT_GIVEN
4416
+ CONSENT_WITHDRAWN
4417
+ POLICY_ACCEPTED
4418
+
4303
4419
  // Security
4304
4420
  SUSPICIOUS_ACTIVITY_DETECTED
4305
4421
  RATE_LIMIT_EXCEEDED
@@ -4317,6 +4433,7 @@ enum AuditCategory {
4317
4433
  Tickets
4318
4434
  AdminAction
4319
4435
  DataAccess
4436
+ Compliance
4320
4437
  Security
4321
4438
  }
4322
4439
 
@@ -4326,6 +4443,88 @@ enum AuditSeverity {
4326
4443
  Critical // Security incidents
4327
4444
  }
4328
4445
 
4446
+ // Service Analytics Tracking
4447
+ model ServiceAnalytics {
4448
+ id String @id @default(cuid())
4449
+ serviceId String
4450
+ userId String? // null for anonymous views
4451
+ eventType ServiceAnalyticsEvent
4452
+ serviceType ServiceTypes? // Venues, EventServices, etc.
4453
+ specificType String? // For detailed tracking (e.g., "WeddingVenue", "Restaurant")
4454
+ timestamp DateTime @default(now())
4455
+ sessionId String? // Track user sessions
4456
+ referrer String? // Where the user came from
4457
+ deviceType String? // mobile, desktop, tablet
4458
+ metadata Json? // Additional context data
4459
+
4460
+ service Service @relation(fields: [serviceId], references: [id], onDelete: Cascade)
4461
+ user User? @relation(fields: [userId], references: [id], onDelete: SetNull)
4462
+
4463
+ @@index([serviceId])
4464
+ @@index([userId])
4465
+ @@index([eventType])
4466
+ @@index([timestamp])
4467
+ @@index([serviceType])
4468
+ @@index([specificType])
4469
+ }
4470
+
4471
+ enum ServiceAnalyticsEvent {
4472
+ VIEW // Card/listing viewed
4473
+ CLICK // Card clicked
4474
+ DETAIL_VIEW // Detail page viewed
4475
+ FAVORITE // Added to favorites
4476
+ UNFAVORITE // Removed from favorites
4477
+ SHARE // Shared via link/social
4478
+ CONTACT_CLICK // Contact button clicked
4479
+ BOOKING_STARTED // Booking process initiated
4480
+ BOOKING_COMPLETED // Booking confirmed
4481
+ BOOKING_ABANDONED // User left during booking
4482
+ INQUIRY_SENT // Inquiry form submitted
4483
+ PHONE_CLICK // Phone number clicked
4484
+ EMAIL_CLICK // Email clicked
4485
+ WEBSITE_CLICK // Website link clicked
4486
+ DIRECTIONS_CLICK // Directions/map clicked
4487
+ PHOTO_VIEW // Photo gallery viewed
4488
+ VIDEO_PLAY // Video played
4489
+ REVIEW_VIEW // Reviews section viewed
4490
+ FILTER_APPLIED // When a user filters results
4491
+ }
4492
+
4493
+ // AI Recommendation System - Logs each recommendation request
4494
+ model AIRecommendationLog {
4495
+ id String @id @default(cuid())
4496
+ eventId String
4497
+ userId String
4498
+ venueId String?
4499
+ serviceType ServiceTypes
4500
+ recommendationCount Int @default(0)
4501
+ cacheHit Boolean @default(false)
4502
+ createdAt DateTime @default(now())
4503
+
4504
+ event BashEvent @relation(fields: [eventId], references: [id], onDelete: Cascade)
4505
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
4506
+
4507
+ @@index([eventId])
4508
+ @@index([userId])
4509
+ @@index([createdAt])
4510
+ }
4511
+
4512
+ // AI Recommendation Cache - Stores recommendations to reduce API costs
4513
+ model AIRecommendationCache {
4514
+ id String @id @default(cuid())
4515
+ cacheKey String @unique
4516
+ eventId String
4517
+ serviceType ServiceTypes
4518
+ recommendations Json // Array of ServiceRecommendation objects
4519
+ expiresAt DateTime
4520
+ createdAt DateTime @default(now())
4521
+
4522
+ event BashEvent @relation(fields: [eventId], references: [id], onDelete: Cascade)
4523
+
4524
+ @@index([eventId])
4525
+ @@index([expiresAt])
4526
+ }
4527
+
4329
4528
  enum VoucherStatus {
4330
4529
  Active
4331
4530
  Redeemed
@@ -2,8 +2,10 @@ import {
2
2
  BashEventDressTags,
3
3
  BashEventType,
4
4
  BashEventVibeTags,
5
+ CompetitionType,
5
6
  Contact,
6
7
  EntertainmentServiceType,
8
+ JudgingType,
7
9
  MembershipTier,
8
10
  MusicGenreType,
9
11
  Prisma,
@@ -877,7 +879,7 @@ export const YearsOfExperienceToString: { [key in YearsOfExperience]: string } =
877
879
  };
878
880
 
879
881
  // Export Prisma enums for use in frontend
880
- export { YearsOfExperience, EntertainmentServiceType, MusicGenreType, ServiceTypes };
882
+ export { YearsOfExperience, EntertainmentServiceType, MusicGenreType, ServiceTypes, CompetitionType, JudgingType };
881
883
 
882
884
  export type BashEventTypeToStringType = {
883
885
  [key in BashEventType]: string;
@@ -10,6 +10,7 @@ import {
10
10
  BlogPost,
11
11
  BlogTag,
12
12
  Checkout,
13
+ Competition,
13
14
  Contact,
14
15
  Coordinates,
15
16
  Demerit,
@@ -23,6 +24,7 @@ import {
23
24
  Notification,
24
25
  Organization,
25
26
  Prisma,
27
+ Prize,
26
28
  Recurrence,
27
29
  Reminder,
28
30
  Review,
@@ -154,6 +156,14 @@ export const PRIVATE_USER_ACCOUNT_TO_SELECT = {
154
156
 
155
157
  export interface SponsoredEventExt extends SponsoredEvent {}
156
158
 
159
+ export interface PrizeExt extends Prize {
160
+ winner?: PublicUser | null;
161
+ }
162
+
163
+ export interface CompetitionExt extends Competition {
164
+ prizes: PrizeExt[];
165
+ }
166
+
157
167
  export interface BashEventExt extends BashEvent {
158
168
  targetAudience?: TargetAudience;
159
169
  amountOfGuests?: AmountOfGuests;
@@ -169,6 +179,7 @@ export interface BashEventExt extends BashEvent {
169
179
  venueServiceId?: string;
170
180
  venueOwner?: PublicUser;
171
181
  sponsorships?: SponsoredEventExt[];
182
+ competitions?: CompetitionExt[];
172
183
  }
173
184
 
174
185
  export const TICKET_TIER_DATA_TO_INCLUDE = {
@@ -206,6 +217,17 @@ export const BASH_EVENT_DATA_TO_INCLUDE = {
206
217
  media: true,
207
218
  eventTasks: true,
208
219
  invitations: true,
220
+ competitions: {
221
+ include: {
222
+ prizes: {
223
+ include: {
224
+ winner: {
225
+ select: FRONT_END_USER_DATA_TO_SELECT,
226
+ },
227
+ },
228
+ },
229
+ },
230
+ },
209
231
  } satisfies Prisma.BashEventInclude;
210
232
 
211
233
  export const BASH_EVENT_DATA_TO_CLONE = [
package/src/index.ts CHANGED
@@ -38,6 +38,7 @@ export * from "./utils/service/serviceDBUtils";
38
38
  export * from "./utils/service/serviceRateUtils";
39
39
  export * from "./utils/stripeAccountUtils";
40
40
  export * from "./utils/userUtils";
41
+ export * from "./utils/venueTypeFormatter";
41
42
 
42
43
  // Export typeUtils types individually to avoid ValueOf conflict with definitions
43
44
  export { createAllTrueObject } from "./utils/typeUtils";
@@ -319,3 +319,4 @@ export function shouldWarnUser(violations: ContentViolation[], userTier: string)
319
319
 
320
320
 
321
321
 
322
+
@@ -0,0 +1,43 @@
1
+ export * from './addressUtils';
2
+ export * from './apiUtils';
3
+ export * from './arrayUtils';
4
+ export * from './awsS3Utils';
5
+ export * from './badgeUtils';
6
+ export * from './bashCashPaymentUtils';
7
+ export * from './blog/blogDbUtils';
8
+ export * from './blogUtils';
9
+ export * from './contentFilterUtils';
10
+ export * from './dateTimeUtils';
11
+ export * from './entityUtils';
12
+ export * from './generalDateTimeUtils';
13
+ export * from './luxonUtils';
14
+ export * from './mathUtils';
15
+ export * from './objUtils';
16
+ export * from './paymentUtils';
17
+ export * from './promoCodesUtils';
18
+ export * from './qrCodeUtils';
19
+ export * from './recurrenceUtils';
20
+ export * from './reviewUtils';
21
+ export * from './service/apiServiceBookingApiUtils';
22
+ export * from './service/attendeeOptionUtils';
23
+ export * from './service/frontendServiceBookingUtils';
24
+ export * from './service/regexUtils';
25
+ export * from './service/serviceBookingStatusUtils';
26
+ export * from './service/serviceBookingTypes';
27
+ export * from './service/serviceDBUtils';
28
+ // export * from './service/serviceRateDBUtils'; // File is all commented out
29
+ export * from './service/serviceRateTypes';
30
+ export * from './service/serviceRateUtils';
31
+ export * from './service/serviceUtils';
32
+ export * from './slugUtils';
33
+ export * from './sortUtils';
34
+ export * from './stringUtils';
35
+ export * from './stripeAccountUtils';
36
+ export * from './ticketListUtils';
37
+ export * from './typeUtils';
38
+ export * from './urlUtils';
39
+ export * from './userPromoCodeUtils';
40
+ export * from './userSubscriptionUtils';
41
+ export * from './userUtils';
42
+ export * from './venueTypeFormatter';
43
+
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Formats venue type enum values into human-readable display names
3
+ * Example: "OutdoorSpace" -> "Outdoor Space", "WeddingVenue" -> "Wedding Venue"
4
+ */
5
+ export function formatVenueType(venueType: string): string {
6
+ if (!venueType) return '';
7
+
8
+ // Insert space before capital letters (but not at the start)
9
+ return venueType.replace(/([A-Z])/g, ' $1').trim();
10
+ }
11
+
12
+ /**
13
+ * Formats an array of venue types into a human-readable string
14
+ */
15
+ export function formatVenueTypes(venueTypes: string[], maxDisplay: number = 2): string {
16
+ if (!Array.isArray(venueTypes) || venueTypes.length === 0) {
17
+ return '';
18
+ }
19
+
20
+ const formatted = venueTypes.slice(0, maxDisplay).map(formatVenueType);
21
+ const remaining = venueTypes.length - maxDisplay;
22
+
23
+ if (remaining > 0) {
24
+ return `${formatted.join(', ')} +${remaining} more`;
25
+ }
26
+
27
+ return formatted.join(', ');
28
+ }
29
+
30
+