Skip to content

Commit

Permalink
#update: thuanvv update registration api
Browse files Browse the repository at this point in the history
  • Loading branch information
vuvanthuan committed Jan 24, 2025
1 parent 35b197a commit a969d25
Show file tree
Hide file tree
Showing 11 changed files with 190 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/application/common/interfaces/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ export * from './core-system-configs-repository';
export * from './student-result-repository';
export * from './activity-class-repository';
export * from './customer-review-repository';
export * from './registration-repository';
3 changes: 3 additions & 0 deletions src/application/common/interfaces/registration-repository.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export interface RegistrationsRepository {
create(parameters: { full_name: string, phone_number: string, email: string, is_learn: number, type_class: number }): Promise<{ id: number } | null>;
}
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { ValidationException } from '@application/common/exceptions';
import { ZodError, z } from 'zod';

import { CreateRegistrationQuery } from './create-registration-query';

export async function validate(query: CreateRegistrationQuery) {
try {
const schema: z.ZodType<CreateRegistrationQuery> = z.object({
full_name: z.string(),
phone_number: z.string(),
email: z.string(),
is_learn: z.number(),
type_class: z.number()
});

await schema.parseAsync(query);
} catch (error) {
throw new ValidationException(error as ZodError);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { validate } from "./create-registration-query-validator";

export type CreateRegistrationQuery = Readonly<{
full_name: string,
phone_number: string,
email: string,
is_learn: number,
type_class: number
}>;

export function makeCreateRegistrationQuery({ registrationRepository }: Pick<Dependencies, 'registrationRepository'>) {
return async function listPagesQuery(query: CreateRegistrationQuery) {
await validate(query);

const { full_name, phone_number, email, is_learn, type_class } = query;

const registration = await registrationRepository.create({ full_name, phone_number, email, is_learn, type_class });

return registration;
};
}
9 changes: 9 additions & 0 deletions src/application/registration/queires/create/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { makeCreateRegistrationQuery } from "./create-registration-query";

export function makeRegistrationsUseCases(dependencies: Dependencies) {
return {
queries: {
create: makeCreateRegistrationQuery(dependencies),
},
};
}
29 changes: 29 additions & 0 deletions src/domain/entities/registration.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
export class RegistrationEntity {
public id?: bigint;
public full_name: string;
public phone_number: string;
public is_learn?: number | null;
public type_class?: number | null;
public created_at?: Date | null;
public updated_at?: Date | null;

constructor(registrationEntity: {
id?: bigint;
full_name: string;
phone_number: string;
is_learn?: number | null;
type_class?: number | null;
created_at?: Date | null;
updated_at?: Date | null;
created_by?: string | null;
updated_by?: string | null;
}) {
this.id = registrationEntity.id;
this.full_name = registrationEntity.full_name;
this.phone_number = registrationEntity.phone_number;
this.is_learn = registrationEntity.is_learn;
this.type_class = registrationEntity.type_class;
this.created_at = registrationEntity.created_at;
this.updated_at = registrationEntity.updated_at;
}
}
2 changes: 2 additions & 0 deletions src/infrastructure/di.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export type Dependencies = {
activityClassRepository: Interfaces.ActivityClassesRepository,
customerReviewRepository: Interfaces.CustomerReviewsRepository,
studentResultRepository: Interfaces.StudentResultsRepository,
registrationRepository: Interfaces.RegistrationsRepository
};

export function makeInfrastructureDependencies(): {
Expand Down Expand Up @@ -60,5 +61,6 @@ export function makeInfrastructureDependencies(): {
activityClassRepository: asFunction(repositories.makeActivityClassesRepository).singleton(),
customerReviewRepository: asFunction(repositories.makeCustomerReviewsRepository).singleton(),
studentResultRepository: asFunction(repositories.makeStudentResultsRepository).singleton(),
registrationRepository: asFunction(repositories.makeRegistrationsRepository).singleton(),
};
}
1 change: 1 addition & 0 deletions src/infrastructure/repositories/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ export * from './core-system-config-repository';
export * from './activity-classes-repository';
export * from './customer-reviews-repository';
export * from './student-results-repository';
export * from './registration-repository';
28 changes: 28 additions & 0 deletions src/infrastructure/repositories/registration-repository.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { RegistrationsRepository } from '@application/common/interfaces';

export function makeRegistrationsRepository({ db }: Dependencies): RegistrationsRepository {
return {
async create(params: {
full_name: string,
phone_number: string,
email: string,
is_learn: number,
type_class: number,
}) {
const newRegistration = await db.registration.create({
data: {
full_name: params.full_name,
phone_number: params.phone_number,
email: params.email,
is_learn: params.is_learn,
type_class: params.type_class,
},
});

return {
...newRegistration,
id: Number(newRegistration.id),
};
}
};
}
76 changes: 76 additions & 0 deletions src/web/routes/registration.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { FastifyRequest } from 'fastify';

import { makeRegistrationsUseCases } from '@application/registration/queires/create';
import { CreateRegistrationQuery } from '@application/registration/queires/create/create-registration-query';
import ResponseBase from '@application/common/response-base';

export default async function registrationRoutes(fastify: FastifyRouteInstance) {
const registrations = makeRegistrationsUseCases(fastify.diContainer.cradle);

fastify.route({
method: 'POST',
url: '/api/registration',
schema: {
body: {
type: 'object',
properties: {
full_name: { type: 'string', description: 'Full name of student' },
phone_number: { type: 'string', description: 'Phone number of student' },
email: { type: 'string', description: 'Email of student or their parents' },
is_learn: { type: 'number', description: 'Are you learning IELTS before?' },
type_class: { type: 'number', description: 'Do you want the type of classes?' },
},
required: ['full_name', 'phone_number', 'email', 'is_learn', 'type_class'],
},
response: {
200: {
type: 'object',
properties: {
status_code: { type: 'integer', example: 200 },
data: {
type: 'object',
properties: {
id: { type: 'integer' },
},
},
message: { type: 'string', example: 'Class fetched successfully' },
},
},
400: { $ref: 'ExceptionResponse#' },
},
tags: ['registrations'],
},
async handler(
req: FastifyRequest<{ Body: CreateRegistrationQuery }>,
res
) {
try {
const componentsList = await registrations.queries.create({
full_name: req.body.full_name,
phone_number: req.body.phone_number,
email: req.body.email,
is_learn: req.body.is_learn,
type_class: req.body.type_class,
});

const response = ResponseBase.formatBaseResponse(
200,
componentsList,
'Register successfully',
);

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

const errorResponse = ResponseBase.formatBaseResponse(
400,
null,
'Register failed',
);

res.status(400).send(errorResponse);
}
},
});
}

0 comments on commit a969d25

Please sign in to comment.