Made add to bucket interested api and sending the count of bucket interested in the landing page api and surprise me api and sending the updated count in the add to bucket api

This commit is contained in:
2026-02-28 13:11:26 +05:30
parent 3fa5b8a3dd
commit fe6bb59cc7
3 changed files with 254 additions and 4 deletions

View File

@@ -346,4 +346,19 @@ getNearbyActivities:
events:
- httpApi:
path: /user/activities/get-nearby-activities
method: get
method: get
addActivityToBucketInterested:
handler: src/modules/user/handlers/activities/addToBucketInterested.handler
memorySize: 384
package:
patterns:
- 'src/modules/user/handlers/activities/**'
- ${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: /user/activities/add-to-bucket-interested
method: post

View File

@@ -0,0 +1,72 @@
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 { UserService } from '../../services/user.service';
const userService = new UserService(prismaClient);
export const handler = safeHandler(async (
event: APIGatewayProxyEvent,
context?: Context
): Promise<APIGatewayProxyResult> => {
// Extract token from headers
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.');
}
// Authenticate user using verifyUserToken
const userInfo = await verifyUserToken(token);
const userId = userInfo.id;
if (Number.isNaN(userId)) {
throw new ApiError(400, 'User id must be a number');
}
const user = await userService.getUserById(userId);
if (!user) {
throw new ApiError(404, 'User not found');
}
// Parse request body
let body: { activityXid: number; isBucket: boolean; bucketTypeName: string; };
try {
body = event.body ? JSON.parse(event.body) : {};
} catch (error) {
throw new ApiError(400, 'Invalid JSON in request body');
}
const { activityXid, isBucket, bucketTypeName } = body;
// Validate required fields
if (
typeof activityXid !== 'number' ||
typeof isBucket !== 'boolean' ||
!bucketTypeName
) {
throw new ApiError(400, 'Required fields missing or invalid');
}
// Set the passcode
const counts = await userService.addToBucketInterested(userId, isBucket, bucketTypeName, activityXid);
return {
statusCode: 200,
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
},
body: JSON.stringify({
success: true,
message: `Activity added to ${isBucket ? 'bucket' : 'interested'} successfully`,
data: {
bucketCount: counts.bucketCount,
interestedCount: counts.interestedCount,
}
}),
};
});

View File

