Compare commits
24 Commits
Split-lamb
...
split-sche
| Author | SHA1 | Date | |
|---|---|---|---|
| 50f93bbeae | |||
| 3ce9d1d180 | |||
| cb819088a0 | |||
| 8f5f01c287 | |||
| e4a2a04045 | |||
| 50ce8e39c5 | |||
| 19e57f0e7f | |||
| ad5e343b66 | |||
| 8c3ece6ebd | |||
| 092f425bb3 | |||
| b1a3afd3a1 | |||
| 97f431260d | |||
| bf6d9ae00b | |||
| 518ec4eb21 | |||
| 95b061b400 | |||
| 92992797ab | |||
| c96e3b0c1a | |||
| f23b93801c | |||
| f1801a3210 | |||
| 2588ca4317 | |||
| e809ba4480 | |||
| 678be7c905 | |||
| 08b4231e5f | |||
| a3ab9db5a2 |
@@ -1728,8 +1728,8 @@ model ItineraryActivities {
|
|||||||
travelMode String? @map("travel_mode") @db.VarChar(30)
|
travelMode String? @map("travel_mode") @db.VarChar(30)
|
||||||
kmForNextPoint Float? @map("km_for_next_point")
|
kmForNextPoint Float? @map("km_for_next_point")
|
||||||
timeForNextPointMins Int? @map("time_for_next_point_mins")
|
timeForNextPointMins Int? @map("time_for_next_point_mins")
|
||||||
paxCount Int @map("pax_count")
|
paxCount Int? @map("pax_count")
|
||||||
totalAmount Int @map("total_amount")
|
totalAmount Int? @map("total_amount")
|
||||||
bookingStatus String @default("pending") @map("booking_status") @db.VarChar(30)
|
bookingStatus String @default("pending") @map("booking_status") @db.VarChar(30)
|
||||||
isActive Boolean @default(true) @map("is_active")
|
isActive Boolean @default(true) @map("is_active")
|
||||||
createdAt DateTime @default(now()) @map("created_at")
|
createdAt DateTime @default(now()) @map("created_at")
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
# Legacy monolith config. For new deployments use serverless.*.yml files.
|
# Legacy monolith config. For new deployments use serverless.*.yml files.
|
||||||
service: minglarDev
|
service: minglar
|
||||||
|
|
||||||
|
|
||||||
useDotenv: true
|
useDotenv: true
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ minglarRegistration:
|
|||||||
- ${file(./serverless/patterns/base.yml):pattern4}
|
- ${file(./serverless/patterns/base.yml):pattern4}
|
||||||
events:
|
events:
|
||||||
- httpApi:
|
- httpApi:
|
||||||
path: /minglaradmin/registration
|
path: /registration
|
||||||
method: post
|
method: post
|
||||||
|
|
||||||
minglarLoginForAdmin:
|
minglarLoginForAdmin:
|
||||||
@@ -28,7 +28,7 @@ minglarLoginForAdmin:
|
|||||||
- ${file(./serverless/patterns/base.yml):pattern4}
|
- ${file(./serverless/patterns/base.yml):pattern4}
|
||||||
events:
|
events:
|
||||||
- httpApi:
|
- httpApi:
|
||||||
path: /minglaradmin/login
|
path: /login
|
||||||
method: post
|
method: post
|
||||||
|
|
||||||
minglarCreatePassword:
|
minglarCreatePassword:
|
||||||
@@ -43,7 +43,7 @@ minglarCreatePassword:
|
|||||||
- ${file(./serverless/patterns/base.yml):pattern4}
|
- ${file(./serverless/patterns/base.yml):pattern4}
|
||||||
events:
|
events:
|
||||||
- httpApi:
|
- httpApi:
|
||||||
path: /minglaradmin/create-password
|
path: /create-password
|
||||||
method: post
|
method: post
|
||||||
|
|
||||||
updateMinglarProfile:
|
updateMinglarProfile:
|
||||||
@@ -60,7 +60,7 @@ updateMinglarProfile:
|
|||||||
- ${file(./serverless/patterns/base.yml):pattern4}
|
- ${file(./serverless/patterns/base.yml):pattern4}
|
||||||
events:
|
events:
|
||||||
- httpApi:
|
- httpApi:
|
||||||
path: /minglaradmin/update-profile
|
path: /update-profile
|
||||||
method: patch
|
method: patch
|
||||||
|
|
||||||
prepopulateRole:
|
prepopulateRole:
|
||||||
@@ -75,7 +75,7 @@ prepopulateRole:
|
|||||||
- ${file(./serverless/patterns/base.yml):pattern4}
|
- ${file(./serverless/patterns/base.yml):pattern4}
|
||||||
events:
|
events:
|
||||||
- httpApi:
|
- httpApi:
|
||||||
path: /minglaradmin/prepopulate-Roles
|
path: /prepopulate-Roles
|
||||||
method: get
|
method: get
|
||||||
|
|
||||||
getHostDetailsById:
|
getHostDetailsById:
|
||||||
@@ -90,7 +90,7 @@ getHostDetailsById:
|
|||||||
- ${file(./serverless/patterns/base.yml):pattern4}
|
- ${file(./serverless/patterns/base.yml):pattern4}
|
||||||
events:
|
events:
|
||||||
- httpApi:
|
- httpApi:
|
||||||
path: /minglaradmin/hosthub/hosts/get-host-details/{host_xid}
|
path: /hosthub/hosts/get-host-details/{host_xid}
|
||||||
method: get
|
method: get
|
||||||
|
|
||||||
inviteTeammate:
|
inviteTeammate:
|
||||||
@@ -105,7 +105,7 @@ inviteTeammate:
|
|||||||
- ${file(./serverless/patterns/base.yml):pattern4}
|
- ${file(./serverless/patterns/base.yml):pattern4}
|
||||||
events:
|
events:
|
||||||
- httpApi:
|
- httpApi:
|
||||||
path: /minglaradmin/settings/teammates/invite-teammate
|
path: /settings/teammates/invite-teammate
|
||||||
method: post
|
method: post
|
||||||
|
|
||||||
getAllHostApplication:
|
getAllHostApplication:
|
||||||
@@ -121,7 +121,7 @@ getAllHostApplication:
|
|||||||
- ${file(./serverless/patterns/base.yml):pattern4}
|
- ${file(./serverless/patterns/base.yml):pattern4}
|
||||||
events:
|
events:
|
||||||
- httpApi:
|
- httpApi:
|
||||||
path: /minglaradmin/hosthub/hosts/get-all-host-applications-am
|
path: /hosthub/hosts/get-all-host-applications-am
|
||||||
method: get
|
method: get
|
||||||
|
|
||||||
getAllHostActivityForAdmin:
|
getAllHostActivityForAdmin:
|
||||||
@@ -137,7 +137,7 @@ getAllHostActivityForAdmin:
|
|||||||
- ${file(./serverless/patterns/base.yml):pattern4}
|
- ${file(./serverless/patterns/base.yml):pattern4}
|
||||||
events:
|
events:
|
||||||
- httpApi:
|
- httpApi:
|
||||||
path: /minglaradmin/get-all-activity-of-host/{id}
|
path: /get-all-activity-of-host/{id}
|
||||||
method: get
|
method: get
|
||||||
|
|
||||||
getAllOnboardingHostApplications:
|
getAllOnboardingHostApplications:
|
||||||
@@ -153,7 +153,7 @@ getAllOnboardingHostApplications:
|
|||||||
- ${file(./serverless/patterns/base.yml):pattern4}
|
- ${file(./serverless/patterns/base.yml):pattern4}
|
||||||
events:
|
events:
|
||||||
- httpApi:
|
- httpApi:
|
||||||
path: /minglaradmin/hosthub/onboarding/get-all-host-applications-admin
|
path: /hosthub/onboarding/get-all-host-applications-admin
|
||||||
method: get
|
method: get
|
||||||
|
|
||||||
getAllOnboardingHostApplications_New:
|
getAllOnboardingHostApplications_New:
|
||||||
@@ -169,7 +169,7 @@ getAllOnboardingHostApplications_New:
|
|||||||
- ${file(./serverless/patterns/base.yml):pattern4}
|
- ${file(./serverless/patterns/base.yml):pattern4}
|
||||||
events:
|
events:
|
||||||
- httpApi:
|
- httpApi:
|
||||||
path: /minglaradmin/hosthub/onboarding/get-all-host-applications-admin-new
|
path: /hosthub/onboarding/get-all-host-applications-admin-new
|
||||||
method: get
|
method: get
|
||||||
|
|
||||||
getAllInvitationDetails:
|
getAllInvitationDetails:
|
||||||
@@ -184,7 +184,7 @@ getAllInvitationDetails:
|
|||||||
- ${file(./serverless/patterns/base.yml):pattern4}
|
- ${file(./serverless/patterns/base.yml):pattern4}
|
||||||
events:
|
events:
|
||||||
- httpApi:
|
- httpApi:
|
||||||
path: /minglaradmin/settings/teammates/get-all-invitation-details
|
path: /settings/teammates/get-all-invitation-details
|
||||||
method: get
|
method: get
|
||||||
|
|
||||||
addSuggestion:
|
addSuggestion:
|
||||||
@@ -200,7 +200,7 @@ addSuggestion:
|
|||||||
- ${file(./serverless/patterns/base.yml):pattern4}
|
- ${file(./serverless/patterns/base.yml):pattern4}
|
||||||
events:
|
events:
|
||||||
- httpApi:
|
- httpApi:
|
||||||
path: /minglaradmin/hosthub/hosts/add-suggestion
|
path: /hosthub/hosts/add-suggestion
|
||||||
method: post
|
method: post
|
||||||
|
|
||||||
getAllCoadminAndAMDetails:
|
getAllCoadminAndAMDetails:
|
||||||
@@ -215,7 +215,7 @@ getAllCoadminAndAMDetails:
|
|||||||
- ${file(./serverless/patterns/base.yml):pattern4}
|
- ${file(./serverless/patterns/base.yml):pattern4}
|
||||||
events:
|
events:
|
||||||
- httpApi:
|
- httpApi:
|
||||||
path: /minglaradmin/settings/teammates/get-all-coadmin-am
|
path: /settings/teammates/get-all-coadmin-am
|
||||||
method: get
|
method: get
|
||||||
|
|
||||||
getAllInvitedCoadminAndAMDetails:
|
getAllInvitedCoadminAndAMDetails:
|
||||||
@@ -230,7 +230,7 @@ getAllInvitedCoadminAndAMDetails:
|
|||||||
- ${file(./serverless/patterns/base.yml):pattern4}
|
- ${file(./serverless/patterns/base.yml):pattern4}
|
||||||
events:
|
events:
|
||||||
- httpApi:
|
- httpApi:
|
||||||
path: /minglaradmin/settings/teammates/get-all-invited-coadmin-am
|
path: /settings/teammates/get-all-invited-coadmin-am
|
||||||
method: get
|
method: get
|
||||||
|
|
||||||
getAmDetailsbyId:
|
getAmDetailsbyId:
|
||||||
@@ -245,7 +245,7 @@ getAmDetailsbyId:
|
|||||||
- ${file(./serverless/patterns/base.yml):pattern4}
|
- ${file(./serverless/patterns/base.yml):pattern4}
|
||||||
events:
|
events:
|
||||||
- httpApi:
|
- httpApi:
|
||||||
path: /minglaradmin/settings/teammates/get-am-details-by-id/{amXid}
|
path: /settings/teammates/get-am-details-by-id/{amXid}
|
||||||
method: get
|
method: get
|
||||||
|
|
||||||
assignAMToHost:
|
assignAMToHost:
|
||||||
@@ -261,7 +261,7 @@ assignAMToHost:
|
|||||||
- ${file(./serverless/patterns/base.yml):pattern4}
|
- ${file(./serverless/patterns/base.yml):pattern4}
|
||||||
events:
|
events:
|
||||||
- httpApi:
|
- httpApi:
|
||||||
path: /minglaradmin/hosthub/onboarding/assign-am
|
path: /hosthub/onboarding/assign-am
|
||||||
method: patch
|
method: patch
|
||||||
|
|
||||||
editAgreementDetailsAndAccept:
|
editAgreementDetailsAndAccept:
|
||||||
@@ -277,7 +277,7 @@ editAgreementDetailsAndAccept:
|
|||||||
- ${file(./serverless/patterns/base.yml):pattern4}
|
- ${file(./serverless/patterns/base.yml):pattern4}
|
||||||
events:
|
events:
|
||||||
- httpApi:
|
- httpApi:
|
||||||
path: /minglaradmin/hosthub/onboarding/edit-agreement-accept-host
|
path: /hosthub/onboarding/edit-agreement-accept-host
|
||||||
method: patch
|
method: patch
|
||||||
|
|
||||||
getAllPqqQuesAnsForAM:
|
getAllPqqQuesAnsForAM:
|
||||||
@@ -292,7 +292,7 @@ getAllPqqQuesAnsForAM:
|
|||||||
- ${file(./serverless/patterns/base.yml):pattern4}
|
- ${file(./serverless/patterns/base.yml):pattern4}
|
||||||
events:
|
events:
|
||||||
- httpApi:
|
- httpApi:
|
||||||
path: /minglaradmin/hosthub/onboarding/get-all-pqq-ques-ans-for-am
|
path: /hosthub/onboarding/get-all-pqq-ques-ans-for-am
|
||||||
method: get
|
method: get
|
||||||
|
|
||||||
acceptHostApplication:
|
acceptHostApplication:
|
||||||
@@ -308,7 +308,7 @@ acceptHostApplication:
|
|||||||
- ${file(./serverless/patterns/base.yml):pattern4}
|
- ${file(./serverless/patterns/base.yml):pattern4}
|
||||||
events:
|
events:
|
||||||
- httpApi:
|
- httpApi:
|
||||||
path: /minglaradmin/hosthub/hosts/accept-host-application
|
path: /hosthub/hosts/accept-host-application
|
||||||
method: patch
|
method: patch
|
||||||
|
|
||||||
RejectPQQByAM:
|
RejectPQQByAM:
|
||||||
@@ -324,7 +324,7 @@ RejectPQQByAM:
|
|||||||
- ${file(./serverless/patterns/base.yml):pattern4}
|
- ${file(./serverless/patterns/base.yml):pattern4}
|
||||||
events:
|
events:
|
||||||
- httpApi:
|
- httpApi:
|
||||||
path: /minglaradmin/hosthub/hosts/reject-pq-by-am
|
path: /hosthub/hosts/reject-pq-by-am
|
||||||
method: patch
|
method: patch
|
||||||
|
|
||||||
rejectActivityDetailsApplicationByAM:
|
rejectActivityDetailsApplicationByAM:
|
||||||
@@ -340,7 +340,7 @@ rejectActivityDetailsApplicationByAM:
|
|||||||
- ${file(./serverless/patterns/base.yml):pattern4}
|
- ${file(./serverless/patterns/base.yml):pattern4}
|
||||||
events:
|
events:
|
||||||
- httpApi:
|
- httpApi:
|
||||||
path: /minglaradmin/hosthub/hosts/reject-activity-application-by-am
|
path: /hosthub/hosts/reject-activity-application-by-am
|
||||||
method: patch
|
method: patch
|
||||||
|
|
||||||
acceptPQByAM:
|
acceptPQByAM:
|
||||||
@@ -356,7 +356,7 @@ acceptPQByAM:
|
|||||||
- ${file(./serverless/patterns/base.yml):pattern4}
|
- ${file(./serverless/patterns/base.yml):pattern4}
|
||||||
events:
|
events:
|
||||||
- httpApi:
|
- httpApi:
|
||||||
path: /minglaradmin/hosthub/hosts/accept-pq-by-am
|
path: /hosthub/hosts/accept-pq-by-am
|
||||||
method: patch
|
method: patch
|
||||||
|
|
||||||
acceptActivityDetailsApplicationByAM:
|
acceptActivityDetailsApplicationByAM:
|
||||||
@@ -372,7 +372,7 @@ acceptActivityDetailsApplicationByAM:
|
|||||||
- ${file(./serverless/patterns/base.yml):pattern4}
|
- ${file(./serverless/patterns/base.yml):pattern4}
|
||||||
events:
|
events:
|
||||||
- httpApi:
|
- httpApi:
|
||||||
path: /minglaradmin/hosthub/hosts/accept-activity-application-by-am
|
path: /hosthub/hosts/accept-activity-application-by-am
|
||||||
method: patch
|
method: patch
|
||||||
|
|
||||||
rejectHostApplication:
|
rejectHostApplication:
|
||||||
@@ -388,7 +388,7 @@ rejectHostApplication:
|
|||||||
- ${file(./serverless/patterns/base.yml):pattern4}
|
- ${file(./serverless/patterns/base.yml):pattern4}
|
||||||
events:
|
events:
|
||||||
- httpApi:
|
- httpApi:
|
||||||
path: /minglaradmin/hosthub/onboarding/reject-host-application
|
path: /hosthub/onboarding/reject-host-application
|
||||||
method: patch
|
method: patch
|
||||||
|
|
||||||
rejectHostApplicationAM:
|
rejectHostApplicationAM:
|
||||||
@@ -404,7 +404,7 @@ rejectHostApplicationAM:
|
|||||||
- ${file(./serverless/patterns/base.yml):pattern4}
|
- ${file(./serverless/patterns/base.yml):pattern4}
|
||||||
events:
|
events:
|
||||||
- httpApi:
|
- httpApi:
|
||||||
path: /minglaradmin/hosthub/hosts/reject-host-application-am
|
path: /hosthub/hosts/reject-host-application-am
|
||||||
method: patch
|
method: patch
|
||||||
|
|
||||||
addPQQSuggestion:
|
addPQQSuggestion:
|
||||||
@@ -420,7 +420,7 @@ addPQQSuggestion:
|
|||||||
- ${file(./serverless/patterns/base.yml):pattern4}
|
- ${file(./serverless/patterns/base.yml):pattern4}
|
||||||
events:
|
events:
|
||||||
- httpApi:
|
- httpApi:
|
||||||
path: /minglaradmin/hosthub/hosts/add-Pqq-suggestion
|
path: /hosthub/hosts/add-Pqq-suggestion
|
||||||
method: post
|
method: post
|
||||||
|
|
||||||
addActivitySuggestion:
|
addActivitySuggestion:
|
||||||
@@ -436,7 +436,7 @@ addActivitySuggestion:
|
|||||||
- ${file(./serverless/patterns/base.yml):pattern4}
|
- ${file(./serverless/patterns/base.yml):pattern4}
|
||||||
events:
|
events:
|
||||||
- httpApi:
|
- httpApi:
|
||||||
path: /minglaradmin/hosthub/hosts/add-Activity-suggestion
|
path: /hosthub/hosts/add-Activity-suggestion
|
||||||
method: post
|
method: post
|
||||||
|
|
||||||
getAllPQPDetailsForAM:
|
getAllPQPDetailsForAM:
|
||||||
@@ -452,7 +452,7 @@ getAllPQPDetailsForAM:
|
|||||||
- ${file(./serverless/patterns/base.yml):pattern4}
|
- ${file(./serverless/patterns/base.yml):pattern4}
|
||||||
events:
|
events:
|
||||||
- httpApi:
|
- httpApi:
|
||||||
path: /minglaradmin/hosthub/pqp/pqp-details-for-am/{activityXid}
|
path: /hosthub/pqp/pqp-details-for-am/{activityXid}
|
||||||
method: get
|
method: get
|
||||||
|
|
||||||
getSuggestionsForAM:
|
getSuggestionsForAM:
|
||||||
@@ -468,5 +468,5 @@ getSuggestionsForAM:
|
|||||||
- ${file(./serverless/patterns/base.yml):pattern4}
|
- ${file(./serverless/patterns/base.yml):pattern4}
|
||||||
events:
|
events:
|
||||||
- httpApi:
|
- httpApi:
|
||||||
path: /minglaradmin/hosthub/onboarding/show-suggestion-to-am/{hostXid}
|
path: /hosthub/onboarding/show-suggestion-to-am/{hostXid}
|
||||||
method: get
|
method: get
|
||||||
|
|||||||
@@ -288,6 +288,21 @@ getActivityFromConnectionsInterest:
|
|||||||
path: /connections/get-activity-from-connections-interest
|
path: /connections/get-activity-from-connections-interest
|
||||||
method: get
|
method: get
|
||||||
|
|
||||||
|
searchConnectionPeople:
|
||||||
|
handler: src/modules/user/handlers/connections/searchConnectionPeople.handler
|
||||||
|
memorySize: 384
|
||||||
|
package:
|
||||||
|
patterns:
|
||||||
|
- 'src/modules/user/handlers/connections/**'
|
||||||
|
- ${file(./serverless/patterns/base.yml):pattern1}
|
||||||
|
- ${file(./serverless/patterns/base.yml):pattern2}
|
||||||
|
- ${file(./serverless/patterns/base.yml):pattern3}
|
||||||
|
- ${file(./serverless/patterns/base.yml):pattern4}
|
||||||
|
events:
|
||||||
|
- httpApi:
|
||||||
|
path: /connections/search-connection-people
|
||||||
|
method: get
|
||||||
|
|
||||||
viewMoreActivitiesByInterest:
|
viewMoreActivitiesByInterest:
|
||||||
handler: src/modules/user/handlers/activities/viewMoreActivities.handler
|
handler: src/modules/user/handlers/activities/viewMoreActivities.handler
|
||||||
memorySize: 384
|
memorySize: 384
|
||||||
@@ -406,4 +421,64 @@ getAllBucketActivities:
|
|||||||
events:
|
events:
|
||||||
- httpApi:
|
- httpApi:
|
||||||
path: /activities/get-all-bucket-activities
|
path: /activities/get-all-bucket-activities
|
||||||
method: get
|
method: get
|
||||||
|
|
||||||
|
getUserItineraryDetails:
|
||||||
|
handler: src/modules/user/handlers/itinerary/getUserItineraryDetails.handler
|
||||||
|
memorySize: 512
|
||||||
|
package:
|
||||||
|
patterns:
|
||||||
|
- 'src/modules/user/**'
|
||||||
|
- ${file(./serverless/patterns/base.yml):pattern1}
|
||||||
|
- ${file(./serverless/patterns/base.yml):pattern2}
|
||||||
|
- ${file(./serverless/patterns/base.yml):pattern3}
|
||||||
|
- ${file(./serverless/patterns/base.yml):pattern4}
|
||||||
|
events:
|
||||||
|
- httpApi:
|
||||||
|
path: /itinerary/get-user-itinerary-details
|
||||||
|
method: get
|
||||||
|
|
||||||
|
saveUserItinerary:
|
||||||
|
handler: src/modules/user/handlers/itinerary/saveUserItinerary.handler
|
||||||
|
memorySize: 512
|
||||||
|
package:
|
||||||
|
patterns:
|
||||||
|
- 'src/modules/user/**'
|
||||||
|
- ${file(./serverless/patterns/base.yml):pattern1}
|
||||||
|
- ${file(./serverless/patterns/base.yml):pattern2}
|
||||||
|
- ${file(./serverless/patterns/base.yml):pattern3}
|
||||||
|
- ${file(./serverless/patterns/base.yml):pattern4}
|
||||||
|
events:
|
||||||
|
- httpApi:
|
||||||
|
path: /itinerary/save-user-itinerary
|
||||||
|
method: post
|
||||||
|
|
||||||
|
getAllUserSavedItineraries:
|
||||||
|
handler: src/modules/user/handlers/itinerary/getAllUserSavedItineraries.handler
|
||||||
|
memorySize: 512
|
||||||
|
package:
|
||||||
|
patterns:
|
||||||
|
- 'src/modules/user/**'
|
||||||
|
- ${file(./serverless/patterns/base.yml):pattern1}
|
||||||
|
- ${file(./serverless/patterns/base.yml):pattern2}
|
||||||
|
- ${file(./serverless/patterns/base.yml):pattern3}
|
||||||
|
- ${file(./serverless/patterns/base.yml):pattern4}
|
||||||
|
events:
|
||||||
|
- httpApi:
|
||||||
|
path: /itinerary/get-all-user-saved-itineraries
|
||||||
|
method: get
|
||||||
|
|
||||||
|
getMatchingBucketInterestedActivities:
|
||||||
|
handler: src/modules/user/handlers/itinerary/getMatchingBucketInterestedActivities.handler
|
||||||
|
memorySize: 512
|
||||||
|
package:
|
||||||
|
patterns:
|
||||||
|
- 'src/modules/user/**'
|
||||||
|
- ${file(./serverless/patterns/base.yml):pattern1}
|
||||||
|
- ${file(./serverless/patterns/base.yml):pattern2}
|
||||||
|
- ${file(./serverless/patterns/base.yml):pattern3}
|
||||||
|
- ${file(./serverless/patterns/base.yml):pattern4}
|
||||||
|
events:
|
||||||
|
- httpApi:
|
||||||
|
path: /itinerary/get-matching-bucket-interested-activities
|
||||||
|
method: post
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ export const ACTIVITY_DISPLAY_STATUS = {
|
|||||||
PQ_IN_REVIEW: 'PQ In Review',
|
PQ_IN_REVIEW: 'PQ In Review',
|
||||||
PQ_APPROVED: 'PQ Approved',
|
PQ_APPROVED: 'PQ Approved',
|
||||||
|
|
||||||
ACTIVITY_DRAFT: 'Draft - Activity',
|
ACTIVITY_DRAFT: 'Draft',
|
||||||
ACTIVITY_IN_REVIEW: 'In Review',
|
ACTIVITY_IN_REVIEW: 'In Review',
|
||||||
ACTIVITY_TO_REVIEW: 'Re-submitted',
|
ACTIVITY_TO_REVIEW: 'Re-submitted',
|
||||||
NOT_LISTED: 'Not Listed',
|
NOT_LISTED: 'Not Listed',
|
||||||
@@ -94,7 +94,7 @@ export const ACTIVITY_AM_DISPLAY_STATUS = {
|
|||||||
PQ_APPROVED: 'PQ Approved',
|
PQ_APPROVED: 'PQ Approved',
|
||||||
REVISED: 'Revised',
|
REVISED: 'Revised',
|
||||||
|
|
||||||
ACTIVITY_DRAFT: 'Draft - Activity',
|
ACTIVITY_DRAFT: 'Draft',
|
||||||
ACTIVITY_NEW: 'New',
|
ACTIVITY_NEW: 'New',
|
||||||
ACTIVITY_TO_REVIEW: 'Activity To Review',
|
ACTIVITY_TO_REVIEW: 'Activity To Review',
|
||||||
ACTIVITY_ENHANCING: 'Enhancing',
|
ACTIVITY_ENHANCING: 'Enhancing',
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import { verifyHostToken } from '../../../../../common/middlewares/jwt/authForHo
|
|||||||
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
import { safeHandler } from '../../../../../common/utils/handlers/safeHandler';
|
||||||
import ApiError from '../../../../../common/utils/helper/ApiError';
|
import ApiError from '../../../../../common/utils/helper/ApiError';
|
||||||
import { HostService } from '../../../services/host.service';
|
import { HostService } from '../../../services/host.service';
|
||||||
|
import { sendPQPEmailToAM } from '../../../services/sendHostResubmitEmailToAM.service';
|
||||||
|
|
||||||
const hostService = new HostService(prismaClient);
|
const hostService = new HostService(prismaClient);
|
||||||
|
|
||||||
@@ -177,6 +178,15 @@ export const handler = safeHandler(async (event: APIGatewayProxyEvent): Promise<
|
|||||||
|
|
||||||
const getAllUpdatedQuestionResponse = await hostService.getAllPQUpdatedResponse(activityXid)
|
const getAllUpdatedQuestionResponse = await hostService.getAllPQUpdatedResponse(activityXid)
|
||||||
|
|
||||||
|
const details = await hostService.getSuggestionDetails(user.id);
|
||||||
|
|
||||||
|
await sendPQPEmailToAM(
|
||||||
|
details.hostDetails.accountManager.emailAddress,
|
||||||
|
details.hostDetails.accountManager.firstName,
|
||||||
|
details.hostDetails.companyName,
|
||||||
|
details.hostDetails.user.userRefNumber,
|
||||||
|
)
|
||||||
|
|
||||||
// CASE 2 — NO deletion & NO new files => DO NOTHING to existing files
|
// CASE 2 — NO deletion & NO new files => DO NOTHING to existing files
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -13,6 +13,40 @@ const hostService = new HostService(prismaClient);
|
|||||||
|
|
||||||
const s3 = new AWS.S3({ region: config.aws.region });
|
const s3 = new AWS.S3({ region: config.aws.region });
|
||||||
|
|
||||||
|
function parseMultipartFieldValue(val: string) {
|
||||||
|
if (val === '' || val === 'null' || val === 'undefined') return null;
|
||||||
|
|
||||||
|
const cleaned = val.trim();
|
||||||
|
const looksLikeJson =
|
||||||
|
(cleaned.startsWith('{') && cleaned.endsWith('}')) ||
|
||||||
|
(cleaned.startsWith('[') && cleaned.endsWith(']')) ||
|
||||||
|
(cleaned.startsWith('"') && cleaned.endsWith('"'));
|
||||||
|
|
||||||
|
if (!looksLikeJson) return val;
|
||||||
|
|
||||||
|
try {
|
||||||
|
return JSON.parse(cleaned);
|
||||||
|
} catch {
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function normalizeComments(comments: unknown): string | null {
|
||||||
|
if (comments === null || comments === undefined || comments === '') return null;
|
||||||
|
|
||||||
|
const value = String(comments).trim();
|
||||||
|
if (!value) return null;
|
||||||
|
|
||||||
|
if (
|
||||||
|
(value.startsWith('"') && value.endsWith('"')) ||
|
||||||
|
(value.startsWith("'") && value.endsWith("'"))
|
||||||
|
) {
|
||||||
|
return value.slice(1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
// Function to extract S3 key from URL
|
// Function to extract S3 key from URL
|
||||||
function getS3KeyFromUrl(url: string): string {
|
function getS3KeyFromUrl(url: string): string {
|
||||||
const bucketBaseUrl = `https://${config.aws.bucketName}.s3.${config.aws.region}.amazonaws.com/`;
|
const bucketBaseUrl = `https://${config.aws.bucketName}.s3.${config.aws.region}.amazonaws.com/`;
|
||||||
@@ -122,22 +156,7 @@ export const handler = safeHandler(async (event: APIGatewayProxyEvent): Promise<
|
|||||||
|
|
||||||
bb.on("field", (fieldname, val) => {
|
bb.on("field", (fieldname, val) => {
|
||||||
console.log(`FIELD RAW: ${fieldname} =`, val);
|
console.log(`FIELD RAW: ${fieldname} =`, val);
|
||||||
if (val === '' || val === 'null' || val === 'undefined') fields[fieldname] = null;
|
fields[fieldname] = parseMultipartFieldValue(val);
|
||||||
else {
|
|
||||||
try {
|
|
||||||
const cleaned = val.trim();
|
|
||||||
|
|
||||||
// If it starts and ends with quotes, remove them
|
|
||||||
const withoutQuotes =
|
|
||||||
(cleaned.startsWith('"') && cleaned.endsWith('"'))
|
|
||||||
? cleaned.slice(1, -1)
|
|
||||||
: cleaned;
|
|
||||||
|
|
||||||
fields[fieldname] = JSON.parse(withoutQuotes);
|
|
||||||
} catch {
|
|
||||||
fields[fieldname] = val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
bb.on("close", () => resolve());
|
bb.on("close", () => resolve());
|
||||||
@@ -154,7 +173,7 @@ export const handler = safeHandler(async (event: APIGatewayProxyEvent): Promise<
|
|||||||
const activityXid = Number(fields.activityXid);
|
const activityXid = Number(fields.activityXid);
|
||||||
const pqqQuestionXid = Number(fields.pqqQuestionXid);
|
const pqqQuestionXid = Number(fields.pqqQuestionXid);
|
||||||
const pqqAnswerXid = Number(fields.pqqAnswerXid);
|
const pqqAnswerXid = Number(fields.pqqAnswerXid);
|
||||||
const comments = fields.comments || null;
|
const comments = normalizeComments(fields.comments);
|
||||||
|
|
||||||
if (!activityXid || isNaN(activityXid)) throw new ApiError(400, "Please provide a valid activity");
|
if (!activityXid || isNaN(activityXid)) throw new ApiError(400, "Please provide a valid activity");
|
||||||
if (!pqqQuestionXid || isNaN(pqqQuestionXid)) throw new ApiError(400, "Please select a valid question");
|
if (!pqqQuestionXid || isNaN(pqqQuestionXid)) throw new ApiError(400, "Please select a valid question");
|
||||||
|
|||||||
@@ -142,6 +142,10 @@ export const handler = safeHandler(async (event: APIGatewayProxyEvent): Promise<
|
|||||||
|
|
||||||
const deletedFiles = normalizeJsonField(fields, "deletedFiles") || [];
|
const deletedFiles = normalizeJsonField(fields, "deletedFiles") || [];
|
||||||
const parentDeletedFiles = normalizeJsonField(fields, "parentDeletedFiles") || [];
|
const parentDeletedFiles = normalizeJsonField(fields, "parentDeletedFiles") || [];
|
||||||
|
const deleteCompanyLogo =
|
||||||
|
fields.deleteCompanyLogo === 'true' || fields.deleteCompanyLogo === true;
|
||||||
|
const deleteParentCompanyLogo =
|
||||||
|
fields.deleteParentCompanyLogo === 'true' || fields.deleteParentCompanyLogo === true;
|
||||||
|
|
||||||
/** 4) Extract and clean isDraft flag */
|
/** 4) Extract and clean isDraft flag */
|
||||||
const isDraft = fields.isDraft === 'true' || fields.isDraft === true;
|
const isDraft = fields.isDraft === 'true' || fields.isDraft === true;
|
||||||
@@ -379,6 +383,63 @@ export const handler = safeHandler(async (event: APIGatewayProxyEvent): Promise<
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** DELETE EXISTING LOGO IF REQUESTED */
|
||||||
|
if (deleteCompanyLogo) {
|
||||||
|
const existingHost = await prismaClient.hostHeader.findFirst({
|
||||||
|
where: { userXid: userInfo.id },
|
||||||
|
select: { logoPath: true },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (existingHost?.logoPath) {
|
||||||
|
try {
|
||||||
|
const s3Key = getS3KeyFromUrl(existingHost.logoPath);
|
||||||
|
await deleteFromS3(s3Key);
|
||||||
|
} catch (e) {
|
||||||
|
console.error('S3 delete failed for company logo:', existingHost.logoPath, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
parsedCompany.logoPath = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** DELETE EXISTING PARENT COMPANY LOGO IF REQUESTED */
|
||||||
|
if (deleteParentCompanyLogo && parsedCompany.isSubsidairy) {
|
||||||
|
const existingHost = await prismaClient.hostHeader.findFirst({
|
||||||
|
where: { userXid: userInfo.id },
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
hostParent: {
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
logoPath: true,
|
||||||
|
},
|
||||||
|
take: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const existingParent = Array.isArray(existingHost?.hostParent)
|
||||||
|
? existingHost.hostParent[0]
|
||||||
|
: existingHost?.hostParent;
|
||||||
|
|
||||||
|
if (existingParent?.logoPath) {
|
||||||
|
try {
|
||||||
|
const s3Key = getS3KeyFromUrl(existingParent.logoPath);
|
||||||
|
await deleteFromS3(s3Key);
|
||||||
|
} catch (e) {
|
||||||
|
console.error('S3 delete failed for parent company logo:', existingParent.logoPath, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parsedParentCompany) {
|
||||||
|
parsedParentCompany.logoPath = null;
|
||||||
|
} else {
|
||||||
|
parsedParentCompany = {
|
||||||
|
logoPath: null,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** UPLOAD LOGO (if provided) */
|
/** UPLOAD LOGO (if provided) */
|
||||||
const logoFile = files.find(
|
const logoFile = files.find(
|
||||||
(f) => f.fieldName === 'companyLogo' || f.fieldName === 'companyLogoFile'
|
(f) => f.fieldName === 'companyLogo' || f.fieldName === 'companyLogoFile'
|
||||||
@@ -449,6 +510,7 @@ export const handler = safeHandler(async (event: APIGatewayProxyEvent): Promise<
|
|||||||
parsedParentCompany,
|
parsedParentCompany,
|
||||||
uploadedParentDocs,
|
uploadedParentDocs,
|
||||||
isDraft,
|
isDraft,
|
||||||
|
{ deleteCompanyLogo, deleteParentCompanyLogo },
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!createdOrUpdated) throw new ApiError(400, 'Failed to add/update company details.');
|
if (!createdOrUpdated) throw new ApiError(400, 'Failed to add/update company details.');
|
||||||
|
|||||||
@@ -446,7 +446,46 @@ export class HostService {
|
|||||||
where: { userXid: id },
|
where: { userXid: id },
|
||||||
include: {
|
include: {
|
||||||
hostParent: {
|
hostParent: {
|
||||||
include: {
|
select: {
|
||||||
|
id: true,
|
||||||
|
logoPath: true,
|
||||||
|
companyName: true,
|
||||||
|
address1: true,
|
||||||
|
address2: true,
|
||||||
|
cities: {
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
cityName: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
states: {
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
stateName: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
countries: {
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
countryName: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
pinCode: true,
|
||||||
|
registrationNumber: true,
|
||||||
|
panNumber: true,
|
||||||
|
gstNumber: true,
|
||||||
|
formationDate: true,
|
||||||
|
companyTypes: {
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
companyTypeName: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
websiteUrl: true,
|
||||||
|
instagramUrl: true,
|
||||||
|
facebookUrl: true,
|
||||||
|
linkedinUrl: true,
|
||||||
|
twitterUrl: true,
|
||||||
HostParenetDocuments: {
|
HostParenetDocuments: {
|
||||||
select: {
|
select: {
|
||||||
id: true,
|
id: true,
|
||||||
@@ -479,6 +518,7 @@ export class HostService {
|
|||||||
select: {
|
select: {
|
||||||
id: true,
|
id: true,
|
||||||
emailAddress: true,
|
emailAddress: true,
|
||||||
|
dateOfBirth: true,
|
||||||
firstName: true,
|
firstName: true,
|
||||||
lastName: true,
|
lastName: true,
|
||||||
mobileNumber: true,
|
mobileNumber: true,
|
||||||
@@ -1351,6 +1391,10 @@ export class HostService {
|
|||||||
parentCompanyData?: any | null,
|
parentCompanyData?: any | null,
|
||||||
parentDocuments?: HostDocumentInput[],
|
parentDocuments?: HostDocumentInput[],
|
||||||
isDraft: boolean = false,
|
isDraft: boolean = false,
|
||||||
|
options?: {
|
||||||
|
deleteCompanyLogo?: boolean;
|
||||||
|
deleteParentCompanyLogo?: boolean;
|
||||||
|
},
|
||||||
) {
|
) {
|
||||||
return await this.prisma.$transaction(async (tx) => {
|
return await this.prisma.$transaction(async (tx) => {
|
||||||
// Check if host already has a company
|
// Check if host already has a company
|
||||||
@@ -1395,7 +1439,7 @@ export class HostService {
|
|||||||
hostStatusDisplay = HOST_STATUS_DISPLAY.UNDER_REVIEW;
|
hostStatusDisplay = HOST_STATUS_DISPLAY.UNDER_REVIEW;
|
||||||
|
|
||||||
minglarStatusInternal = MINGLAR_STATUS_INTERNAL.AM_TO_REVIEW;
|
minglarStatusInternal = MINGLAR_STATUS_INTERNAL.AM_TO_REVIEW;
|
||||||
minglarStatusDisplay = MINGLAR_STATUS_DISPLAY.TO_REVIEW;
|
minglarStatusDisplay = MINGLAR_STATUS_DISPLAY.RE_SUBMITTED;
|
||||||
}
|
}
|
||||||
// CASE 2: Admin has rejected but host can resubmit
|
// CASE 2: Admin has rejected but host can resubmit
|
||||||
else if (
|
else if (
|
||||||
@@ -1611,7 +1655,9 @@ export class HostService {
|
|||||||
? { connect: { id: Number(companyData.countryXid) } }
|
? { connect: { id: Number(companyData.countryXid) } }
|
||||||
: undefined,
|
: undefined,
|
||||||
pinCode: companyData.pinCode,
|
pinCode: companyData.pinCode,
|
||||||
logoPath: companyData.logoPath || existingHostCompany.logoPath,
|
logoPath: options?.deleteCompanyLogo
|
||||||
|
? companyData.logoPath ?? null
|
||||||
|
: companyData.logoPath || existingHostCompany.logoPath,
|
||||||
isSubsidairy: companyData.isSubsidairy,
|
isSubsidairy: companyData.isSubsidairy,
|
||||||
registrationNumber: companyData.registrationNumber,
|
registrationNumber: companyData.registrationNumber,
|
||||||
panNumber: companyData.panNumber,
|
panNumber: companyData.panNumber,
|
||||||
@@ -1752,10 +1798,11 @@ export class HostService {
|
|||||||
? { connect: { id: Number(parentCompanyData.countryXid) } }
|
? { connect: { id: Number(parentCompanyData.countryXid) } }
|
||||||
: undefined,
|
: undefined,
|
||||||
pinCode: parentCompanyData.pinCode || null,
|
pinCode: parentCompanyData.pinCode || null,
|
||||||
logoPath:
|
logoPath: options?.deleteParentCompanyLogo
|
||||||
parentCompanyData?.logoPath ||
|
? parentCompanyData?.logoPath ?? null
|
||||||
existingParentCompany?.logoPath ||
|
: parentCompanyData?.logoPath ||
|
||||||
null,
|
existingParentCompany?.logoPath ||
|
||||||
|
null,
|
||||||
registrationNumber: parentCompanyData.registrationNumber || null,
|
registrationNumber: parentCompanyData.registrationNumber || null,
|
||||||
panNumber: parentCompanyData.panNumber || null,
|
panNumber: parentCompanyData.panNumber || null,
|
||||||
gstNumber: parentCompanyData.gstNumber || null,
|
gstNumber: parentCompanyData.gstNumber || null,
|
||||||
@@ -1810,10 +1857,11 @@ export class HostService {
|
|||||||
? { connect: { id: Number(parentCompanyData.countryXid) } }
|
? { connect: { id: Number(parentCompanyData.countryXid) } }
|
||||||
: undefined,
|
: undefined,
|
||||||
pinCode: parentCompanyData.pinCode || null,
|
pinCode: parentCompanyData.pinCode || null,
|
||||||
logoPath:
|
logoPath: options?.deleteParentCompanyLogo
|
||||||
parentCompanyData?.logoPath ||
|
? parentCompanyData?.logoPath ?? null
|
||||||
existingParentCompany?.logoPath ||
|
: parentCompanyData?.logoPath ||
|
||||||
null,
|
existingParentCompany?.logoPath ||
|
||||||
|
null,
|
||||||
registrationNumber: parentCompanyData.registrationNumber || null,
|
registrationNumber: parentCompanyData.registrationNumber || null,
|
||||||
panNumber: parentCompanyData.panNumber || null,
|
panNumber: parentCompanyData.panNumber || null,
|
||||||
gstNumber: parentCompanyData.gstNumber || null,
|
gstNumber: parentCompanyData.gstNumber || null,
|
||||||
@@ -3337,6 +3385,34 @@ export class HostService {
|
|||||||
throw new ApiError(404, 'Activity not found');
|
throw new ApiError(404, 'Activity not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const normalizedActivityTitle =
|
||||||
|
typeof payload.activityTitle === 'string'
|
||||||
|
? payload.activityTitle.trim()
|
||||||
|
: '';
|
||||||
|
|
||||||
|
if (normalizedActivityTitle) {
|
||||||
|
payload.activityTitle = normalizedActivityTitle;
|
||||||
|
|
||||||
|
const duplicateActivity = await tx.activities.findFirst({
|
||||||
|
where: {
|
||||||
|
id: { not: existingActivity.id },
|
||||||
|
isActive: true,
|
||||||
|
activityTitle: {
|
||||||
|
equals: normalizedActivityTitle,
|
||||||
|
mode: 'insensitive',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
select: { id: true },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (duplicateActivity) {
|
||||||
|
throw new ApiError(
|
||||||
|
400,
|
||||||
|
'Same activity name already exists. Please choose a different name.',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* --------------------------------
|
/* --------------------------------
|
||||||
* 3️⃣ STATUS DECISION
|
* 3️⃣ STATUS DECISION
|
||||||
* -------------------------------- */
|
* -------------------------------- */
|
||||||
|
|||||||
@@ -76,3 +76,41 @@ export async function sendEmailToMinglarAdmin(
|
|||||||
throw new ApiError(500, "Failed to send OTP to host via email.");
|
throw new ApiError(500, "Failed to send OTP to host via email.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function sendPQPEmailToAM(
|
||||||
|
emailAddress: string,
|
||||||
|
minglarAdminName: string,
|
||||||
|
hostCompanyName: string,
|
||||||
|
hostRefNumber: string
|
||||||
|
): Promise<{
|
||||||
|
sent: boolean;
|
||||||
|
// messageId: string
|
||||||
|
}> {
|
||||||
|
|
||||||
|
const subject = `New Pre-qualification Questionnaire from : ${hostCompanyName}`;
|
||||||
|
|
||||||
|
const htmlContent = `
|
||||||
|
<p>Dear ${minglarAdminName},</p>
|
||||||
|
<p>Host ${hostCompanyName} with reference number: <strong>${hostRefNumber}</strong> has submited their pre-qualification questionnaire.</p>
|
||||||
|
<p>Please review their appliaction and take the necessary action.</p>
|
||||||
|
<p>Best regards,<br/>Minglar Team</p>
|
||||||
|
`;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const result = await brevoService.sendEmail({
|
||||||
|
recipients: [{ email: emailAddress }],
|
||||||
|
subject,
|
||||||
|
htmlContent,
|
||||||
|
});
|
||||||
|
|
||||||
|
// console.log("📧 Email sent successfully:", result);
|
||||||
|
|
||||||
|
return {
|
||||||
|
sent: true,
|
||||||
|
// messageId: result.messageId
|
||||||
|
};
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Brevo email send failed:", err);
|
||||||
|
throw new ApiError(500, "Failed to send OTP to host via email.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ const bucket = config.aws.bucketName;
|
|||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class MinglarService {
|
export class MinglarService {
|
||||||
constructor(private prisma: PrismaService | PrismaClient) {}
|
constructor(private prisma: PrismaService | PrismaClient) { }
|
||||||
|
|
||||||
async createPassword(user_xid: number, password: string): Promise<boolean> {
|
async createPassword(user_xid: number, password: string): Promise<boolean> {
|
||||||
// Find user by id
|
// Find user by id
|
||||||
@@ -314,6 +314,8 @@ export class MinglarService {
|
|||||||
companyName: true,
|
companyName: true,
|
||||||
user: {
|
user: {
|
||||||
select: {
|
select: {
|
||||||
|
firstName: true,
|
||||||
|
lastName: true,
|
||||||
userRefNumber: true,
|
userRefNumber: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -375,11 +377,52 @@ export class MinglarService {
|
|||||||
const {
|
const {
|
||||||
paginationService,
|
paginationService,
|
||||||
} = require('@/common/utils/pagination/pagination.service');
|
} = require('@/common/utils/pagination/pagination.service');
|
||||||
return paginationService.createPaginatedResponse(
|
|
||||||
|
let hostDetails = null;
|
||||||
|
|
||||||
|
if (hostXid) {
|
||||||
|
hostDetails = await this.prisma.hostHeader.findUnique({
|
||||||
|
where: { id: hostXid },
|
||||||
|
select: {
|
||||||
|
companyName: true,
|
||||||
|
user: {
|
||||||
|
select: {
|
||||||
|
firstName: true,
|
||||||
|
lastName: true,
|
||||||
|
userRefNumber: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const paginatedResponse = paginationService.createPaginatedResponse(
|
||||||
hostActivities,
|
hostActivities,
|
||||||
totalCount,
|
totalCount,
|
||||||
paginationOptions || { page: 1, limit: 10, skip: 0 },
|
paginationOptions || { page: 1, limit: 10, skip: 0 },
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// 👇 ADD THIS BLOCK
|
||||||
|
if (hostActivities.length === 0 && hostDetails) {
|
||||||
|
paginatedResponse.data = [
|
||||||
|
{
|
||||||
|
id: null,
|
||||||
|
activityRefNumber: null,
|
||||||
|
activityTitle: null,
|
||||||
|
totalScore: null,
|
||||||
|
activityInternalStatus: null,
|
||||||
|
activityDisplayStatus: null,
|
||||||
|
amInternalStatus: null,
|
||||||
|
amDisplayStatus: null,
|
||||||
|
createdAt: null,
|
||||||
|
host: hostDetails,
|
||||||
|
ActivityAmDetails: [],
|
||||||
|
activityType: null,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return paginatedResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
async createUserRevenue(
|
async createUserRevenue(
|
||||||
@@ -818,7 +861,7 @@ export class MinglarService {
|
|||||||
if (
|
if (
|
||||||
userStatus &&
|
userStatus &&
|
||||||
userStatus.trim().toLowerCase() ===
|
userStatus.trim().toLowerCase() ===
|
||||||
MINGLAR_STATUS_DISPLAY.NEW.toLowerCase()
|
MINGLAR_STATUS_DISPLAY.NEW.toLowerCase()
|
||||||
) {
|
) {
|
||||||
filters.adminStatusInternal = MINGLAR_STATUS_INTERNAL.ADMIN_TO_REVIEW;
|
filters.adminStatusInternal = MINGLAR_STATUS_INTERNAL.ADMIN_TO_REVIEW;
|
||||||
}
|
}
|
||||||
@@ -832,9 +875,9 @@ export class MinglarService {
|
|||||||
internal: MINGLAR_STATUS_INTERNAL.AM_TO_REVIEW,
|
internal: MINGLAR_STATUS_INTERNAL.AM_TO_REVIEW,
|
||||||
display: MINGLAR_STATUS_DISPLAY.NEW,
|
display: MINGLAR_STATUS_DISPLAY.NEW,
|
||||||
},
|
},
|
||||||
To_Review: {
|
Re_Submitted: {
|
||||||
internal: MINGLAR_STATUS_INTERNAL.AM_TO_REVIEW,
|
internal: MINGLAR_STATUS_INTERNAL.AM_TO_REVIEW,
|
||||||
display: MINGLAR_STATUS_DISPLAY.TO_REVIEW,
|
display: MINGLAR_STATUS_DISPLAY.RE_SUBMITTED,
|
||||||
},
|
},
|
||||||
Enhancing: {
|
Enhancing: {
|
||||||
internal: MINGLAR_STATUS_INTERNAL.AM_REJECTED,
|
internal: MINGLAR_STATUS_INTERNAL.AM_REJECTED,
|
||||||
@@ -945,6 +988,7 @@ export class MinglarService {
|
|||||||
const where: any = {
|
const where: any = {
|
||||||
isActive: true,
|
isActive: true,
|
||||||
hostStatusInternal: { notIn: [HOST_STATUS_INTERNAL.DRAFT] },
|
hostStatusInternal: { notIn: [HOST_STATUS_INTERNAL.DRAFT] },
|
||||||
|
adminStatusInternal: { notIn: [MINGLAR_STATUS_INTERNAL.AM_TO_REVIEW] },
|
||||||
};
|
};
|
||||||
|
|
||||||
if (search?.trim()) {
|
if (search?.trim()) {
|
||||||
@@ -1187,15 +1231,15 @@ export class MinglarService {
|
|||||||
// Build search filter if search term is provided
|
// Build search filter if search term is provided
|
||||||
const searchFilter = search
|
const searchFilter = search
|
||||||
? {
|
? {
|
||||||
OR: [
|
OR: [
|
||||||
{ email: { contains: search, mode: 'insensitive' as const } },
|
{ email: { contains: search, mode: 'insensitive' as const } },
|
||||||
{ firstName: { contains: search, mode: 'insensitive' as const } },
|
{ firstName: { contains: search, mode: 'insensitive' as const } },
|
||||||
{ lastName: { contains: search, mode: 'insensitive' as const } },
|
{ lastName: { contains: search, mode: 'insensitive' as const } },
|
||||||
{
|
{
|
||||||
userRefNumber: { contains: search, mode: 'insensitive' as const },
|
userRefNumber: { contains: search, mode: 'insensitive' as const },
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
: {};
|
: {};
|
||||||
|
|
||||||
// 1. Fetch all required users (Admin, Co-Admin, AM)
|
// 1. Fetch all required users (Admin, Co-Admin, AM)
|
||||||
@@ -1711,6 +1755,7 @@ export class MinglarService {
|
|||||||
isEmailVerfied: true,
|
isEmailVerfied: true,
|
||||||
isMobileVerfied: true,
|
isMobileVerfied: true,
|
||||||
isBiometric: true,
|
isBiometric: true,
|
||||||
|
createdAt: true,
|
||||||
userAddressDetails: {
|
userAddressDetails: {
|
||||||
select: {
|
select: {
|
||||||
id: true,
|
id: true,
|
||||||
@@ -1826,8 +1871,8 @@ export class MinglarService {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async rejectActivityApplicationByAM(activityId: number, user_xid: number) {
|
async rejectActivityApplicationByAM(activityId: number, user_xid: number) {
|
||||||
return await this.prisma.$transaction(async (tx) => {
|
return await this.prisma.$transaction(async (tx) => {
|
||||||
await tx.activities.update({
|
await tx.activities.update({
|
||||||
|
|||||||
@@ -140,7 +140,9 @@ export class PrePopulateService {
|
|||||||
}),
|
}),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return { documentDetails, countryDetails, stateDetails, companyTypeDetails };
|
const adminEmail = config.MinglarAdminEmail;
|
||||||
|
|
||||||
|
return { documentDetails, countryDetails, stateDetails, companyTypeDetails, adminEmail };
|
||||||
}
|
}
|
||||||
|
|
||||||
async getAllFrequencies() {
|
async getAllFrequencies() {
|
||||||
|
|||||||
@@ -86,9 +86,10 @@ export const handler = safeHandler(
|
|||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
success: true,
|
success: true,
|
||||||
message: 'Access token generated successfully',
|
message: 'Access token generated successfully',
|
||||||
|
data: {
|
||||||
accessToken: newAccessToken.access.token,
|
accessToken: newAccessToken.access.token,
|
||||||
accessTokenExpires: newAccessToken.access.expires,
|
accessTokenExpires: newAccessToken.access.expires,
|
||||||
data: null,
|
},
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -30,16 +30,17 @@ export const handler = safeHandler(async (
|
|||||||
const transactionResult = await prismaClient.$transaction(async (tx) => {
|
const transactionResult = await prismaClient.$transaction(async (tx) => {
|
||||||
const user = await tx.user.findFirst({
|
const user = await tx.user.findFirst({
|
||||||
where: { mobileNumber: mobileNumber, isActive: true, userStatus: USER_STATUS.ACTIVE },
|
where: { mobileNumber: mobileNumber, isActive: true, userStatus: USER_STATUS.ACTIVE },
|
||||||
select: { id: true, userPasscode: true, mobileNumber: true },
|
select: { id: true, userPasscode: true, mobileNumber: true, firstName: true },
|
||||||
});
|
});
|
||||||
|
|
||||||
let newUserLocal;
|
let newUserLocal;
|
||||||
let isNewUser = false;
|
let isNewUser = false;
|
||||||
|
|
||||||
|
|
||||||
if (user && !user.userPasscode) {
|
if (user && (!user.userPasscode || !user.firstName)) {
|
||||||
// reuse existing invited user record
|
// reuse existing invited user record
|
||||||
newUserLocal = user;
|
newUserLocal = user;
|
||||||
|
isNewUser = true;
|
||||||
} else if (user) {
|
} else if (user) {
|
||||||
// Fully registered user already exists
|
// Fully registered user already exists
|
||||||
newUserLocal = user;
|
newUserLocal = user;
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
||||||
|
import { safeHandler } from '../../../../common/utils/handlers/safeHandler';
|
||||||
|
import { prismaClient } from '../../../../common/database/prisma.lambda.service';
|
||||||
|
import ApiError from '../../../../common/utils/helper/ApiError';
|
||||||
|
import { UserService } from '../../services/user.service';
|
||||||
|
import { verifyUserToken } from '../../../../common/middlewares/jwt/authForUser';
|
||||||
|
|
||||||
|
const userService = new UserService(prismaClient);
|
||||||
|
|
||||||
|
export const handler = safeHandler(async (
|
||||||
|
event: APIGatewayProxyEvent,
|
||||||
|
context?: Context,
|
||||||
|
): Promise<APIGatewayProxyResult> => {
|
||||||
|
const token = event.headers['x-auth-token'] || event.headers['X-Auth-Token'];
|
||||||
|
if (!token) {
|
||||||
|
throw new ApiError(
|
||||||
|
400,
|
||||||
|
'This is a protected route. Please provide a valid token.',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const userInfo = await verifyUserToken(token);
|
||||||
|
const userId = Number(userInfo.id);
|
||||||
|
|
||||||
|
if (!userId || isNaN(userId)) {
|
||||||
|
throw new ApiError(400, 'Invalid user ID');
|
||||||
|
}
|
||||||
|
|
||||||
|
const searchQuery = event.queryStringParameters?.searchQuery ?? '';
|
||||||
|
const result = await userService.searchConnectionPeople(userId, searchQuery);
|
||||||
|
|
||||||
|
return {
|
||||||
|
statusCode: 200,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'Access-Control-Allow-Origin': '*',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
success: true,
|
||||||
|
message: 'Connection people retrieved successfully',
|
||||||
|
data: result,
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
});
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
||||||
|
import { prismaClient } from '../../../../common/database/prisma.lambda.service';
|
||||||
|
import { verifyUserToken } from '../../../../common/middlewares/jwt/authForUser';
|
||||||
|
import { safeHandler } from '../../../../common/utils/handlers/safeHandler';
|
||||||
|
import ApiError from '../../../../common/utils/helper/ApiError';
|
||||||
|
import { ItineraryService } from '../../services/itinerary.service';
|
||||||
|
|
||||||
|
const itineraryService = new ItineraryService(prismaClient);
|
||||||
|
|
||||||
|
export const handler = safeHandler(async (
|
||||||
|
event: APIGatewayProxyEvent,
|
||||||
|
context?: Context,
|
||||||
|
): Promise<APIGatewayProxyResult> => {
|
||||||
|
const token = event.headers['x-auth-token'] || event.headers['X-Auth-Token'];
|
||||||
|
if (!token) {
|
||||||
|
throw new ApiError(
|
||||||
|
400,
|
||||||
|
'This is a protected route. Please provide a valid token.',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const userInfo = await verifyUserToken(token);
|
||||||
|
const userId = Number(userInfo.id);
|
||||||
|
|
||||||
|
if (!userId || isNaN(userId)) {
|
||||||
|
throw new ApiError(400, 'Invalid user ID');
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = await itineraryService.getAllUserSavedItineraries(userId);
|
||||||
|
|
||||||
|
return {
|
||||||
|
statusCode: 200,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'Access-Control-Allow-Origin': '*',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
success: true,
|
||||||
|
message: 'Saved itineraries retrieved successfully',
|
||||||
|
data: result,
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
});
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
||||||
|
import { prismaClient } from '../../../../common/database/prisma.lambda.service';
|
||||||
|
import { verifyUserToken } from '../../../../common/middlewares/jwt/authForUser';
|
||||||
|
import { safeHandler } from '../../../../common/utils/handlers/safeHandler';
|
||||||
|
import ApiError from '../../../../common/utils/helper/ApiError';
|
||||||
|
import { ItineraryService } from '../../services/itinerary.service';
|
||||||
|
|
||||||
|
const itineraryService = new ItineraryService(prismaClient);
|
||||||
|
|
||||||
|
export const handler = safeHandler(async (
|
||||||
|
event: APIGatewayProxyEvent,
|
||||||
|
context?: Context,
|
||||||
|
): Promise<APIGatewayProxyResult> => {
|
||||||
|
const token = event.headers['x-auth-token'] || event.headers['X-Auth-Token'];
|
||||||
|
if (!token) {
|
||||||
|
throw new ApiError(
|
||||||
|
400,
|
||||||
|
'This is a protected route. Please provide a valid token.',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const userInfo = await verifyUserToken(token);
|
||||||
|
const userId = Number(userInfo.id);
|
||||||
|
|
||||||
|
if (!userId || Number.isNaN(userId)) {
|
||||||
|
throw new ApiError(400, 'Invalid user ID');
|
||||||
|
}
|
||||||
|
|
||||||
|
let body: Record<string, any> = {};
|
||||||
|
if (event.body) {
|
||||||
|
try {
|
||||||
|
body = JSON.parse(event.body);
|
||||||
|
} catch {
|
||||||
|
throw new ApiError(400, 'Invalid JSON body');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const payload = {
|
||||||
|
userLat: Number(body.userLat),
|
||||||
|
userLong: Number(body.userLong),
|
||||||
|
startDate: body.startDate,
|
||||||
|
endDate: body.endDate,
|
||||||
|
startTime: body.startTime,
|
||||||
|
endTime: body.endTime,
|
||||||
|
energyLevelXid:
|
||||||
|
body.energyLevelXid !== undefined && body.energyLevelXid !== null
|
||||||
|
? Number(body.energyLevelXid)
|
||||||
|
: undefined,
|
||||||
|
entryTypeXid: Number(body.entryTypeXid),
|
||||||
|
groupCount:
|
||||||
|
body.groupCount !== undefined && body.groupCount !== null
|
||||||
|
? Number(body.groupCount)
|
||||||
|
: undefined,
|
||||||
|
page: body.page !== undefined ? Number(body.page) : 1,
|
||||||
|
limit: body.limit !== undefined ? Number(body.limit) : 20,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (
|
||||||
|
Number.isNaN(payload.userLat) ||
|
||||||
|
Number.isNaN(payload.userLong) ||
|
||||||
|
!payload.startDate ||
|
||||||
|
!payload.endDate ||
|
||||||
|
!payload.startTime ||
|
||||||
|
!payload.endTime ||
|
||||||
|
(payload.energyLevelXid !== undefined &&
|
||||||
|
Number.isNaN(payload.energyLevelXid)) ||
|
||||||
|
Number.isNaN(payload.entryTypeXid) ||
|
||||||
|
(payload.groupCount !== undefined && Number.isNaN(payload.groupCount)) ||
|
||||||
|
Number.isNaN(payload.page) ||
|
||||||
|
Number.isNaN(payload.limit)
|
||||||
|
) {
|
||||||
|
throw new ApiError(
|
||||||
|
400,
|
||||||
|
'userLat, userLong, startDate, endDate, startTime, endTime, entryTypeXid, page and limit are required. energyLevelXid is optional.',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = await itineraryService.getMatchingBucketInterestedActivities(
|
||||||
|
userId,
|
||||||
|
payload,
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
statusCode: 200,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'Access-Control-Allow-Origin': '*',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
success: true,
|
||||||
|
message: 'Matching itinerary activities retrieved successfully',
|
||||||
|
data: result,
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
});
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
||||||
|
import { prismaClient } from '../../../../common/database/prisma.lambda.service';
|
||||||
|
import { verifyUserToken } from '../../../../common/middlewares/jwt/authForUser';
|
||||||
|
import { safeHandler } from '../../../../common/utils/handlers/safeHandler';
|
||||||
|
import ApiError from '../../../../common/utils/helper/ApiError';
|
||||||
|
import { ItineraryService } from '../../services/itinerary.service';
|
||||||
|
|
||||||
|
const itineraryService = new ItineraryService(prismaClient);
|
||||||
|
|
||||||
|
export const handler = safeHandler(async (
|
||||||
|
event: APIGatewayProxyEvent,
|
||||||
|
context?: Context,
|
||||||
|
): Promise<APIGatewayProxyResult> => {
|
||||||
|
const token = event.headers['x-auth-token'] || event.headers['X-Auth-Token'];
|
||||||
|
if (!token) {
|
||||||
|
throw new ApiError(
|
||||||
|
400,
|
||||||
|
'This is a protected route. Please provide a valid token.',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const userInfo = await verifyUserToken(token);
|
||||||
|
const userId = Number(userInfo.id);
|
||||||
|
|
||||||
|
if (!userId || isNaN(userId)) {
|
||||||
|
throw new ApiError(400, 'Invalid user ID');
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = await itineraryService.getUserItineraryDetails(userId);
|
||||||
|
|
||||||
|
return {
|
||||||
|
statusCode: 200,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'Access-Control-Allow-Origin': '*',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
success: true,
|
||||||
|
message: 'Itinerary details retrieved successfully',
|
||||||
|
data: result,
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
});
|
||||||
145
src/modules/user/handlers/itinerary/saveUserItinerary.ts
Normal file
145
src/modules/user/handlers/itinerary/saveUserItinerary.ts
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context } from 'aws-lambda';
|
||||||
|
import { prismaClient } from '../../../../common/database/prisma.lambda.service';
|
||||||
|
import { verifyUserToken } from '../../../../common/middlewares/jwt/authForUser';
|
||||||
|
import { safeHandler } from '../../../../common/utils/handlers/safeHandler';
|
||||||
|
import ApiError from '../../../../common/utils/helper/ApiError';
|
||||||
|
import { ItineraryService } from '../../services/itinerary.service';
|
||||||
|
|
||||||
|
const itineraryService = new ItineraryService(prismaClient);
|
||||||
|
|
||||||
|
export const handler = safeHandler(async (
|
||||||
|
event: APIGatewayProxyEvent,
|
||||||
|
context?: Context,
|
||||||
|
): Promise<APIGatewayProxyResult> => {
|
||||||
|
const token = event.headers['x-auth-token'] || event.headers['X-Auth-Token'];
|
||||||
|
if (!token) {
|
||||||
|
throw new ApiError(
|
||||||
|
400,
|
||||||
|
'This is a protected route. Please provide a valid token.',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const userInfo = await verifyUserToken(token);
|
||||||
|
const userId = Number(userInfo.id);
|
||||||
|
|
||||||
|
if (!userId || Number.isNaN(userId)) {
|
||||||
|
throw new ApiError(400, 'Invalid user ID');
|
||||||
|
}
|
||||||
|
|
||||||
|
let body: Record<string, any> = {};
|
||||||
|
if (event.body) {
|
||||||
|
try {
|
||||||
|
body = JSON.parse(event.body);
|
||||||
|
} catch {
|
||||||
|
throw new ApiError(400, 'Invalid JSON body');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const activities = Array.isArray(body.activities) ? body.activities : [];
|
||||||
|
|
||||||
|
if (!body.startDate || !body.endDate || !body.startTime || !body.endTime) {
|
||||||
|
throw new ApiError(
|
||||||
|
400,
|
||||||
|
'startDate, endDate, startTime and endTime are required.',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!activities.length) {
|
||||||
|
throw new ApiError(400, 'At least one activity is required.');
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const activity of activities) {
|
||||||
|
if (
|
||||||
|
!activity.activityXid ||
|
||||||
|
!activity.venueXid ||
|
||||||
|
!activity.scheduleHeaderXid ||
|
||||||
|
!activity.modeOfTravel ||
|
||||||
|
activity.travelTimeBetweenPointsMins === undefined ||
|
||||||
|
activity.travelTimeBetweenPointsMins === null
|
||||||
|
) {
|
||||||
|
throw new ApiError(
|
||||||
|
400,
|
||||||
|
'Each activity must include activityXid, venueXid, scheduleHeaderXid, modeOfTravel and travelTimeBetweenPointsMins.',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const payload = {
|
||||||
|
title: body.title,
|
||||||
|
startDate: body.startDate,
|
||||||
|
endDate: body.endDate,
|
||||||
|
startTime: body.startTime,
|
||||||
|
endTime: body.endTime,
|
||||||
|
activities: activities.map((activity: any) => ({
|
||||||
|
activityXid: Number(activity.activityXid),
|
||||||
|
venueXid: Number(activity.venueXid),
|
||||||
|
scheduleHeaderXid: Number(activity.scheduleHeaderXid),
|
||||||
|
modeOfTravel: activity.modeOfTravel,
|
||||||
|
travelTimeBetweenPointsMins: Number(
|
||||||
|
activity.travelTimeBetweenPointsMins,
|
||||||
|
),
|
||||||
|
kmForNextPoint:
|
||||||
|
activity.kmForNextPoint !== undefined &&
|
||||||
|
activity.kmForNextPoint !== null
|
||||||
|
? Number(activity.kmForNextPoint)
|
||||||
|
: undefined,
|
||||||
|
occurenceDate: activity.occurenceDate,
|
||||||
|
selectedStartTime: activity.selectedStartTime,
|
||||||
|
selectedEndTime: activity.selectedEndTime,
|
||||||
|
itineraryType: activity.itineraryType,
|
||||||
|
paxCount:
|
||||||
|
activity.paxCount !== undefined && activity.paxCount !== null
|
||||||
|
? Number(activity.paxCount)
|
||||||
|
: undefined,
|
||||||
|
totalAmount:
|
||||||
|
activity.totalAmount !== undefined && activity.totalAmount !== null
|
||||||
|
? Number(activity.totalAmount)
|
||||||
|
: undefined,
|
||||||
|
locationLat:
|
||||||
|
activity.locationLat !== undefined && activity.locationLat !== null
|
||||||
|
? Number(activity.locationLat)
|
||||||
|
: undefined,
|
||||||
|
locationLong:
|
||||||
|
activity.locationLong !== undefined && activity.locationLong !== null
|
||||||
|
? Number(activity.locationLong)
|
||||||
|
: undefined,
|
||||||
|
locationAddress: activity.locationAddress,
|
||||||
|
})),
|
||||||
|
};
|
||||||
|
|
||||||
|
if (
|
||||||
|
payload.activities.some(
|
||||||
|
(activity) =>
|
||||||
|
Number.isNaN(activity.activityXid) ||
|
||||||
|
Number.isNaN(activity.venueXid) ||
|
||||||
|
Number.isNaN(activity.scheduleHeaderXid) ||
|
||||||
|
Number.isNaN(activity.travelTimeBetweenPointsMins) ||
|
||||||
|
(activity.kmForNextPoint !== undefined &&
|
||||||
|
Number.isNaN(activity.kmForNextPoint)) ||
|
||||||
|
(activity.paxCount !== undefined && Number.isNaN(activity.paxCount)) ||
|
||||||
|
(activity.totalAmount !== undefined &&
|
||||||
|
Number.isNaN(activity.totalAmount)) ||
|
||||||
|
(activity.locationLat !== undefined &&
|
||||||
|
Number.isNaN(activity.locationLat)) ||
|
||||||
|
(activity.locationLong !== undefined &&
|
||||||
|
Number.isNaN(activity.locationLong)),
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
throw new ApiError(400, 'One or more numeric itinerary values are invalid.');
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = await itineraryService.saveUserItinerary(userId, payload);
|
||||||
|
|
||||||
|
return {
|
||||||
|
statusCode: 201,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'Access-Control-Allow-Origin': '*',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
success: true,
|
||||||
|
message: 'Itinerary saved successfully',
|
||||||
|
data: result,
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
});
|
||||||
1815
src/modules/user/services/itinerary.service.ts
Normal file
1815
src/modules/user/services/itinerary.service.ts
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1148,7 +1148,9 @@ export class UserService {
|
|||||||
// 6️⃣ RANDOM ACTIVITIES (5 ONLY - SIMPLE)
|
// 6️⃣ RANDOM ACTIVITIES (5 ONLY - SIMPLE)
|
||||||
// =====================================================
|
// =====================================================
|
||||||
|
|
||||||
const totalActiveCount = await tx.activities.count({
|
let randomActivities: any[] = [];
|
||||||
|
|
||||||
|
const eligibleRandomActivityIds = await tx.activities.findMany({
|
||||||
where: {
|
where: {
|
||||||
isActive: true,
|
isActive: true,
|
||||||
activityInternalStatus: ACTIVITY_INTERNAL_STATUS.ACTIVITY_LISTED,
|
activityInternalStatus: ACTIVITY_INTERNAL_STATUS.ACTIVITY_LISTED,
|
||||||
@@ -1157,53 +1159,44 @@ export class UserService {
|
|||||||
id: {
|
id: {
|
||||||
notIn: allUserExcludedActivityIds.length
|
notIn: allUserExcludedActivityIds.length
|
||||||
? allUserExcludedActivityIds
|
? allUserExcludedActivityIds
|
||||||
: [-1], // prevent empty notIn issue
|
: [-1],
|
||||||
},
|
},
|
||||||
|
ActivitiesMedia: {
|
||||||
|
some: {
|
||||||
|
isActive: true,
|
||||||
|
isCoverImage: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
let randomActivities: any[] = [];
|
if (eligibleRandomActivityIds.length > 0) {
|
||||||
|
const takeCount = Math.min(5, eligibleRandomActivityIds.length);
|
||||||
|
const selectedIds = eligibleRandomActivityIds
|
||||||
|
.sort(() => Math.random() - 0.5)
|
||||||
|
.slice(0, takeCount)
|
||||||
|
.map((activity) => activity.id);
|
||||||
|
|
||||||
if (totalActiveCount > 0) {
|
const randomFetched = await tx.activities.findMany({
|
||||||
const takeCount = Math.min(5, totalActiveCount);
|
where: {
|
||||||
|
id: { in: selectedIds },
|
||||||
const randomOffsets = new Set<number>();
|
},
|
||||||
while (randomOffsets.size < takeCount) {
|
select: {
|
||||||
randomOffsets.add(Math.floor(Math.random() * totalActiveCount));
|
id: true,
|
||||||
}
|
activityTitle: true,
|
||||||
|
ActivitiesMedia: {
|
||||||
const randomFetched = await Promise.all(
|
where: { isActive: true, isCoverImage: true },
|
||||||
Array.from(randomOffsets).map((offset) =>
|
orderBy: { displayOrder: 'asc' },
|
||||||
tx.activities.findFirst({
|
take: 1,
|
||||||
skip: offset,
|
|
||||||
where: {
|
|
||||||
isActive: true,
|
|
||||||
activityInternalStatus:
|
|
||||||
ACTIVITY_INTERNAL_STATUS.ACTIVITY_LISTED,
|
|
||||||
amInternalStatus:
|
|
||||||
ACTIVITY_AM_INTERNAL_STATUS.ACTIVITY_LISTED,
|
|
||||||
deletedAt: null,
|
|
||||||
id: {
|
|
||||||
notIn: allUserExcludedActivityIds.length
|
|
||||||
? allUserExcludedActivityIds
|
|
||||||
: [-1], // prevent empty notIn issue
|
|
||||||
},
|
|
||||||
},
|
|
||||||
select: {
|
select: {
|
||||||
id: true,
|
mediaFileName: true,
|
||||||
activityTitle: true,
|
|
||||||
ActivitiesMedia: {
|
|
||||||
where: { isActive: true, isCoverImage: true },
|
|
||||||
orderBy: { displayOrder: 'asc' },
|
|
||||||
take: 1,
|
|
||||||
select: {
|
|
||||||
mediaFileName: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}),
|
},
|
||||||
),
|
},
|
||||||
);
|
});
|
||||||
|
|
||||||
randomActivities = await Promise.all(
|
randomActivities = await Promise.all(
|
||||||
randomFetched
|
randomFetched
|
||||||
@@ -1817,7 +1810,9 @@ export class UserService {
|
|||||||
RANDOM ACTIVITIES (5 COVER IMAGES)
|
RANDOM ACTIVITIES (5 COVER IMAGES)
|
||||||
===================================================== */
|
===================================================== */
|
||||||
|
|
||||||
const totalActiveCount = await tx.activities.count({
|
let randomActivities: any[] = [];
|
||||||
|
|
||||||
|
const eligibleRandomActivityIds = await tx.activities.findMany({
|
||||||
where: {
|
where: {
|
||||||
isActive: true,
|
isActive: true,
|
||||||
activityInternalStatus: ACTIVITY_INTERNAL_STATUS.ACTIVITY_LISTED,
|
activityInternalStatus: ACTIVITY_INTERNAL_STATUS.ACTIVITY_LISTED,
|
||||||
@@ -1826,50 +1821,43 @@ export class UserService {
|
|||||||
id: {
|
id: {
|
||||||
notIn: safeExcludedIds,
|
notIn: safeExcludedIds,
|
||||||
},
|
},
|
||||||
|
ActivitiesMedia: {
|
||||||
|
some: {
|
||||||
|
isActive: true,
|
||||||
|
isCoverImage: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
...excludeUserInterestCondition,
|
...excludeUserInterestCondition,
|
||||||
},
|
},
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
let randomActivities: any[] = [];
|
if (eligibleRandomActivityIds.length > 0) {
|
||||||
|
const takeCount = Math.min(5, eligibleRandomActivityIds.length);
|
||||||
|
const selectedIds = eligibleRandomActivityIds
|
||||||
|
.sort(() => Math.random() - 0.5)
|
||||||
|
.slice(0, takeCount)
|
||||||
|
.map((activity) => activity.id);
|
||||||
|
|
||||||
if (totalActiveCount > 0) {
|
const randomFetched = await tx.activities.findMany({
|
||||||
const takeCount = Math.min(5, totalActiveCount);
|
where: {
|
||||||
|
id: { in: selectedIds },
|
||||||
const randomOffsets = new Set<number>();
|
},
|
||||||
|
select: {
|
||||||
while (randomOffsets.size < takeCount) {
|
id: true,
|
||||||
randomOffsets.add(Math.floor(Math.random() * totalActiveCount));
|
activityTitle: true,
|
||||||
}
|
ActivitiesMedia: {
|
||||||
|
where: { isActive: true, isCoverImage: true },
|
||||||
const randomFetched = await Promise.all(
|
orderBy: { displayOrder: 'asc' },
|
||||||
Array.from(randomOffsets).map((offset) =>
|
take: 1,
|
||||||
tx.activities.findFirst({
|
|
||||||
skip: offset,
|
|
||||||
where: {
|
|
||||||
isActive: true,
|
|
||||||
activityInternalStatus: ACTIVITY_INTERNAL_STATUS.ACTIVITY_LISTED,
|
|
||||||
amInternalStatus: ACTIVITY_AM_INTERNAL_STATUS.ACTIVITY_LISTED,
|
|
||||||
deletedAt: null,
|
|
||||||
id: {
|
|
||||||
notIn: safeExcludedIds,
|
|
||||||
},
|
|
||||||
...excludeUserInterestCondition,
|
|
||||||
},
|
|
||||||
select: {
|
select: {
|
||||||
id: true,
|
mediaFileName: true,
|
||||||
activityTitle: true,
|
|
||||||
ActivitiesMedia: {
|
|
||||||
where: { isActive: true, isCoverImage: true },
|
|
||||||
orderBy: { displayOrder: 'asc' },
|
|
||||||
take: 1,
|
|
||||||
select: {
|
|
||||||
mediaFileName: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}),
|
},
|
||||||
),
|
},
|
||||||
);
|
});
|
||||||
|
|
||||||
randomActivities = await Promise.all(
|
randomActivities = await Promise.all(
|
||||||
randomFetched
|
randomFetched
|
||||||
@@ -2863,6 +2851,111 @@ export class UserService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async searchConnectionPeople(userXid: number, searchQuery?: string) {
|
||||||
|
const userConnectionDetails = await this.prisma.connectDetails.findMany({
|
||||||
|
where: {
|
||||||
|
userXid,
|
||||||
|
isActive: true,
|
||||||
|
deletedAt: null,
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
schoolCompanyXid: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const schoolCompanyXids = [
|
||||||
|
...new Set(userConnectionDetails.map((item) => item.schoolCompanyXid)),
|
||||||
|
];
|
||||||
|
|
||||||
|
if (!schoolCompanyXids.length) {
|
||||||
|
return {
|
||||||
|
count: 0,
|
||||||
|
people: [],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const trimmedSearchQuery = searchQuery?.trim() ?? '';
|
||||||
|
|
||||||
|
const connectionPeople = await this.prisma.connectDetails.findMany({
|
||||||
|
where: {
|
||||||
|
isActive: true,
|
||||||
|
deletedAt: null,
|
||||||
|
schoolCompanyXid: { in: schoolCompanyXids },
|
||||||
|
userXid: { not: userXid },
|
||||||
|
user: {
|
||||||
|
isActive: true,
|
||||||
|
deletedAt: null,
|
||||||
|
...(trimmedSearchQuery
|
||||||
|
? {
|
||||||
|
OR: [
|
||||||
|
{
|
||||||
|
firstName: {
|
||||||
|
contains: trimmedSearchQuery,
|
||||||
|
mode: 'insensitive',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
lastName: {
|
||||||
|
contains: trimmedSearchQuery,
|
||||||
|
mode: 'insensitive',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
: {}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
distinct: ['userXid'],
|
||||||
|
orderBy: {
|
||||||
|
createdAt: 'desc',
|
||||||
|
},
|
||||||
|
take: 10,
|
||||||
|
select: {
|
||||||
|
userXid: true,
|
||||||
|
schoolCompany: {
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
schoolCompanyName: true,
|
||||||
|
isSchool: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
user: {
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
firstName: true,
|
||||||
|
lastName: true,
|
||||||
|
profileImage: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const people = await Promise.all(
|
||||||
|
connectionPeople.map(async (item) => {
|
||||||
|
const firstName = item.user.firstName?.trim() ?? '';
|
||||||
|
const lastName = item.user.lastName?.trim() ?? '';
|
||||||
|
const fullName = `${firstName} ${lastName}`.trim();
|
||||||
|
|
||||||
|
return {
|
||||||
|
userXid: item.user.id,
|
||||||
|
fullName,
|
||||||
|
firstName: item.user.firstName,
|
||||||
|
lastName: item.user.lastName,
|
||||||
|
profileImage: item.user.profileImage,
|
||||||
|
profileImagePresignedUrl: await attachPresignedUrl(
|
||||||
|
item.user.profileImage,
|
||||||
|
),
|
||||||
|
schoolCompany: item.schoolCompany,
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
count: people.length,
|
||||||
|
people,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
async searchSchoolsAndCompanies(searchQuery: string, isSchool: boolean) {
|
async searchSchoolsAndCompanies(searchQuery: string, isSchool: boolean) {
|
||||||
if (!searchQuery) {
|
if (!searchQuery) {
|
||||||
throw new ApiError(
|
throw new ApiError(
|
||||||
@@ -3529,7 +3622,9 @@ export class UserService {
|
|||||||
RANDOM ACTIVITIES FROM CONNECTION USERS (5 COVER IMAGES)
|
RANDOM ACTIVITIES FROM CONNECTION USERS (5 COVER IMAGES)
|
||||||
===================================================== */
|
===================================================== */
|
||||||
|
|
||||||
const totalActiveCount = await tx.activities.count({
|
let randomActivities: any[] = [];
|
||||||
|
|
||||||
|
const eligibleRandomActivityIds = await tx.activities.findMany({
|
||||||
where: {
|
where: {
|
||||||
id: { in: connectionActivityIds },
|
id: { in: connectionActivityIds },
|
||||||
isActive: true,
|
isActive: true,
|
||||||
@@ -3537,47 +3632,42 @@ export class UserService {
|
|||||||
amInternalStatus: ACTIVITY_AM_INTERNAL_STATUS.ACTIVITY_LISTED,
|
amInternalStatus: ACTIVITY_AM_INTERNAL_STATUS.ACTIVITY_LISTED,
|
||||||
activityTypeXid: { in: activityTypeIds },
|
activityTypeXid: { in: activityTypeIds },
|
||||||
deletedAt: null,
|
deletedAt: null,
|
||||||
|
ActivitiesMedia: {
|
||||||
|
some: {
|
||||||
|
isActive: true,
|
||||||
|
isCoverImage: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
let randomActivities: any[] = [];
|
if (eligibleRandomActivityIds.length > 0) {
|
||||||
|
const takeCount = Math.min(5, eligibleRandomActivityIds.length);
|
||||||
|
const selectedIds = eligibleRandomActivityIds
|
||||||
|
.sort(() => Math.random() - 0.5)
|
||||||
|
.slice(0, takeCount)
|
||||||
|
.map((activity) => activity.id);
|
||||||
|
|
||||||
if (totalActiveCount > 0) {
|
const randomFetched = await tx.activities.findMany({
|
||||||
const takeCount = Math.min(5, totalActiveCount);
|
where: {
|
||||||
|
id: { in: selectedIds },
|
||||||
const randomOffsets = new Set<number>();
|
},
|
||||||
|
select: {
|
||||||
while (randomOffsets.size < takeCount) {
|
id: true,
|
||||||
randomOffsets.add(Math.floor(Math.random() * totalActiveCount));
|
activityTitle: true,
|
||||||
}
|
ActivitiesMedia: {
|
||||||
|
where: { isActive: true, isCoverImage: true },
|
||||||
const randomFetched = await Promise.all(
|
orderBy: { displayOrder: 'asc' },
|
||||||
Array.from(randomOffsets).map((offset) =>
|
take: 1,
|
||||||
tx.activities.findFirst({
|
|
||||||
skip: offset,
|
|
||||||
where: {
|
|
||||||
id: { in: connectionActivityIds },
|
|
||||||
isActive: true,
|
|
||||||
activityInternalStatus: ACTIVITY_INTERNAL_STATUS.ACTIVITY_LISTED,
|
|
||||||
amInternalStatus: ACTIVITY_AM_INTERNAL_STATUS.ACTIVITY_LISTED,
|
|
||||||
activityTypeXid: { in: activityTypeIds },
|
|
||||||
deletedAt: null,
|
|
||||||
},
|
|
||||||
select: {
|
select: {
|
||||||
id: true,
|
mediaFileName: true,
|
||||||
activityTitle: true,
|
|
||||||
ActivitiesMedia: {
|
|
||||||
where: { isActive: true, isCoverImage: true },
|
|
||||||
orderBy: { displayOrder: "asc" },
|
|
||||||
take: 1,
|
|
||||||
select: {
|
|
||||||
mediaFileName: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}),
|
},
|
||||||
),
|
},
|
||||||
);
|
});
|
||||||
|
|
||||||
randomActivities = await Promise.all(
|
randomActivities = await Promise.all(
|
||||||
randomFetched
|
randomFetched
|
||||||
@@ -4046,56 +4136,54 @@ export class UserService {
|
|||||||
async getFiveRandomActivities() {
|
async getFiveRandomActivities() {
|
||||||
return await this.prisma.$transaction(async (tx) => {
|
return await this.prisma.$transaction(async (tx) => {
|
||||||
|
|
||||||
// Step 1: Count eligible activities
|
const eligibleRandomActivityIds = await tx.activities.findMany({
|
||||||
const totalCount = await tx.activities.count({
|
|
||||||
where: {
|
where: {
|
||||||
isActive: true,
|
isActive: true,
|
||||||
activityInternalStatus: ACTIVITY_INTERNAL_STATUS.ACTIVITY_LISTED,
|
activityInternalStatus: ACTIVITY_INTERNAL_STATUS.ACTIVITY_LISTED,
|
||||||
amInternalStatus: ACTIVITY_AM_INTERNAL_STATUS.ACTIVITY_LISTED,
|
amInternalStatus: ACTIVITY_AM_INTERNAL_STATUS.ACTIVITY_LISTED,
|
||||||
deletedAt: null,
|
deletedAt: null,
|
||||||
|
ActivitiesMedia: {
|
||||||
|
some: {
|
||||||
|
isActive: true,
|
||||||
|
isCoverImage: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (totalCount === 0) return [];
|
if (eligibleRandomActivityIds.length === 0) return [];
|
||||||
|
|
||||||
// Step 2: Generate 5 unique random offsets
|
const takeCount = Math.min(5, eligibleRandomActivityIds.length);
|
||||||
const takeCount = Math.min(5, totalCount);
|
const selectedIds = eligibleRandomActivityIds
|
||||||
const randomOffsets = new Set<number>();
|
.sort(() => Math.random() - 0.5)
|
||||||
|
.slice(0, takeCount)
|
||||||
|
.map((activity) => activity.id);
|
||||||
|
|
||||||
while (randomOffsets.size < takeCount) {
|
const activities = await tx.activities.findMany({
|
||||||
randomOffsets.add(Math.floor(Math.random() * totalCount));
|
where: {
|
||||||
}
|
id: { in: selectedIds },
|
||||||
|
},
|
||||||
// Step 3: Fetch activities using skip (efficient for small limit like 5)
|
select: {
|
||||||
const activities = await Promise.all(
|
id: true,
|
||||||
Array.from(randomOffsets).map((offset) =>
|
activityTitle: true,
|
||||||
tx.activities.findFirst({
|
ActivitiesMedia: {
|
||||||
skip: offset,
|
|
||||||
where: {
|
where: {
|
||||||
isActive: true,
|
isActive: true,
|
||||||
activityInternalStatus: ACTIVITY_INTERNAL_STATUS.ACTIVITY_LISTED,
|
isCoverImage: true,
|
||||||
amInternalStatus: ACTIVITY_AM_INTERNAL_STATUS.ACTIVITY_LISTED,
|
|
||||||
deletedAt: null,
|
|
||||||
},
|
},
|
||||||
|
orderBy: {
|
||||||
|
displayOrder: 'asc',
|
||||||
|
},
|
||||||
|
take: 1,
|
||||||
select: {
|
select: {
|
||||||
id: true,
|
mediaFileName: true,
|
||||||
activityTitle: true,
|
|
||||||
ActivitiesMedia: {
|
|
||||||
where: {
|
|
||||||
isActive: true,
|
|
||||||
},
|
|
||||||
orderBy: {
|
|
||||||
displayOrder: 'asc',
|
|
||||||
},
|
|
||||||
take: 1,
|
|
||||||
select: {
|
|
||||||
mediaFileName: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
})
|
},
|
||||||
)
|
},
|
||||||
);
|
});
|
||||||
|
|
||||||
// Step 4: Attach presigned URLs
|
// Step 4: Attach presigned URLs
|
||||||
const result = await Promise.all(
|
const result = await Promise.all(
|
||||||
@@ -4138,7 +4226,7 @@ export class UserService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const existing = await this.prisma.userBucketInterested.findFirst({
|
const existing = await this.prisma.userBucketInterested.findFirst({
|
||||||
where: { userXid, activityXid },
|
where: { userXid, activityXid, isActive: true },
|
||||||
});
|
});
|
||||||
|
|
||||||
if (existing) {
|
if (existing) {
|
||||||
@@ -4322,4 +4410,4 @@ export class UserService {
|
|||||||
oneDay,
|
oneDay,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user