Skip to content

Commit

Permalink
#fix: thuanvv fix activity-class pagination api
Browse files Browse the repository at this point in the history
  • Loading branch information
vuvanthuan committed Jan 22, 2025
1 parent 4b7dc20 commit c04b222
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 17 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { ValidationException } from '@application/common/exceptions';
import { ZodError, z } from 'zod';

import { ListActivitClassQuery } from './list-activity-class-query';

export async function validate(query: ListActivitClassQuery) {
try {
const schema: z.ZodType<ListActivitClassQuery> = z.object({
language: z.string(),
size: z.number().optional(),
page: z.number().optional()
});

await schema.parseAsync(query);
} catch (error) {
throw new ValidationException(error as ZodError);
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,25 @@
import { ActivityClassDTO } from "@domain/dtos/activity-class";

import { map } from "./list-activity-class-query-mapper";
import { validate } from "./list-activity-class-query-validator";

export type ListActivitClassQuery = Readonly<{
language: string;
size?: number;
page?: number
}>;

export function makeListActivityClassQuery({ activityClassRepository, db }: Pick<Dependencies, 'activityClassRepository' | 'db'>) {
return async function listActivityClassQuery({ language }: ListActivitClassQuery) {
const activityClasses = await activityClassRepository.list({ language });
return async function listActivityClassQuery(query: ListActivitClassQuery) {
await validate(query);

const { language, size, page } = query;

const { data: activityClasses, total } = await activityClassRepository.list({ language, size, page });

const per_page = size;
const current_page = page;
const last_page = total && per_page ? Math.ceil(total / per_page) : 1;

const enrichedActivityClasses = await Promise.all(activityClasses.map(async (activityClass) => {
const classInfo = await db.renamedclass.findUnique({
Expand Down Expand Up @@ -47,6 +59,12 @@ export function makeListActivityClassQuery({ activityClassRepository, db }: Pick
return activityClassDTO;
}));

return enrichedActivityClasses.map((activityClass) => map(activityClass));
return {
data: enrichedActivityClasses.map((activityClass) => map(activityClass)),
total,
per_page,
current_page,
last_page,
}
};
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { ActivityClassEntity } from "@domain/entities/activity-class";

export interface ActivityClassesRepository {
list(params: { language: string }): Promise<Array<ActivityClassEntity>>;
list(params: {
language: string;
size?: number;
page?: number
}): Promise<{ data: Array<ActivityClassEntity>, total: number } | { data: [], total: null }>;
}
25 changes: 19 additions & 6 deletions src/infrastructure/repositories/activity-classes-repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,30 @@ import { ActivityClassesRepository } from "@application/common/interfaces";

export function makeActivityClassesRepository({ db }: Dependencies): ActivityClassesRepository {
return {
async list() {
async list(params: { language: string; size?: number; page?: number }) {
const { size = 10, page = 1 } = params;

const activityClasses = await db.activity_class.findMany({
where: { status: 1 },
orderBy: { order: 'asc' },
skip: (page - 1) * size,
take: size,
});

const total = await db.activity_class.count({
where: {
status: 1,
},
});

return activityClasses.map(activityClass => ({
...activityClass,
id: Number(activityClass.id),
class_id: Number(activityClass.class_id),
}));
return {
data: activityClasses.map(activityClass => ({
...activityClass,
id: Number(activityClass.id),
class_id: Number(activityClass.class_id),
})),
total
}
},
};
}
33 changes: 26 additions & 7 deletions src/web/routes/activity-class.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@ export default async function activityClassRoutes(fastify: FastifyRouteInstance)
type: 'object',
properties: {
language: { type: 'string', description: 'Language code (e.g., vi, en, etc.)' },
size: { type: 'number', description: 'Size number of records (e.g., 10.)' },
page: { type: 'number', description: 'Page number of database (e.g., 1.)' }
},
required: ['language'],
required: ['language', 'size', 'page'],
},
response: {
200: {
Expand Down Expand Up @@ -51,6 +53,10 @@ export default async function activityClassRoutes(fastify: FastifyRouteInstance)
},
},
},
total: { type: 'integer', },
per_page: { type: 'integer', },
current_page: { type: 'integer', },
last_page: { type: 'integer', },
message: { type: 'string', example: 'Activity class fetched successfully' },
},
},
Expand All @@ -63,22 +69,35 @@ export default async function activityClassRoutes(fastify: FastifyRouteInstance)
res
) {
try {
const activtyClassList = await activityClass.queries.listActivityClasses({ language: req.body.language });

const response = ResponseBase.formatBaseResponse(
const { data, total, per_page, current_page, last_page } = await activityClass.queries.listActivityClasses({
language: req.body.language,
size: req.body.size,
page: req.body.page,
});

const response = ResponseBase.formatPaginationResponse(
200,
activtyClassList,
'Activity class fetched successfully',
data,
total ?? 0,
per_page ?? 0,
current_page ?? 0,
last_page ?? 0,
'Activity classes fetched successfully',
);

res.status(200).send(response);
} catch (error) {
fastify.log.error(error);

const errorResponse = ResponseBase.formatBaseResponse(
const errorResponse = ResponseBase.formatPaginationResponse(
400,
null,
'Failed to fetch activity class',
0,
0,
0,
0,
'Failed to fetch activty classes',
);

res.status(400).send(errorResponse);
Expand Down

0 comments on commit c04b222

Please sign in to comment.