@bash-app/bash-common 30.40.0 → 30.44.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 +1 -1
- package/prisma/schema.prisma +87 -46
- package/src/extendedSchemas.ts +9 -3
- package/src/utils/addressUtils.ts +34 -5
package/package.json
CHANGED
package/prisma/schema.prisma
CHANGED
|
@@ -94,18 +94,18 @@ model CompetitionSponsor {
|
|
|
94
94
|
}
|
|
95
95
|
|
|
96
96
|
model EventTask {
|
|
97
|
-
id
|
|
98
|
-
creatorId
|
|
99
|
-
creator
|
|
100
|
-
bashEventId
|
|
101
|
-
bashEvent
|
|
102
|
-
title
|
|
103
|
-
description
|
|
104
|
-
assignedToId
|
|
105
|
-
assignedTo
|
|
106
|
-
status
|
|
107
|
-
|
|
108
|
-
createdAt
|
|
97
|
+
id String @id @default(cuid())
|
|
98
|
+
creatorId String
|
|
99
|
+
creator User @relation(fields: [creatorId], references: [id], onDelete: Cascade)
|
|
100
|
+
bashEventId String
|
|
101
|
+
bashEvent BashEvent @relation(fields: [bashEventId], references: [id], onDelete: Cascade)
|
|
102
|
+
title String
|
|
103
|
+
description String?
|
|
104
|
+
assignedToId String?
|
|
105
|
+
assignedTo User? @relation("TasksAssignedToMe", fields: [assignedToId], references: [id], onDelete: Cascade)
|
|
106
|
+
status TaskStatus?
|
|
107
|
+
notificationsReferencingMe Notification[]
|
|
108
|
+
createdAt DateTime? @default(now())
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
enum TaskStatus {
|
|
@@ -118,14 +118,14 @@ enum TaskStatus {
|
|
|
118
118
|
}
|
|
119
119
|
|
|
120
120
|
model Reminder {
|
|
121
|
-
id String
|
|
121
|
+
id String @id @default(cuid())
|
|
122
122
|
creatorId String
|
|
123
|
-
creator User
|
|
123
|
+
creator User @relation("RemindersCreatedByMe", fields: [creatorId], references: [id], onDelete: Cascade)
|
|
124
124
|
remindWhoId String?
|
|
125
|
-
remindWho User?
|
|
125
|
+
remindWho User? @relation("RemindersAssignedToMe", fields: [remindWhoId], references: [id], onDelete: Cascade)
|
|
126
126
|
remindDateTime DateTime
|
|
127
127
|
notificationId String
|
|
128
|
-
notification
|
|
128
|
+
notification Notification @relation(fields: [notificationId], references: [id], onDelete: Cascade)
|
|
129
129
|
}
|
|
130
130
|
|
|
131
131
|
model BashEventPromoCode {
|
|
@@ -195,15 +195,18 @@ model PromoterClick {
|
|
|
195
195
|
clickedAt DateTime @default(now())
|
|
196
196
|
}
|
|
197
197
|
|
|
198
|
-
model
|
|
198
|
+
model Notification {
|
|
199
199
|
id String @id @default(cuid())
|
|
200
200
|
creatorId String
|
|
201
201
|
creator User @relation("NotificationsCreatedByMe", fields: [creatorId], references: [id], onDelete: Cascade)
|
|
202
202
|
email String
|
|
203
|
+
userId String? // Direct reference to recipient user
|
|
204
|
+
user User? @relation("NotificationsReceivedByMe", fields: [userId], references: [id], onDelete: Cascade)
|
|
203
205
|
createdDateTime DateTime @default(now())
|
|
204
206
|
message String
|
|
205
207
|
image String?
|
|
206
208
|
readDateTime DateTime?
|
|
209
|
+
type String // Notification type: "FOLLOW", "TASK", "EVENT", etc.
|
|
207
210
|
taskId String?
|
|
208
211
|
eventTask EventTask? @relation(fields: [taskId], references: [id], onDelete: Cascade)
|
|
209
212
|
invitationId String?
|
|
@@ -217,33 +220,41 @@ model BashNotification {
|
|
|
217
220
|
reminders Reminder[]
|
|
218
221
|
redirectUrl String?
|
|
219
222
|
|
|
223
|
+
// Additional specific fields for different notification types
|
|
224
|
+
actionTaken Boolean? // For notifications that may require action
|
|
225
|
+
actionType String? // Type of action taken (ACCEPT, REJECT, etc.)
|
|
226
|
+
priority String? // Priority level (HIGH, MEDIUM, LOW)
|
|
227
|
+
expiresAt DateTime? // For time-sensitive notifications
|
|
228
|
+
|
|
220
229
|
@@unique([creatorId, email, bashEventId, taskId])
|
|
221
230
|
@@unique([creatorId, email, invitationId])
|
|
222
231
|
@@unique([creatorId, email, serviceBookingId])
|
|
223
232
|
@@index([creatorId])
|
|
233
|
+
@@index([userId])
|
|
234
|
+
@@index([type]) // Add index for efficient filtering by notification type
|
|
224
235
|
}
|
|
225
236
|
|
|
226
237
|
model Invitation {
|
|
227
|
-
id
|
|
228
|
-
creatorId
|
|
229
|
-
creator
|
|
230
|
-
email
|
|
231
|
-
sentToId
|
|
232
|
-
sentTo
|
|
233
|
-
bashEventId
|
|
234
|
-
bashEvent
|
|
235
|
-
image
|
|
236
|
-
phone
|
|
237
|
-
name
|
|
238
|
-
message
|
|
239
|
-
inviteDate
|
|
240
|
-
acceptedDate
|
|
241
|
-
rejectedDate
|
|
242
|
-
maybeDate
|
|
243
|
-
isFreeGuest
|
|
244
|
-
tickets
|
|
245
|
-
|
|
246
|
-
associatedBash
|
|
238
|
+
id String @id @default(cuid())
|
|
239
|
+
creatorId String
|
|
240
|
+
creator User @relation("InvitationsCreatedByMe", fields: [creatorId], references: [id], onDelete: Cascade)
|
|
241
|
+
email String
|
|
242
|
+
sentToId String?
|
|
243
|
+
sentTo User? @relation("InvitationsSentToMe", fields: [sentToId], references: [id], onDelete: Cascade)
|
|
244
|
+
bashEventId String?
|
|
245
|
+
bashEvent BashEvent? @relation(fields: [bashEventId], references: [id], onDelete: Cascade)
|
|
246
|
+
image String?
|
|
247
|
+
phone String?
|
|
248
|
+
name String?
|
|
249
|
+
message String?
|
|
250
|
+
inviteDate DateTime? @default(now())
|
|
251
|
+
acceptedDate DateTime?
|
|
252
|
+
rejectedDate DateTime?
|
|
253
|
+
maybeDate DateTime?
|
|
254
|
+
isFreeGuest Boolean @default(false)
|
|
255
|
+
tickets Ticket[] @relation("TicketsForInvitation")
|
|
256
|
+
notifications Notification[]
|
|
257
|
+
associatedBash AssociatedBash?
|
|
247
258
|
|
|
248
259
|
@@index([email])
|
|
249
260
|
}
|
|
@@ -302,7 +313,7 @@ model BashEvent {
|
|
|
302
313
|
includedItems String[]
|
|
303
314
|
associatedBashesReferencingMe AssociatedBash[] // maybe rename later to AssociatedWithABash
|
|
304
315
|
associatedServicesReferencingMe Service[] // maybe rename later to AssociatedWithAService
|
|
305
|
-
|
|
316
|
+
notificationsReferencingMe Notification[]
|
|
306
317
|
checkouts Checkout[]
|
|
307
318
|
eventTasks EventTask[]
|
|
308
319
|
videoLink String?
|
|
@@ -1047,7 +1058,7 @@ model User {
|
|
|
1047
1058
|
associatedServices AssociatedService[]
|
|
1048
1059
|
invitationsCreatedByMe Invitation[] @relation("InvitationsCreatedByMe")
|
|
1049
1060
|
invitationsSentToMe Invitation[] @relation("InvitationsSentToMe")
|
|
1050
|
-
notificationsCreatedByMe
|
|
1061
|
+
notificationsCreatedByMe Notification[] @relation("NotificationsCreatedByMe")
|
|
1051
1062
|
remindersCreatedByMe Reminder[] @relation("RemindersCreatedByMe")
|
|
1052
1063
|
remindersAssignedToMe Reminder[] @relation("RemindersAssignedToMe")
|
|
1053
1064
|
eventTasksAssignedToMe EventTask[] @relation("TasksAssignedToMe")
|
|
@@ -1056,9 +1067,7 @@ model User {
|
|
|
1056
1067
|
contactlist ContactList[]
|
|
1057
1068
|
|
|
1058
1069
|
bashEventPromoCodesIUsed BashEventPromoCode[]
|
|
1059
|
-
// bookingForMe Booking[]
|
|
1060
1070
|
userSubscription UserSubscription?
|
|
1061
|
-
// serviceSubscriptions ServiceSubscription[]
|
|
1062
1071
|
volunteerService VolunteerService[]
|
|
1063
1072
|
stripeAccounts StripeAccount[]
|
|
1064
1073
|
userPromoCodeRedemption UserPromoCodeRedemption[]
|
|
@@ -1081,19 +1090,27 @@ model User {
|
|
|
1081
1090
|
preferences UserPreferences?
|
|
1082
1091
|
userStats UserStats?
|
|
1083
1092
|
|
|
1084
|
-
// Add fields for user suspension
|
|
1085
1093
|
suspendedUntil DateTime?
|
|
1086
1094
|
suspendedById String?
|
|
1087
1095
|
suspendedBy User? @relation("SuspendedUsers", fields: [suspendedById], references: [id], onDelete: SetNull)
|
|
1088
1096
|
suspendedUsers User[] @relation("SuspendedUsers")
|
|
1089
1097
|
|
|
1090
|
-
// Add relations for reports and demerits
|
|
1091
1098
|
reportsMade UserReport[] @relation("ReportsMade")
|
|
1092
1099
|
reportsReceived UserReport[] @relation("ReportsReceived")
|
|
1093
1100
|
reportsReviewed UserReport[] @relation("ReportsReviewed")
|
|
1094
1101
|
demerits Demerit[] @relation("UserDemerits")
|
|
1095
1102
|
issuedDemerits Demerit[] @relation("IssuedDemerits")
|
|
1096
1103
|
expungedDemerits Demerit[] @relation("ExpungedDemerits")
|
|
1104
|
+
|
|
1105
|
+
notification Notification[] @relation("NotificationsReceivedByMe")
|
|
1106
|
+
followers UserFollowing[] @relation("Following")
|
|
1107
|
+
following UserFollowing[] @relation("Follower")
|
|
1108
|
+
|
|
1109
|
+
// For lightweight sign-up
|
|
1110
|
+
isLightweightAccount Boolean @default(false)
|
|
1111
|
+
notifyForTrendingBashes Boolean @default(false)
|
|
1112
|
+
trendingBashThreshold Int @default(10) // Min attendees to trigger notification
|
|
1113
|
+
organizerUser UserFollowing[] @relation("FollowingOrganizers")
|
|
1097
1114
|
}
|
|
1098
1115
|
|
|
1099
1116
|
model UserPreferences {
|
|
@@ -1112,6 +1129,8 @@ model UserPreferences {
|
|
|
1112
1129
|
invitationNotify Boolean @default(true)
|
|
1113
1130
|
eventUpdatesNotify Boolean @default(true)
|
|
1114
1131
|
servicePromotionsNotify Boolean @default(true)
|
|
1132
|
+
trendingBashesNotify Boolean @default(false) // New field
|
|
1133
|
+
organizerUpdatesNotify Boolean @default(false) // New field
|
|
1115
1134
|
|
|
1116
1135
|
// Privacy Settings
|
|
1117
1136
|
profileVisibility String @default("PUBLIC") // PUBLIC, FRIENDS, PRIVATE
|
|
@@ -1164,6 +1183,23 @@ model UserPreferences {
|
|
|
1164
1183
|
updatedAt DateTime @updatedAt
|
|
1165
1184
|
}
|
|
1166
1185
|
|
|
1186
|
+
model UserFollowing {
|
|
1187
|
+
id String @id @default(cuid())
|
|
1188
|
+
userId String
|
|
1189
|
+
followingId String
|
|
1190
|
+
isFollowing Boolean @default(true)
|
|
1191
|
+
followedAt DateTime?
|
|
1192
|
+
unfollowedAt DateTime?
|
|
1193
|
+
isOrganizer Boolean @default(false) // Flag if following as organizer
|
|
1194
|
+
lastNotified DateTime? // For organizer notifications
|
|
1195
|
+
|
|
1196
|
+
user User @relation("Follower", fields: [userId], references: [id], onDelete: Cascade, map: "UserFollowing_follower_fkey")
|
|
1197
|
+
following User @relation("Following", fields: [followingId], references: [id], onDelete: Cascade)
|
|
1198
|
+
organizerUser User? @relation("FollowingOrganizers", fields: [userId], references: [id], onDelete: Cascade, map: "UserFollowing_organizer_fkey")
|
|
1199
|
+
|
|
1200
|
+
@@unique([userId, followingId])
|
|
1201
|
+
}
|
|
1202
|
+
|
|
1167
1203
|
model Contact {
|
|
1168
1204
|
id String @id @default(cuid())
|
|
1169
1205
|
contactOwnerId String
|
|
@@ -1393,6 +1429,9 @@ model Service {
|
|
|
1393
1429
|
displayGoogleReviewsOnDetailPage Boolean @default(true)
|
|
1394
1430
|
displayBashReviewsOnDetailPage Boolean @default(true)
|
|
1395
1431
|
|
|
1432
|
+
serviceRating Float? @default(0)
|
|
1433
|
+
totalRatings Int? @default(0)
|
|
1434
|
+
|
|
1396
1435
|
stripeAccountId String?
|
|
1397
1436
|
stripeAccount StripeAccount? @relation(fields: [stripeAccountId], references: [id], onDelete: Restrict)
|
|
1398
1437
|
|
|
@@ -1431,7 +1470,7 @@ model Service {
|
|
|
1431
1470
|
bashEvent BashEvent[] // because a service needs to be associated with a bash to post to the bashfeed
|
|
1432
1471
|
userPromoCodeRedemption UserPromoCodeRedemption[]
|
|
1433
1472
|
bookings ServiceBooking[]
|
|
1434
|
-
|
|
1473
|
+
notification Notification[]
|
|
1435
1474
|
}
|
|
1436
1475
|
|
|
1437
1476
|
model StripeAccount {
|
|
@@ -1573,6 +1612,7 @@ model Venue {
|
|
|
1573
1612
|
secondaryVenueTypes String[] @default([])
|
|
1574
1613
|
pitch String?
|
|
1575
1614
|
capacity Int?
|
|
1615
|
+
squareFootage Int?
|
|
1576
1616
|
anticipatedAttendees Int?
|
|
1577
1617
|
trademark Boolean?
|
|
1578
1618
|
manager Boolean?
|
|
@@ -2064,8 +2104,8 @@ model ServiceBooking {
|
|
|
2064
2104
|
isFreeGuest Boolean @default(false)
|
|
2065
2105
|
allowPromiseToPay Boolean @default(false)
|
|
2066
2106
|
|
|
2067
|
-
checkout
|
|
2068
|
-
|
|
2107
|
+
checkout ServiceBookingCheckout?
|
|
2108
|
+
notification Notification[]
|
|
2069
2109
|
|
|
2070
2110
|
additionalFees ServiceBookingFee[]
|
|
2071
2111
|
|
|
@@ -2230,6 +2270,7 @@ model UserStats {
|
|
|
2230
2270
|
totalEarnings Float @default(0)
|
|
2231
2271
|
servicesBookedCount Int @default(0)
|
|
2232
2272
|
followersCount Int @default(0)
|
|
2273
|
+
followingCount Int @default(0)
|
|
2233
2274
|
|
|
2234
2275
|
// Rankings
|
|
2235
2276
|
hostRank Int? // Rank based on number of events hosted
|
package/src/extendedSchemas.ts
CHANGED
|
@@ -5,7 +5,6 @@ import {
|
|
|
5
5
|
BashComment,
|
|
6
6
|
BashEvent,
|
|
7
7
|
BashEventPromoCode,
|
|
8
|
-
BashNotification,
|
|
9
8
|
Checkout,
|
|
10
9
|
Contact,
|
|
11
10
|
Coordinates,
|
|
@@ -17,6 +16,7 @@ import {
|
|
|
17
16
|
Invitation,
|
|
18
17
|
Link,
|
|
19
18
|
Media,
|
|
19
|
+
Notification,
|
|
20
20
|
Organization,
|
|
21
21
|
Prisma,
|
|
22
22
|
Recurrence,
|
|
@@ -63,6 +63,11 @@ import {
|
|
|
63
63
|
UnionFromArray
|
|
64
64
|
} from "./utils/typeUtils";
|
|
65
65
|
|
|
66
|
+
export interface ApiResponse<T> {
|
|
67
|
+
data: T;
|
|
68
|
+
error?: string;
|
|
69
|
+
}
|
|
70
|
+
|
|
66
71
|
//------------------------------------------------------user subscriptions------------------------------------------------------
|
|
67
72
|
export const PUBLIC_USER_SUBSCRIPTION_DATA_TO_SELECT = {
|
|
68
73
|
type: true,
|
|
@@ -93,6 +98,7 @@ export type UserSubscriptionExt = {
|
|
|
93
98
|
|
|
94
99
|
export const FRONT_END_USER_DATA_TO_SELECT = {
|
|
95
100
|
id: true,
|
|
101
|
+
username: true,
|
|
96
102
|
email: true,
|
|
97
103
|
givenName: true,
|
|
98
104
|
familyName: true,
|
|
@@ -630,7 +636,7 @@ export interface ServiceLinkExt extends ServiceLink {
|
|
|
630
636
|
|
|
631
637
|
//-----------------------------------------
|
|
632
638
|
|
|
633
|
-
export interface
|
|
639
|
+
export interface NotificationExt extends Notification {
|
|
634
640
|
bashEvent?: BashEvent;
|
|
635
641
|
creator?: PublicUser;
|
|
636
642
|
eventTask?: EventTask;
|
|
@@ -676,7 +682,7 @@ export const BASH_NOTIFICATION_DATA_TO_INCLUDE = {
|
|
|
676
682
|
serviceBooking: {
|
|
677
683
|
include: SERVICE_BOOKING_PUBLIC_DATA_TO_INCLUDE,
|
|
678
684
|
},
|
|
679
|
-
} satisfies Prisma.
|
|
685
|
+
} satisfies Prisma.NotificationInclude;
|
|
680
686
|
|
|
681
687
|
export interface EventTaskExt extends EventTask {
|
|
682
688
|
creator: PublicUser;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {IAddress} from "../definitions";
|
|
1
|
+
import { IAddress } from "../definitions";
|
|
2
2
|
|
|
3
3
|
const ADDRESS_DELIM = '|';
|
|
4
4
|
|
|
@@ -32,21 +32,50 @@ export function databaseAddressStringToAddressValues(addressString: string | und
|
|
|
32
32
|
|
|
33
33
|
export function databaseAddressStringToOneLineString(addressString: string | undefined | null): string {
|
|
34
34
|
if (addressString) {
|
|
35
|
+
// Special handling for place-only addresses
|
|
36
|
+
if (!addressString.includes(ADDRESS_DELIM)) {
|
|
37
|
+
return addressString.trim();
|
|
38
|
+
}
|
|
39
|
+
|
|
35
40
|
const address = databaseAddressStringToAddressValues(addressString);
|
|
41
|
+
|
|
42
|
+
// If only place exists, just return it
|
|
43
|
+
if (address.place &&
|
|
44
|
+
(!address.street || address.street === 'undefined') &&
|
|
45
|
+
(!address.city || address.city === 'undefined') &&
|
|
46
|
+
(!address.state || address.state === 'undefined')) {
|
|
47
|
+
return address.place.trim();
|
|
48
|
+
}
|
|
49
|
+
|
|
36
50
|
let addressArr = address.place ? [address.place] : [];
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
51
|
+
|
|
52
|
+
// Add non-empty and non-undefined parts
|
|
53
|
+
if (address.street && address.street !== 'undefined') addressArr.push(address.street);
|
|
54
|
+
if (address.city && address.city !== 'undefined') addressArr.push(address.city);
|
|
55
|
+
if (address.state && address.state !== 'undefined') addressArr.push(address.state);
|
|
56
|
+
|
|
57
|
+
const addressStr = addressArr.filter(str => !!str && str !== 'undefined').join(', ');
|
|
58
|
+
|
|
59
|
+
// Only add zip code if it exists and isn't 'undefined'
|
|
60
|
+
return address.zipCode && address.zipCode !== 'undefined'
|
|
61
|
+
? `${addressStr} ${address.zipCode}`
|
|
62
|
+
: addressStr;
|
|
40
63
|
}
|
|
41
64
|
return '';
|
|
42
65
|
}
|
|
43
66
|
|
|
44
67
|
export function databaseAddressStringToDisplayString(addressString: string | undefined | null): string {
|
|
45
68
|
if (addressString) {
|
|
69
|
+
// Special handling for place-only addresses (no delimiters)
|
|
70
|
+
if (!addressString.includes(ADDRESS_DELIM)) {
|
|
71
|
+
return addressString.trim();
|
|
72
|
+
}
|
|
73
|
+
|
|
46
74
|
const oneLineString = databaseAddressStringToOneLineString(addressString);
|
|
47
75
|
const formatted = oneLineString.replace(/([A-Z])(?=[A-Z][a-z])/g, "$1 ") // Add space between a single uppercase letter and a capitalized word
|
|
48
76
|
.replace(/(\d)(?=[A-Z])/g, "$1 ") // Add space between numbers and letters
|
|
49
|
-
.replace(/,/g, ", ")
|
|
77
|
+
.replace(/,/g, ", ") // Add space after commas
|
|
78
|
+
.replace(/undefined/g, ""); // Remove any "undefined" strings
|
|
50
79
|
return formatted;
|
|
51
80
|
}
|
|
52
81
|
return '';
|