@bash-app/bash-common 30.5.0 → 30.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bash-app/bash-common",
3
- "version": "30.5.0",
3
+ "version": "30.7.0",
4
4
  "description": "Common data and scripts to use on the frontend and backend",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
@@ -99,7 +99,7 @@ model EventTask {
99
99
  creator User @relation(fields: [creatorId], references: [id], onDelete: Cascade)
100
100
  bashEventId String
101
101
  bashEvent BashEvent @relation(fields: [bashEventId], references: [id], onDelete: Cascade)
102
- title String
102
+ title String
103
103
  description String?
104
104
  assignedToId String?
105
105
  assignedTo User? @relation("TasksAssignedToMe", fields: [assignedToId], references: [id], onDelete: Cascade)
@@ -113,6 +113,7 @@ enum TaskStatus {
113
113
  Rejected
114
114
  Completed
115
115
  Assigned
116
+ Pending
116
117
  Open
117
118
  }
118
119
 
@@ -138,10 +139,60 @@ model BashEventPromoCode {
138
139
  maxRedemptions Int?
139
140
  redeemBy DateTime?
140
141
  usedBy User[]
142
+ promoter Promoter? @relation(fields: [promoterId], references: [id])
143
+ promoterId String? // Remove the @unique constraint here
144
+ meta String?
141
145
 
142
146
  @@unique([ticketTierId, code])
143
147
  }
144
148
 
149
+ model Promoter {
150
+ id String @id @default(cuid())
151
+ promoterId String // The user who is promoting
152
+ promotedForBash String // The bash being promoted
153
+ level Int @default(1)
154
+ isActive Boolean @default(true)
155
+ commissionRate Float @default(5.0)
156
+ creditsGenerated Int @default(0)
157
+ earningsGenerated Float @default(0.00)
158
+ createdAt DateTime @default(now())
159
+ updatedAt DateTime @updatedAt
160
+ promoCodes BashEventPromoCode[] // This allows one promoter to have multiple promo codes
161
+ promoterUser User @relation(fields: [userId], references: [id])
162
+ userId String
163
+
164
+ @@unique([promoterId, promotedForBash])
165
+ }
166
+
167
+ model PromoterStats {
168
+ id String @id @default(cuid())
169
+ userId String @unique
170
+ user User @relation(fields: [userId], references: [id])
171
+ directSignups Int @default(0)
172
+ indirectSignups Int @default(0)
173
+ totalSignups Int @default(0)
174
+ directClicks Int @default(0)
175
+ indirectClicks Int @default(0)
176
+ totalClicks Int @default(0)
177
+ directCreditsEarned Int @default(0)
178
+ indirectCreditsEarned Int @default(0)
179
+ totalCreditsEarned Int @default(0)
180
+ createdAt DateTime @default(now())
181
+ updatedAt DateTime @updatedAt
182
+ }
183
+
184
+ model PromoterClick {
185
+ id String @id @default(cuid())
186
+ promoterId String // References Promoter.id
187
+ promoterCode String?
188
+ userAgent String?
189
+ ipHash String? // Store a hash of IP for privacy
190
+ converted Boolean @default(false)
191
+ attributionChain String // JSON string of the full attribution path
192
+ createdAt DateTime @default(now())
193
+ clickedAt DateTime @default(now())
194
+ }
195
+
145
196
  model BashNotification {
146
197
  id String @id @default(cuid())
147
198
  creatorId String
@@ -164,7 +215,7 @@ model BashNotification {
164
215
  reminders Reminder[]
165
216
  redirectUrl String?
166
217
 
167
- @@unique([creatorId, email, bashEventId])
218
+ @@unique([creatorId, email, bashEventId, taskId])
168
219
  @@unique([creatorId, email, invitationId])
169
220
  @@unique([creatorId, email, serviceBookingId])
170
221
  @@index([creatorId])
@@ -948,6 +999,8 @@ model User {
948
999
  serviceBookingForCreator ServiceBooking[] @relation("BookingCreator")
949
1000
  serviceBookingForUser ServiceBooking[] @relation("BookingForUser")
950
1001
  serviceBookingCheckout ServiceBookingCheckout[]
1002
+ promoter Promoter[]
1003
+ promoterStats PromoterStats?
951
1004
  }
952
1005
 
953
1006
  model Contact {
@@ -1151,7 +1204,7 @@ model Service {
1151
1204
  serviceLinks ServiceLink[]
1152
1205
 
1153
1206
  volunteerServiceId String? @unique
1154
- volunteerService VolunteerService? @relation(fields: [volunteerServiceId], references: [id], onDelete: Cascade)
1207
+ volunteerService VolunteerService? @relation("ServiceToVolunteer")
1155
1208
  eventServiceId String? @unique
1156
1209
  eventService EventService? @relation(fields: [eventServiceId], references: [id], onDelete: Cascade)
1157
1210
  entertainmentServiceId String? @unique
@@ -1199,26 +1252,38 @@ model StripeAccount {
1199
1252
  }
1200
1253
 
1201
1254
  model VolunteerService {
1202
- id String @id @default(cuid())
1203
- // service Service
1204
- userId String?
1205
- user User? @relation(fields: [userId], references: [id])
1206
- serviceRangeId String?
1207
- serviceRange ServiceRange? @relation(fields: [serviceRangeId], references: [id])
1208
- links Link[] @relation("VolunteerServiceLinks")
1209
- // availableDateTimes ServiceAvailability[] @relation("AvailableDateTimes")
1210
- fullName String?
1211
- address String?
1212
- email String?
1213
- phone String?
1214
- agreedToAgreement Boolean? @default(false)
1215
- description String?
1216
- status VolunteerServiceStatus?
1217
- media Media[]
1255
+ id String @id @default(cuid())
1256
+ userId String // Make required, not nullable
1257
+ user User @relation(fields: [userId], references: [id])
1258
+ serviceRangeId String?
1259
+ serviceRange ServiceRange? @relation(fields: [serviceRangeId], references: [id])
1260
+ links Link[] @relation("VolunteerServiceLinks")
1261
+ fullName String?
1262
+ address String?
1263
+ email String?
1264
+ phone String?
1265
+ agreedToAgreement Boolean @default(false) // Remove nullable
1266
+ description String @default("") // Make required with default
1267
+ status VolunteerServiceStatus @default(Draft) // Make required with default
1268
+ media Media[]
1269
+ skills String?
1270
+ experienceLevel String?
1271
+ preferredEventTypes String[] @default([])
1272
+ availability String[] @default([])
1273
+ physicalCapabilities String?
1274
+ equipment String?
1275
+ transportation String?
1276
+ emergencyContactName String?
1277
+ emergencyContactPhone String?
1218
1278
 
1219
1279
  serviceRatesAssociation ServiceRatesAssociation?
1220
1280
 
1221
- service Service?
1281
+ // Make this a required one-to-one relationship
1282
+ service Service @relation("ServiceToVolunteer", fields: [serviceId], references: [id])
1283
+ serviceId String @unique
1284
+
1285
+ // Add indexes for better performance
1286
+ @@index([userId])
1222
1287
  }
1223
1288
 
1224
1289
  model EventService {
@@ -1498,6 +1563,11 @@ enum ServiceRateType {
1498
1563
  // WEEKLY
1499
1564
  }
1500
1565
 
1566
+ enum ServiceAddonStatus {
1567
+ Enabled
1568
+ Disabled
1569
+ }
1570
+
1501
1571
  //can optionally be associated with a package
1502
1572
  model ServiceAddon {
1503
1573
  id String @id @default(cuid())
@@ -1506,6 +1576,8 @@ model ServiceAddon {
1506
1576
  priceCents Int
1507
1577
  quantity Int
1508
1578
 
1579
+ status ServiceAddonStatus @default(Enabled)
1580
+
1509
1581
  servicePackage ServicePackage? @relation(fields: [servicePackageId], references: [id], onDelete: Cascade)
1510
1582
  servicePackageId String?
1511
1583
 
@@ -1750,6 +1822,8 @@ model ServiceBookingCheckout {
1750
1822
  stripeCheckoutSessionId String? @unique
1751
1823
  stripePaymentIntentId String? @unique
1752
1824
 
1825
+ stripeRefundId String? @unique
1826
+
1753
1827
  paidOn DateTime?
1754
1828
  refundedOn DateTime?
1755
1829
 
package/src/index.ts CHANGED
@@ -15,6 +15,7 @@ export * from "./utils/arrayUtils";
15
15
  export * from "./utils/promoCodesUtils";
16
16
  export * from "./utils/userPromoCodeUtils";
17
17
  export * from "./utils/userSubscriptionUtils";
18
+ export * from "./utils/service/regexUtils";
18
19
  export * from "./utils/service/serviceUtils";
19
20
  export * from "./utils/service/venueUtils";
20
21
  export * from "./utils/service/attendeeOptionUtils";
@@ -0,0 +1,11 @@
1
+ export function isPositiveInt(str: string): boolean {
2
+ return /^\d*$/.test(str);
3
+ }
4
+
5
+ export function isPositiveFloat(str: string): boolean {
6
+ return /^\d*\.?\d*$/.test(str);
7
+ }
8
+
9
+ export function isPrice(str: string): boolean {
10
+ return /^\d*\.?\d{0,2}$/.test(str);
11
+ }
@@ -107,11 +107,18 @@ export function serviceBookingCanHaveApprovalDecision(
107
107
  errorMessage: "Approval decisions can only be made on booking requests.",
108
108
  };
109
109
  }
110
- if (!serviceBookingIsPending(booking)) {
110
+ if (serviceBookingIsCanceled(booking)) {
111
+ return {
112
+ valid: false,
113
+ errorMessage:
114
+ "Approval decisions can not be made on canceled booking requests.",
115
+ };
116
+ }
117
+ if (serviceBookingIsConfirmed(booking)) {
111
118
  return {
112
119
  valid: false,
113
120
  errorMessage:
114
- "Approval decisions can only be made for pending booking requests.",
121
+ "Approval decisions can not be made on confirmed booking requests.",
115
122
  };
116
123
  }
117
124
 
@@ -64,7 +64,7 @@ export const SERVICE_CANCELLATION_POLICY_DATA: ServiceCancellationPolicyMap = {
64
64
  ],
65
65
  },
66
66
  [ServiceCancellationPolicyOption.Standard90Day]: {
67
- name: "Very Flexible",
67
+ name: "Standard 90 Day",
68
68
  refundPolicy: [
69
69
  {
70
70
  days: 90,