Skip to content

Commit

Permalink
Feat(Student, Enrollment, Route): Fetch student courses route
Browse files Browse the repository at this point in the history
  • Loading branch information
Artur-Poffo committed Feb 23, 2024
1 parent fabc655 commit 67a2bf7
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 1 deletion.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@

### Students
- [x] GET /courses/:courseId/students - Get students enrolled in course
- [ ] GET /students/:studentId/enrollments - Get student courses with instructor and evaluations
- [x] GET /students/:studentId/enrollments - Get student courses with instructor and evaluations

### Instructors
- [ ] GET /courses/:courseId/instructor - Get course instructor details
Expand Down
2 changes: 2 additions & 0 deletions src/infra/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { evaluationRoutes } from './http/routes/evaluation'
import { fileRoutes } from './http/routes/file'
import { imageRoutes } from './http/routes/image'
import { moduleRoutes } from './http/routes/module'
import { studentRoutes } from './http/routes/student'
import { studentCertificateRoutes } from './http/routes/student-certificate'
import { tagRoutes } from './http/routes/tag'
import { userRoutes } from './http/routes/user'
Expand Down Expand Up @@ -53,6 +54,7 @@ app.register(multer.contentParser)
// API Routes

app.register(userRoutes)
app.register(studentRoutes)
app.register(courseRoutes)
app.register(fileRoutes)
app.register(imageRoutes)
Expand Down
93 changes: 93 additions & 0 deletions src/infra/http/controllers/fetch-student-courses.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import { ResourceNotFoundError } from '@/core/errors/errors/resource-not-found-error'
import { type CourseWithInstructorAndEvaluationDTO } from '@/domain/course-management/enterprise/entities/dtos/course-with-instructor-and-evaluation'
import { CourseDtoMapper } from '@/domain/course-management/enterprise/entities/dtos/mappers/course-dto-mapper'
import { makeGetCourseEvaluationsAverageUseCase } from '@/infra/use-cases/factories/make-get-course-evaluations-average-use-case'
import { makeGetStudentWithCoursesUseCase } from '@/infra/use-cases/factories/make-get-student-with-courses-use-case'
import { makeGetUserInfoUseCase } from '@/infra/use-cases/factories/make-get-user-info-use-case'
import { type FastifyReply, type FastifyRequest } from 'fastify'
import { z } from 'zod'
import { CoursesWithInstructorAndEvaluationPresenter } from '../presenters/courses-with-instructor-and-evaluation-presenter'

const fetchStudentCoursesParamsSchema = z.object({
studentId: z.string().uuid()
})

export async function fetchStudentCoursesController(request: FastifyRequest, reply: FastifyReply) {
const { studentId } = fetchStudentCoursesParamsSchema.parse(request.params)

const fetchStudentCoursesUseCase = makeGetStudentWithCoursesUseCase()
const getUserInfoUseCase = makeGetUserInfoUseCase()
const getCourseEvaluationsAverageUseCase = makeGetCourseEvaluationsAverageUseCase()

const result = await fetchStudentCoursesUseCase.exec({
studentId
})

if (result.isLeft()) {
const error = result.value

switch (error.constructor) {
case ResourceNotFoundError:
return await reply.status(404).send({ message: error.message })
default:
return await reply.status(500).send({ message: error.message })
}
}

const courses = result.value.studentWithCourses.courses

const coursesWithInstructorAndEvaluation: CourseWithInstructorAndEvaluationDTO[] = []

await Promise.all(
courses.map(async (course) => {
const instructorResult = await getUserInfoUseCase.exec({
id: course.instructorId.toString()
})
const courseEvaluationAverageResult = await getCourseEvaluationsAverageUseCase.exec({
courseId: course.id.toString()
})

if (instructorResult.isLeft()) {
const error = instructorResult.value

switch (error.constructor) {
case ResourceNotFoundError:
return await reply.status(404).send({ message: error.message })
default:
return await reply.status(500).send({ message: error.message })
}
}

if (courseEvaluationAverageResult.isLeft()) {
return await reply.status(500).send()
}

const { user } = instructorResult.value
const { evaluationsAverage } = courseEvaluationAverageResult.value

const courseWithInstructorAndEvaluation: CourseWithInstructorAndEvaluationDTO = {
course: CourseDtoMapper.toDTO(course),
instructor: {
id: user.id,
name: user.name,
email: user.email,
age: user.age,
registeredAt: user.registeredAt,
summary: user.summary,
bannerImageKey: user.bannerImageKey,
profileImageKey: user.profileImageKey
},
evaluationsAverage
}

coursesWithInstructorAndEvaluation.push(courseWithInstructorAndEvaluation)
})
)

return await reply.status(200).send({
courses: coursesWithInstructorAndEvaluation.map(courseWithInstructorAndEvaluation =>
CoursesWithInstructorAndEvaluationPresenter.toHTTP(courseWithInstructorAndEvaluation
)
)
})
}
7 changes: 7 additions & 0 deletions src/infra/http/routes/student.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { type FastifyInstance } from 'fastify'
import { fetchStudentCoursesController } from '../controllers/fetch-student-courses'
import { verifyJwt } from '../middlewares/verify-jwt'

export async function studentRoutes(app: FastifyInstance) {
app.get('/students/:studentId/enrollments', { onRequest: [verifyJwt] }, fetchStudentCoursesController)
}

0 comments on commit 67a2bf7

Please sign in to comment.