feat: teacher get, post en delete route
This commit is contained in:
		
							parent
							
								
									b8db32161f
								
							
						
					
					
						commit
						6b87722469
					
				
					 6 changed files with 166 additions and 24 deletions
				
			
		|  | @ -7,6 +7,7 @@ import learningPathRoutes from './routes/learning-paths.js'; | |||
| import learningObjectRoutes from './routes/learning-objects.js'; | ||||
| 
 | ||||
| import studentRoutes from './routes/students.js'; | ||||
| import teacherRoutes from './routes/teachers.js' | ||||
| import groupRoutes from './routes/groups.js'; | ||||
| import submissionRoutes from './routes/submissions.js'; | ||||
| import classRoutes from './routes/classes.js'; | ||||
|  | @ -16,6 +17,8 @@ const app: Express = express(); | |||
| const port: string | number = getNumericEnvVar(EnvVars.Port); | ||||
| 
 | ||||
| 
 | ||||
| app.use(express.json()); | ||||
| 
 | ||||
| // TODO Replace with Express routes
 | ||||
| app.get('/', (_, res: Response) => { | ||||
|     res.json({ | ||||
|  | @ -24,6 +27,7 @@ app.get('/', (_, res: Response) => { | |||
| }); | ||||
| 
 | ||||
| app.use('/student', studentRoutes); | ||||
| app.use('/teacher', teacherRoutes); | ||||
| app.use('/group', groupRoutes); | ||||
| app.use('/submission', submissionRoutes); | ||||
| app.use('/class', classRoutes); | ||||
|  |  | |||
							
								
								
									
										79
									
								
								backend/src/controllers/teachers.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								backend/src/controllers/teachers.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,79 @@ | |||
| import { Request, Response } from 'express'; | ||||
| import { | ||||
|     createTeacher, deleteTeacher, | ||||
|     fetchAllTeachers, fetchTeacherByUsername | ||||
| } from '../services/teachers.js'; | ||||
| import {TeacherDTO} from "../interfaces/teacher"; | ||||
| 
 | ||||
| export async function getTeacherHandler(req: Request, res: Response): Promise<void> { | ||||
|     try { | ||||
|         const full = req.query.full === 'true'; | ||||
|         const username = req.query.username as string; | ||||
| 
 | ||||
|         if (username){ | ||||
|             const teacher = await fetchTeacherByUsername(username); | ||||
|             if (!teacher){ | ||||
|                 res.status(404).json({ error: `Teacher with username '${username}' not found.` }); | ||||
|                 return; | ||||
|             } | ||||
|             res.json(teacher); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         let teachers: TeacherDTO[] | string[] = await fetchAllTeachers(); | ||||
| 
 | ||||
|         if (!full) | ||||
|             teachers = teachers.map((teacher) => teacher.username) | ||||
| 
 | ||||
|         res.json(teachers); | ||||
|     } catch (error) { | ||||
|         console.error("❌ Error fetching teachers:", error); | ||||
|         res.status(500).json({ error: "Internal server error" }); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| export async function createTeacherHandler( | ||||
|     req: Request, | ||||
|     res: Response | ||||
| ): Promise<void> { | ||||
|     try { | ||||
|         const teacherData = req.body as TeacherDTO; | ||||
| 
 | ||||
|         if (!teacherData.username || !teacherData.firstName || !teacherData.lastName) { | ||||
|             res.status(400).json({ error: 'Missing required fields: username, firstName, lastName' }); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         const newTeacher = await createTeacher(teacherData); | ||||
|         res.status(201).json(newTeacher); | ||||
|     } catch (error) { | ||||
|         console.error('Error creating teacher:', error); | ||||
|         res.status(500).json({ error: 'Internal server error' }); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| export async function deleteTeacherHandler( | ||||
|     req: Request, | ||||
|     res: Response | ||||
| ): Promise<void> { | ||||
|     try { | ||||
|         const username = req.params.username as string; | ||||
| 
 | ||||
|         if (!username) { | ||||
|             res.status(400).json({ error: 'Missing required field: username' }); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         const deletedTeacher = await deleteTeacher(username); | ||||
| 
 | ||||
|         if (!deletedTeacher) { | ||||
|             res.status(400).json({ error: `Did not find teacher with username ${username}` }); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         res.status(201).json(deletedTeacher); | ||||
|     } catch (error) { | ||||
|         console.error('Error deleting teacher:', error); | ||||
|         res.status(500).json({ error: 'Internal server error' }); | ||||
|     } | ||||
| } | ||||
|  | @ -5,6 +5,9 @@ export class TeacherRepository extends DwengoEntityRepository<Teacher> { | |||
|     public findByUsername(username: string): Promise<Teacher | null> { | ||||
|         return this.findOne({ username: username }); | ||||
|     } | ||||
|     public addTeacher(teacher: Teacher): Promise<void> { | ||||
|         return this.save(teacher); | ||||
|     } | ||||
|     public deleteByUsername(username: string): Promise<void> { | ||||
|         return this.deleteWhere({ username: username }); | ||||
|     } | ||||
|  |  | |||
							
								
								
									
										36
									
								
								backend/src/interfaces/teacher.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								backend/src/interfaces/teacher.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,36 @@ | |||
| import { Teacher } from "../entities/users/teacher.entity.js"; | ||||
| 
 | ||||
| /** | ||||
|  * Teacher Data Transfer Object | ||||
|  */ | ||||
| export interface TeacherDTO { | ||||
|     username: string; | ||||
|     firstName: string; | ||||
|     lastName: string; | ||||
|     endpoints?: { | ||||
|         self: string; | ||||
|         classes: string; | ||||
|         questions: string; | ||||
|         invitations: string; | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  * Maps a Teacher entity to a TeacherDTO | ||||
|  */ | ||||
| export function mapToTeacherDTO(teacher: Teacher): TeacherDTO { | ||||
|     return { | ||||
|         username: teacher.username, | ||||
|         firstName: teacher.firstName, | ||||
|         lastName: teacher.lastName, | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| export function mapToTeacher(teacherData: TeacherDTO): Teacher { | ||||
|     const teacher = new Teacher(); | ||||
|     teacher.username = teacherData.username; | ||||
|     teacher.firstName = teacherData.firstName; | ||||
|     teacher.lastName = teacherData.lastName; | ||||
| 
 | ||||
|     return teacher; | ||||
| } | ||||
|  | @ -1,31 +1,13 @@ | |||
| import express from 'express' | ||||
| import {createTeacherHandler, deleteTeacherHandler, getTeacherHandler} from "../controllers/teachers.js"; | ||||
| const router = express.Router(); | ||||
| 
 | ||||
| // root endpoint used to search objects
 | ||||
| router.get('/', (req, res) => { | ||||
|     res.json({ | ||||
|         teachers: [ | ||||
|             '0', | ||||
|             '1', | ||||
|         ] | ||||
|     }); | ||||
| }); | ||||
| router.get('/', getTeacherHandler); | ||||
| 
 | ||||
| // information about a teacher
 | ||||
| router.get('/:id', (req, res) => { | ||||
|     res.json({ | ||||
|         id: req.params.id, | ||||
|         firstName: 'John', | ||||
|         lastName: 'Doe', | ||||
|         username: 'JohnDoe1', | ||||
|         links: { | ||||
|             self: `${req.baseUrl}/${req.params.id}`, | ||||
|             classes: `${req.baseUrl}/${req.params.id}/classes`, | ||||
|             questions: `${req.baseUrl}/${req.params.id}/questions`, | ||||
|             invitations: `${req.baseUrl}/${req.params.id}/invitations`, | ||||
|         }, | ||||
|     }); | ||||
| }) | ||||
| router.post('/', createTeacherHandler); | ||||
| 
 | ||||
| router.delete('/:username', deleteTeacherHandler); | ||||
| 
 | ||||
| // the questions students asked a teacher
 | ||||
| router.get('/:id/questions', (req, res) => { | ||||
|  |  | |||
							
								
								
									
										38
									
								
								backend/src/services/teachers.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								backend/src/services/teachers.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,38 @@ | |||
| import {getTeacherRepository} from "../data/repositories.js"; | ||||
| import {mapToTeacher, mapToTeacherDTO, TeacherDTO} from "../interfaces/teacher.js"; | ||||
| import { Teacher } from "../entities/users/teacher.entity"; | ||||
| 
 | ||||
| 
 | ||||
| export async function fetchAllTeachers(): Promise<TeacherDTO[]> { | ||||
|     const teacherRepository = getTeacherRepository(); | ||||
|     const teachers = await teacherRepository.find({}); | ||||
| 
 | ||||
|     return teachers.map(mapToTeacherDTO); | ||||
| } | ||||
| 
 | ||||
| export async function createTeacher(teacherData: TeacherDTO): Promise<Teacher> { | ||||
|     const teacherRepository = getTeacherRepository(); | ||||
|     const newTeacher = mapToTeacher(teacherData); | ||||
| 
 | ||||
|     await teacherRepository.addTeacher(newTeacher); | ||||
|     return newTeacher; | ||||
| } | ||||
| 
 | ||||
| export async function fetchTeacherByUsername(username: string): Promise<TeacherDTO | null> { | ||||
|     const teacherRepository = getTeacherRepository(); | ||||
|     const teacher = await teacherRepository.findByUsername(username); | ||||
| 
 | ||||
|     return teacher ? mapToTeacherDTO(teacher) : null; | ||||
| } | ||||
| 
 | ||||
| export async function deleteTeacher(username: string): Promise<TeacherDTO | null> { | ||||
|     const teacherRepository = getTeacherRepository(); | ||||
|     const teacher = await teacherRepository.findByUsername(username); | ||||
| 
 | ||||
|     if (!teacher) | ||||
|         return null; | ||||
| 
 | ||||
|     await teacherRepository.deleteByUsername(username); | ||||
|     return teacher; | ||||
| } | ||||
| 
 | ||||
		Reference in a new issue
	
	 Gabriellvl
						Gabriellvl