feat: controller en service laag toegevoegd voor student/:id/classes
This commit is contained in:
		
							parent
							
								
									f5b6a5a604
								
							
						
					
					
						commit
						ceef74f1af
					
				
					 6 changed files with 127 additions and 23 deletions
				
			
		|  | @ -1,13 +1,31 @@ | ||||||
| import { Request, Response } from 'express'; | import { Request, Response } from 'express'; | ||||||
| import { getStudentById } from "../services/students"; | import { getStudent, getStudentClasses, getStudentClassIds } from '../services/students'; | ||||||
|  | import { ClassDTO } from '../interfaces/classes'; | ||||||
| 
 | 
 | ||||||
| export async function getStudent( | export async function getAllStudentsHandler ( | ||||||
|  |     req: Request, | ||||||
|  |     res: Response, | ||||||
|  | ): Promise<void> { | ||||||
|  |     try { | ||||||
|  |         res.json({ | ||||||
|  |             students: [ | ||||||
|  |                 '0', | ||||||
|  |                 '1', | ||||||
|  |             ] | ||||||
|  |         }); | ||||||
|  |     } catch (error) { | ||||||
|  |         console.error('Error fetching learning objects:', error); | ||||||
|  |         res.status(500).json({ error: 'Internal server error' }); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export async function getStudentHandler( | ||||||
|     req: Request, |     req: Request, | ||||||
|     res: Response, |     res: Response, | ||||||
| ): Promise<void> { | ): Promise<void> { | ||||||
|     try { |     try { | ||||||
|         const username = req.params.id; |         const username = req.params.id; | ||||||
|         const student = await getStudentById(username); |         const student = await getStudent(username); | ||||||
|      |      | ||||||
|         if (!student) { |         if (!student) { | ||||||
|             res.status(404).json({ error: "Student not found" }); |             res.status(404).json({ error: "Student not found" }); | ||||||
|  | @ -21,7 +39,34 @@ export async function getStudent( | ||||||
|             } |             } | ||||||
|             res.json(student); |             res.json(student); | ||||||
|         } |         } | ||||||
|          | 
 | ||||||
|  |     } catch (error) { | ||||||
|  |         console.error('Error fetching learning objects:', error); | ||||||
|  |         res.status(500).json({ error: 'Internal server error' }); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export async function getStudentClassesHandler ( | ||||||
|  |     req: Request, | ||||||
|  |     res: Response, | ||||||
|  | ): Promise<void> { | ||||||
|  |     try { | ||||||
|  |         const full = req.query.full === 'true'; | ||||||
|  |         const username = req.params.id; | ||||||
|  | 
 | ||||||
|  |         let classes: ClassDTO[] | string[]; | ||||||
|  |         if (full) classes = await getStudentClasses(username); | ||||||
|  |         else classes = await getStudentClassIds(username); | ||||||
|  | 
 | ||||||
|  |         res.json({ | ||||||
|  |             classes: classes, | ||||||
|  |             endpoints: { | ||||||
|  |                 self: `${req.baseUrl}/${req.params.id}`, | ||||||
|  |                 classes: `${req.baseUrl}/${req.params.id}/invitations`, | ||||||
|  |                 questions: `${req.baseUrl}/${req.params.id}/assignments`, | ||||||
|  |                 students: `${req.baseUrl}/${req.params.id}/students`, | ||||||
|  |             } | ||||||
|  |         }); | ||||||
|     } catch (error) { |     } catch (error) { | ||||||
|         console.error('Error fetching learning objects:', error); |         console.error('Error fetching learning objects:', error); | ||||||
|         res.status(500).json({ error: 'Internal server error' }); |         res.status(500).json({ error: 'Internal server error' }); | ||||||
|  |  | ||||||
|  | @ -1,5 +1,6 @@ | ||||||
| import { DwengoEntityRepository } from '../dwengo-entity-repository.js'; | import { DwengoEntityRepository } from '../dwengo-entity-repository.js'; | ||||||
| import { Class } from '../../entities/classes/class.entity.js'; | import { Class } from '../../entities/classes/class.entity.js'; | ||||||
|  | import { Student } from '../../entities/users/student.entity.js'; | ||||||
| 
 | 
 | ||||||
| export class ClassRepository extends DwengoEntityRepository<Class> { | export class ClassRepository extends DwengoEntityRepository<Class> { | ||||||
|     public findById(id: string): Promise<Class | null> { |     public findById(id: string): Promise<Class | null> { | ||||||
|  | @ -8,4 +9,10 @@ export class ClassRepository extends DwengoEntityRepository<Class> { | ||||||
|     public deleteById(id: string): Promise<void> { |     public deleteById(id: string): Promise<void> { | ||||||
|         return this.deleteWhere({ classId: id }); |         return this.deleteWhere({ classId: id }); | ||||||
|     } |     } | ||||||
|  |     public findByStudent(student: Student): Promise<Class[]> { | ||||||
|  |         return this.find( | ||||||
|  |             { students: student }, | ||||||
|  |             { populate: ["students", "teachers"] } // voegt student en teacher objecten toe
 | ||||||
|  |         ) | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
							
								
								
									
										17
									
								
								backend/src/interfaces/classes.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								backend/src/interfaces/classes.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,17 @@ | ||||||
|  | import { ClassJoinRequest } from "../entities/classes/class-join-request.entity"; | ||||||
|  | import { Student } from "../entities/users/student.entity"; | ||||||
|  | import { Teacher } from "../entities/users/teacher.entity"; | ||||||
|  | 
 | ||||||
|  | export interface ClassDTO { | ||||||
|  |     id: string; | ||||||
|  |     displayName: string; | ||||||
|  |     teachers: string[]; | ||||||
|  |     students: string[]; | ||||||
|  |     joinRequests: string[]; | ||||||
|  |     endpoints?: { | ||||||
|  |         classes: string; | ||||||
|  |         questions: string; | ||||||
|  |         invitations: string; | ||||||
|  |         groups: string; | ||||||
|  |     }; | ||||||
|  | } | ||||||
|  | @ -19,7 +19,7 @@ router.get('/:id', (req, res) => { | ||||||
|         teachers: [ '0' ], |         teachers: [ '0' ], | ||||||
|         students: [ '0' ], |         students: [ '0' ], | ||||||
|         joinRequests: [ '0' ], |         joinRequests: [ '0' ], | ||||||
|         links: { |         endpoints: { | ||||||
|             self: `${req.baseUrl}/${req.params.id}`, |             self: `${req.baseUrl}/${req.params.id}`, | ||||||
|             classes: `${req.baseUrl}/${req.params.id}/invitations`, |             classes: `${req.baseUrl}/${req.params.id}/invitations`, | ||||||
|             questions: `${req.baseUrl}/${req.params.id}/assignments`, |             questions: `${req.baseUrl}/${req.params.id}/assignments`, | ||||||
|  |  | ||||||
|  | @ -1,27 +1,15 @@ | ||||||
| import express from 'express' | import express from 'express' | ||||||
| import { getStudentById } from '../services/students'; | import { getAllStudentsHandler, getStudentClassesHandler, getStudentHandler } from '../controllers/students'; | ||||||
| import { getStudent } from '../controllers/students'; |  | ||||||
| const router = express.Router(); | const router = express.Router(); | ||||||
| 
 | 
 | ||||||
| // root endpoint used to search objects
 | // root endpoint used to search objects
 | ||||||
| router.get('/', (req, res) => { | router.get('/', getAllStudentsHandler); | ||||||
|     res.json({ |  | ||||||
|         students: [ |  | ||||||
|             '0', |  | ||||||
|             '1', |  | ||||||
|         ] |  | ||||||
|     }); |  | ||||||
| }); |  | ||||||
| 
 | 
 | ||||||
| // information about a student's profile
 | // information about a student's profile
 | ||||||
| router.get('/:id', getStudent); | router.get('/:id', getStudentHandler); | ||||||
| 
 | 
 | ||||||
| // the list of classes a student is in
 | // the list of classes a student is in
 | ||||||
| router.get('/:id/classes', (req, res) => { | router.get('/:id/classes', getStudentClassesHandler); | ||||||
|     res.json({ |  | ||||||
|         classes: [ '0' ], |  | ||||||
|     }); |  | ||||||
| }) |  | ||||||
| 
 | 
 | ||||||
| // the list of submissions a student has made
 | // the list of submissions a student has made
 | ||||||
| router.get('/:id/submissions', (req, res) => { | router.get('/:id/submissions', (req, res) => { | ||||||
|  |  | ||||||
|  | @ -1,7 +1,14 @@ | ||||||
| import { getStudentRepository } from "../data/repositories"; | import { getClassRepository, getStudentRepository } from "../data/repositories"; | ||||||
|  | import { Class } from "../entities/classes/class.entity"; | ||||||
|  | import { ClassDTO } from "../interfaces/classes"; | ||||||
| import { StudentDTO } from "../interfaces/students"; | import { StudentDTO } from "../interfaces/students"; | ||||||
| 
 | 
 | ||||||
| export async function getStudentById(username: string): Promise<StudentDTO | null> { | export async function getAllStudents(): Promise<StudentDTO[]> { | ||||||
|  |     // TODO
 | ||||||
|  |     return []; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export async function getStudent(username: string): Promise<StudentDTO | null> { | ||||||
|     const studentRepository = getStudentRepository(); |     const studentRepository = getStudentRepository(); | ||||||
|     const student = await studentRepository.findByUsername(username); |     const student = await studentRepository.findByUsername(username); | ||||||
| 
 | 
 | ||||||
|  | @ -16,3 +23,43 @@ export async function getStudentById(username: string): Promise<StudentDTO | nul | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | async function fetchStudentClasses(username: string): Promise<Class[]> { | ||||||
|  |     const studentRepository = getStudentRepository(); | ||||||
|  |     const student = await studentRepository.findByUsername(username); | ||||||
|  | 
 | ||||||
|  |     if (!student) return []; | ||||||
|  | 
 | ||||||
|  |     const classRepository = getClassRepository(); | ||||||
|  |     // a weird error when running npm run dev occurs when using .findByStudent
 | ||||||
|  |     // the error says that the function could not be found which is weird
 | ||||||
|  |     // because typescript does not throw any errors
 | ||||||
|  |     const classes = await classRepository.find( | ||||||
|  |         { students: student }, | ||||||
|  |         { populate: ["students", "teachers"] } // voegt student en teacher objecten toe
 | ||||||
|  |     ) | ||||||
|  |     // const classes = await classRepository.findByStudent(student);
 | ||||||
|  | 
 | ||||||
|  |     if (!classes) return []; | ||||||
|  | 
 | ||||||
|  |     return classes; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export async function getStudentClasses(username: string): Promise<ClassDTO[]> { | ||||||
|  |     const classes = await fetchStudentClasses(username); | ||||||
|  | 
 | ||||||
|  |     return classes.map((cls: Class): ClassDTO => { | ||||||
|  |         return { | ||||||
|  |             id: cls.classId, | ||||||
|  |             displayName: cls.displayName, | ||||||
|  |             teachers: cls.teachers.map(teacher => teacher.username), | ||||||
|  |             students: cls.students.map(student => student.username), | ||||||
|  |             joinRequests: [], // TODO
 | ||||||
|  |         } | ||||||
|  |     }); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export async function getStudentClassIds(username: string): Promise<string[]> { | ||||||
|  |     const classes = await fetchStudentClasses(username); | ||||||
|  |     return classes.map(cls => cls.classId); // class is a native keyword
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  |  | ||||||
		Reference in a new issue
	
	 Adriaan Jacquet
						Adriaan Jacquet