made a pagination service
This commit is contained in:
@@ -282,7 +282,7 @@ submitCompanyDetails:
|
||||
|
||||
submitPQQ_Answer:
|
||||
handler: src/modules/host/handlers/Activity_Hub/OnBoarding/submitPQQ_Answer.handler
|
||||
memorySize: 384
|
||||
memorySize: 1024
|
||||
package:
|
||||
patterns:
|
||||
- 'src/modules/host/handlers/submitPqqAns.*'
|
||||
|
||||
66
src/common/utils/pagination/pagination.service.ts
Normal file
66
src/common/utils/pagination/pagination.service.ts
Normal file
@@ -0,0 +1,66 @@
|
||||
// common/utils/pagination/pagination.service.ts
|
||||
import { PaginationOptions, PaginationParams, PaginatedResponse } from './pagination.types';
|
||||
|
||||
export class PaginationService {
|
||||
private readonly DEFAULT_PAGE = 1;
|
||||
private readonly DEFAULT_LIMIT = 10;
|
||||
private readonly MAX_LIMIT = 100;
|
||||
|
||||
/**
|
||||
* Parse and validate pagination parameters
|
||||
*/
|
||||
parsePaginationParams(params: PaginationParams): PaginationOptions {
|
||||
let page = Number(params.page) || this.DEFAULT_PAGE;
|
||||
let limit = Number(params.limit) || this.DEFAULT_LIMIT;
|
||||
|
||||
// Validate and constrain values
|
||||
page = Math.max(1, page);
|
||||
limit = Math.max(1, Math.min(limit, this.MAX_LIMIT));
|
||||
|
||||
const skip = (page - 1) * limit;
|
||||
|
||||
return {
|
||||
page,
|
||||
limit,
|
||||
skip,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Create paginated response
|
||||
*/
|
||||
createPaginatedResponse<T>(
|
||||
data: T[],
|
||||
totalCount: number,
|
||||
paginationOptions: PaginationOptions,
|
||||
): PaginatedResponse<T> {
|
||||
const { page, limit } = paginationOptions;
|
||||
const totalPages = Math.ceil(totalCount / limit);
|
||||
|
||||
return {
|
||||
data,
|
||||
pagination: {
|
||||
currentPage: page,
|
||||
pageSize: limit,
|
||||
totalCount,
|
||||
totalPages,
|
||||
hasNext: page < totalPages,
|
||||
hasPrevious: page > 1,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract pagination params from API Gateway event
|
||||
*/
|
||||
getPaginationFromEvent(event: any): PaginationParams {
|
||||
const queryParams = event.queryStringParameters || {};
|
||||
|
||||
return {
|
||||
page: queryParams.page,
|
||||
limit: queryParams.limit,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export const paginationService = new PaginationService();
|
||||
23
src/common/utils/pagination/pagination.types.ts
Normal file
23
src/common/utils/pagination/pagination.types.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
// common/utils/pagination/pagination.types.ts
|
||||
export interface PaginationOptions {
|
||||
page: number;
|
||||
limit: number;
|
||||
skip: number;
|
||||
}
|
||||
|
||||
export interface PaginatedResponse<T> {
|
||||
data: T[];
|
||||
pagination: {
|
||||
currentPage: number;
|
||||
pageSize: number;
|
||||
totalCount: number;
|
||||
totalPages: number;
|
||||
hasNext: boolean;
|
||||
hasPrevious: boolean;
|
||||
};
|
||||
}
|
||||
|
||||
export interface PaginationParams {
|
||||
page?: string | number;
|
||||
limit?: string | number;
|
||||
}
|
||||
@@ -38,16 +38,25 @@ async function uploadToS3(buffer: Buffer, mimeType: string, originalName: string
|
||||
let s3Key: string;
|
||||
|
||||
// If existing URL provided, use the same S3 key to replace the file
|
||||
// if (existingUrl) {
|
||||
// s3Key = getS3KeyFromUrl(existingUrl);
|
||||
// // Delete existing file first
|
||||
// await deleteFromS3(s3Key);
|
||||
// } else {
|
||||
// // Generate new unique key for new file
|
||||
// const uniqueKey = `${crypto.randomUUID()}_${originalName}`;
|
||||
// s3Key = `${prefix}/${uniqueKey}`;
|
||||
// }
|
||||
if (existingUrl) {
|
||||
s3Key = getS3KeyFromUrl(existingUrl);
|
||||
// Delete existing file first
|
||||
await deleteFromS3(s3Key);
|
||||
} else {
|
||||
// Generate new unique key for new file
|
||||
const uniqueKey = `${crypto.randomUUID()}_${originalName}`;
|
||||
s3Key = `${prefix}/${uniqueKey}`;
|
||||
// Delete old file, but DO NOT reuse its name
|
||||
const oldKey = getS3KeyFromUrl(existingUrl);
|
||||
await deleteFromS3(oldKey);
|
||||
}
|
||||
|
||||
// Create new key always
|
||||
const uniqueKey = `${crypto.randomUUID()}_${originalName}`;
|
||||
s3Key = `${prefix}/${uniqueKey}`;
|
||||
|
||||
// Upload new file (replaces existing if same key)
|
||||
await s3.upload({
|
||||
Bucket: config.aws.bucketName,
|
||||
|
||||
@@ -4,13 +4,13 @@ import { PrismaService } from '../../../../../common/database/prisma.service';
|
||||
import { MinglarService } from '../../../services/minglar.service';
|
||||
import ApiError from '../../../../../common/utils/helper/ApiError';
|
||||
import { verifyMinglarAdminToken } from '../../../../../common/middlewares/jwt/authForMinglarAdmin';
|
||||
import { paginationService } from '../../../../../common/utils/pagination/pagination.service';
|
||||
|
||||
const prismaService = new PrismaService();
|
||||
const minglarService = new MinglarService(prismaService);
|
||||
|
||||
/**
|
||||
* Get all host applications handler
|
||||
* Returns host details with status, submission date, and account manager info
|
||||
* Get all host applications handler with pagination
|
||||
*/
|
||||
export const handler = safeHandler(async (
|
||||
event: APIGatewayProxyEvent,
|
||||
@@ -35,13 +35,29 @@ export const handler = safeHandler(async (
|
||||
throw new ApiError(404, 'User not found');
|
||||
}
|
||||
|
||||
// Get search query from query parameters
|
||||
// Get query parameters
|
||||
const search = event.queryStringParameters?.search || '';
|
||||
// Extract userStatus (e.g. 'new') from query parameters
|
||||
const userStatus = event.queryStringParameters?.userStatus || '';
|
||||
|
||||
// Parse pagination parameters
|
||||
const paginationParams = paginationService.getPaginationFromEvent(event);
|
||||
const paginationOptions = paginationService.parsePaginationParams(paginationParams);
|
||||
|
||||
// Get all host applications from service based on user role
|
||||
const hostApplications = await minglarService.getAllHostApplications(user.id, Number(user.roleXid), search, userStatus);
|
||||
// Get paginated host applications
|
||||
const { data, totalCount } = await minglarService.getAllHostApplications(
|
||||
user.id,
|
||||
Number(user.roleXid),
|
||||
search,
|
||||
userStatus,
|
||||
paginationOptions
|
||||
);
|
||||
|
||||
// Create paginated response
|
||||
const paginatedResponse = paginationService.createPaginatedResponse(
|
||||
data,
|
||||
totalCount,
|
||||
paginationOptions
|
||||
);
|
||||
|
||||
return {
|
||||
statusCode: 200,
|
||||
@@ -52,7 +68,7 @@ export const handler = safeHandler(async (
|
||||
body: JSON.stringify({
|
||||
success: true,
|
||||
message: 'Host applications retrieved successfully',
|
||||
data: hostApplications,
|
||||
...paginatedResponse,
|
||||
}),
|
||||
};
|
||||
});
|
||||
});
|
||||
@@ -26,6 +26,7 @@ import { CreateMinglarDto, UpdateMinglarDto } from '../dto/minglar.dto';
|
||||
import { sendAMEmailForHostAssign } from './AMEmail.service';
|
||||
import { getPresignedUrl } from '@/common/middlewares/aws/getPreSignedUrl';
|
||||
import config from '@/config/config';
|
||||
import { PaginationOptions } from '@/common/utils/pagination/pagination.types';
|
||||
|
||||
@Injectable()
|
||||
export class MinglarService {
|
||||
@@ -636,11 +637,13 @@ export class MinglarService {
|
||||
});
|
||||
}
|
||||
|
||||
// Update your MinglarService method
|
||||
async getAllHostApplications(
|
||||
userId: number,
|
||||
userRoleXid: number,
|
||||
search?: string,
|
||||
userStatus?: string,
|
||||
paginationOptions?: PaginationOptions,
|
||||
) {
|
||||
const filters: any = {
|
||||
isActive: true,
|
||||
@@ -693,7 +696,14 @@ export class MinglarService {
|
||||
}
|
||||
|
||||
/** -----------------------------------
|
||||
* MAIN QUERY
|
||||
* COUNT TOTAL RECORDS
|
||||
* ----------------------------------- */
|
||||
const totalCount = await this.prisma.hostHeader.count({
|
||||
where: filters,
|
||||
});
|
||||
|
||||
/** -----------------------------------
|
||||
* MAIN QUERY WITH PAGINATION
|
||||
* ----------------------------------- */
|
||||
const results = await this.prisma.hostHeader.findMany({
|
||||
where: filters,
|
||||
@@ -732,12 +742,14 @@ export class MinglarService {
|
||||
},
|
||||
},
|
||||
orderBy: { createdAt: 'desc' },
|
||||
skip: paginationOptions?.skip || 0,
|
||||
take: paginationOptions?.limit || 10,
|
||||
});
|
||||
|
||||
/** -----------------------------------
|
||||
* TRANSFORM RESPONSE
|
||||
* ----------------------------------- */
|
||||
return results.map((h) => ({
|
||||
const transformedData = results.map((h) => ({
|
||||
hostId: h.id,
|
||||
host: h.user,
|
||||
hostStatusDisplay: h.hostStatusDisplay,
|
||||
@@ -752,6 +764,11 @@ export class MinglarService {
|
||||
country: h.countries || null,
|
||||
assignedOn: h.assignedOn || null,
|
||||
}));
|
||||
|
||||
return {
|
||||
data: transformedData,
|
||||
totalCount,
|
||||
};
|
||||
}
|
||||
|
||||
async getAllOnboardingHostApplications() {
|
||||
|
||||
Reference in New Issue
Block a user