diff --git a/README.md b/README.md index 85590b9..7c01d4b 100644 --- a/README.md +++ b/README.md @@ -248,7 +248,7 @@ - [x] POST /courses/:courseId/enroll - Enroll to course - [x] POST /enrollments/:enrollmentId/modules/:moduleId/complete - Mark module as completed - [x] POST /enrollments/:enrollmentId/classes/:classId/complete - Mark class as completed -- [ ] POST /enrollments/:enrollmentId/complete - Mark enrollment as completed +- [x] POST /enrollments/:enrollmentId/complete - Mark enrollment as completed - [x] GET /courses/:courseId/students/:studentId/enrollments - Get enrollment of a student on a course - [x] DELETE /enrollments/:enrollmentId - Cancel enrollment diff --git a/src/infra/http/controllers/mark-course-as-completed.ts b/src/infra/http/controllers/mark-course-as-completed.ts new file mode 100644 index 0000000..c158889 --- /dev/null +++ b/src/infra/http/controllers/mark-course-as-completed.ts @@ -0,0 +1,39 @@ +import { NotAllowedError } from '@/core/errors/errors/not-allowed-error' +import { ResourceNotFoundError } from '@/core/errors/errors/resource-not-found-error' +import { AllModulesInTheCourseMustBeMarkedAsCompleted } from '@/domain/course-management/application/use-cases/errors/all-modules-in-the-course-must-be-marked-as-completed' +import { makeMarkCourseAsCompletedUseCase } from '@/infra/use-cases/factories/make-mark-course-as-completed-use-case' +import { type FastifyReply, type FastifyRequest } from 'fastify' +import { z } from 'zod' + +const markCourseAsCompletedParamsSchema = z.object({ + enrollmentId: z.string().uuid() +}) + +export async function markCourseAsCompletedController(request: FastifyRequest, reply: FastifyReply) { + const { enrollmentId } = markCourseAsCompletedParamsSchema.parse(request.params) + const { sub: studentId } = request.user + + const markCourseAsCompletedUseCase = makeMarkCourseAsCompletedUseCase() + + const result = await markCourseAsCompletedUseCase.exec({ + enrollmentId, + studentId + }) + + if (result.isLeft()) { + const error = result.value + + switch (error.constructor) { + case ResourceNotFoundError: + return await reply.status(404).send({ message: error.message }) + case NotAllowedError: + return await reply.status(401).send({ message: error.message }) + case AllModulesInTheCourseMustBeMarkedAsCompleted: + return await reply.status(403).send({ message: error.message }) + default: + return await reply.status(500).send({ message: error.message }) + } + } + + return await reply.status(201).send() +} diff --git a/src/infra/http/routes/enrollment.ts b/src/infra/http/routes/enrollment.ts index 3fd8177..354d076 100644 --- a/src/infra/http/routes/enrollment.ts +++ b/src/infra/http/routes/enrollment.ts @@ -3,6 +3,7 @@ import { cancelEnrollmentController } from '../controllers/cancel-enrollment' import { enrollToCourseController } from '../controllers/enroll-to-course' import { getEnrollmentDetailsController } from '../controllers/get-enrollment-details' import { markClassAsCompletedController } from '../controllers/mark-class-as-completed' +import { markCourseAsCompletedController } from '../controllers/mark-course-as-completed' import { markModuleAsCompletedController } from '../controllers/mark-module-as-completed' import { verifyJwt } from '../middlewares/verify-jwt' import { verifyUserRole } from '../middlewares/verify-user-role' @@ -13,6 +14,7 @@ export async function enrollmentRoutes(app: FastifyInstance) { app.post('/courses/:courseId/enroll', { onRequest: [verifyJwt, verifyUserRole('STUDENT')] }, enrollToCourseController) app.post('/enrollments/:enrollmentId/classes/:classId', { onRequest: [verifyJwt, verifyUserRole('STUDENT')] }, markClassAsCompletedController) app.post('/enrollments/:enrollmentId/modules/:moduleId', { onRequest: [verifyJwt, verifyUserRole('STUDENT')] }, markModuleAsCompletedController) + app.post('/enrollments/:enrollmentId/completed', { onRequest: [verifyJwt, verifyUserRole('STUDENT')] }, markCourseAsCompletedController) app.delete('/enrollments/:enrollmentId', { onRequest: [verifyJwt, verifyUserRole('STUDENT')] }, cancelEnrollmentController) }