@@ -709,6 +709,29 @@ export class UserService {
};
}
const userBucketInterested = await tx.userBucketInterested.findMany({
where: {
userXid: userId,
isActive: true,
},
select: {
activityXid: true,
isBucket: true,
},
});
const userBucketActivityIds = userBucketInterested
.filter(u => u.isBucket)
.map(u => u.activityXid);
const userInterestedActivityIds = userBucketInterested
.filter(u => !u.isBucket)
.map(u => u.activityXid);
const allUserExcludedActivityIds = userBucketInterested.map(
u => u.activityXid,
);
const userConnectionDetails = await tx.connectDetails.findMany({
where: { userXid: userId, isActive: true },
select: {
@@ -762,6 +785,11 @@ export class UserService {
activityTypeXid: {
in: activitiyTypesOfUserInterests.map((at) => at.id),
},
id: {
notIn: allUserExcludedActivityIds.length
? allUserExcludedActivityIds
: [-1], // prevent empty notIn issue
},
},
skip,
take: limit,
@@ -842,7 +870,12 @@ export class UserService {
// IF user wants the standard 4-step ranking applied TO the most hyped items:
const mostHypedActivitiesRaw = await tx.activities.findMany({
where: {
id: { in: mostHypedActivityIds },
id: {
in: mostHypedActivityIds,
notIn: allUserExcludedActivityIds.length
? allUserExcludedActivityIds
: [-1],
},
isActive: true,
activityInternalStatus: ACTIVITY_INTERNAL_STATUS.ACTIVITY_LISTED,
amInternalStatus: ACTIVITY_AM_INTERNAL_STATUS.ACTIVITY_LISTED,
@@ -966,6 +999,11 @@ export class UserService {
isActive: true,
activityInternalStatus: ACTIVITY_INTERNAL_STATUS.ACTIVITY_LISTED,
amInternalStatus: ACTIVITY_AM_INTERNAL_STATUS.ACTIVITY_LISTED,
id: {
notIn: allUserExcludedActivityIds.length
? allUserExcludedActivityIds
: [-1], // prevent empty notIn issue
},
createdAt: { gte: new Date(Date.now() - 31 * 24 * 60 * 60 * 1000) },
};
@@ -984,6 +1022,11 @@ export class UserService {
isActive: true,
activityInternalStatus: ACTIVITY_INTERNAL_STATUS.ACTIVITY_LISTED,
amInternalStatus: ACTIVITY_AM_INTERNAL_STATUS.ACTIVITY_LISTED,
id: {
notIn: allUserExcludedActivityIds.length
? allUserExcludedActivityIds
: [-1], // prevent empty notIn issue
},
};
if (effectiveCountryXid) {
@@ -1010,6 +1053,11 @@ export class UserService {
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
},
},
});
@@ -1034,6 +1082,11 @@ export class UserService {
amInternalStatus:
ACTIVITY_AM_INTERNAL_STATUS.ACTIVITY_LISTED,
deletedAt: null,
id: {
notIn: allUserExcludedActivityIds.length
? allUserExcludedActivityIds
: [-1], // prevent empty notIn issue
},
},
select: {
id: true,
@@ -1076,6 +1129,11 @@ export class UserService {
isActive: true,
activityInternalStatus: ACTIVITY_INTERNAL_STATUS.ACTIVITY_LISTED,
amInternalStatus: ACTIVITY_AM_INTERNAL_STATUS.ACTIVITY_LISTED,
id: {
notIn: allUserExcludedActivityIds.length
? allUserExcludedActivityIds
: [-1], // prevent empty notIn issue
},
};
if (effectiveCountryXid) {
@@ -1152,6 +1210,8 @@ export class UserService {
loggedInNetworkCount: 0,
citiesInNetworkCount: 0,
rating: 0,
interestedCount: userInterestedActivityIds.length,
bucketCount: userBucketActivityIds.length,
pagination: {
page,
limit,
@@ -1237,6 +1297,32 @@ export class UserService {
const skip = (page - 1) * limit;
const userBucketInterested = await tx.userBucketInterested.findMany({
where: {
userXid: userId,
isActive: true,
},
select: {
activityXid: true,
isBucket: true,
},
});
const bucketActivityIds = userBucketInterested
.filter(u => u.isBucket)
.map(u => u.activityXid);
const interestedActivityIds = userBucketInterested
.filter(u => !u.isBucket)
.map(u => u.activityXid);
const excludedActivityIds = userBucketInterested.map(
u => u.activityXid,
);
const safeExcludedIds =
excludedActivityIds.length > 0 ? excludedActivityIds : [-1];
/* =====================================================
CONNECTION INTEREST MAP
===================================================== */
@@ -1270,7 +1356,6 @@ export class UserService {
where: {
userXid: { in: connectionUserIds },
isActive: true,
isBucket: true,
},
_count: { activityXid: true },
});
@@ -1302,6 +1387,9 @@ export class UserService {
const otherInterestActivities = await tx.activities.findMany({
where: {
isActive: true,
activityInternalStatus: ACTIVITY_INTERNAL_STATUS.ACTIVITY_LISTED,
amInternalStatus: ACTIVITY_AM_INTERNAL_STATUS.ACTIVITY_LISTED,
id: { notIn: safeExcludedIds },
...excludeUserInterestCondition,
},
skip,
@@ -1388,7 +1476,16 @@ export class UserService {
).length;
const hypedActivities = await tx.activities.findMany({
where: { id: { in: mostHypedGrouped.map((h) => h.activityXid) } },
where: {
id: {
in: mostHypedGrouped.map((h) => h.activityXid),
notIn: safeExcludedIds,
},
activityInternalStatus: ACTIVITY_INTERNAL_STATUS.ACTIVITY_LISTED,
amInternalStatus: ACTIVITY_AM_INTERNAL_STATUS.ACTIVITY_LISTED,
isActive: true,
},
select: {
id: true,
activityTitle: true,
@@ -1427,7 +1524,10 @@ export class UserService {
5⃣ NEW ARRIVALS
===================================================== */
const newArrivalsWhere = {
id: { notIn: safeExcludedIds },
isActive: true,
activityInternalStatus: ACTIVITY_INTERNAL_STATUS.ACTIVITY_LISTED,
amInternalStatus: ACTIVITY_AM_INTERNAL_STATUS.ACTIVITY_LISTED,
createdAt: { gte: new Date(Date.now() - 31 * 24 * 60 * 60 * 1000) },
...excludeUserInterestCondition,
};
@@ -1457,6 +1557,9 @@ export class UserService {
===================================================== */
const otherStatesWhere: any = {
isActive: true,
id: { notIn: safeExcludedIds },
activityInternalStatus: ACTIVITY_INTERNAL_STATUS.ACTIVITY_LISTED,
amInternalStatus: ACTIVITY_AM_INTERNAL_STATUS.ACTIVITY_LISTED,
...excludeUserInterestCondition,
};
if (effectiveCountryXid)
@@ -1466,6 +1569,9 @@ export class UserService {
const overseasWhere: any = {
isActive: true,
id: { notIn: safeExcludedIds },
activityInternalStatus: ACTIVITY_INTERNAL_STATUS.ACTIVITY_LISTED,
amInternalStatus: ACTIVITY_AM_INTERNAL_STATUS.ACTIVITY_LISTED,
...excludeUserInterestCondition,
};
if (effectiveCountryXid)
@@ -1513,6 +1619,8 @@ export class UserService {
return {
pagination: { page, limit },
interests: interestsWithActivities,
interestedCount: interestedActivityIds.length,
bucketCount: bucketActivityIds.length,
mostHypedActivities: {
page,
@@ -3500,4 +3608,59 @@ export class UserService {
});
}
async addToBucketInterested(
userXid: number,
isBucket: boolean,
bucketTypeName: string,
activityXid: number
) {
const activityExists = await this.prisma.activities.findFirst({
where: { id: activityXid, isActive: true },
});
if (!activityExists) {
throw new ApiError(404, 'Activity not found');
}
const existing = await this.prisma.userBucketInterested.findFirst({
where: { userXid, activityXid },
});
if (existing) {
throw new ApiError(400, 'Activity already added');
}
await this.prisma.userBucketInterested.create({
data: {
userXid,
activityXid,
isBucket,
bucketTypeName,
},
});
// ✅ Get updated counts
const [bucketCount, interestedCount] = await Promise.all([
this.prisma.userBucketInterested.count({
where: {
userXid,
isBucket: true,
isActive: true,
},
}),
this.prisma.userBucketInterested.count({
where: {
userXid,
isBucket: false,
isActive: true,
},
}),
]);
return {
bucketCount,
interestedCount,
};
}
}