From 6b87722469e2afd1671336e4c988690fcdf6ce57 Mon Sep 17 00:00:00 2001 From: Gabriellvl Date: Fri, 7 Mar 2025 20:05:16 +0100 Subject: [PATCH] feat: teacher get, post en delete route --- backend/src/app.ts | 4 + backend/src/controllers/teachers.ts | 79 ++++++++++++++++++++ backend/src/data/users/teacher-repository.ts | 3 + backend/src/interfaces/teacher.ts | 36 +++++++++ backend/src/routes/teachers.ts | 30 ++------ backend/src/services/teachers.ts | 38 ++++++++++ 6 files changed, 166 insertions(+), 24 deletions(-) create mode 100644 backend/src/controllers/teachers.ts create mode 100644 backend/src/interfaces/teacher.ts create mode 100644 backend/src/services/teachers.ts diff --git a/backend/src/app.ts b/backend/src/app.ts index 811c6cfc..f28604c0 100644 --- a/backend/src/app.ts +++ b/backend/src/app.ts @@ -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); diff --git a/backend/src/controllers/teachers.ts b/backend/src/controllers/teachers.ts new file mode 100644 index 00000000..d4baef2f --- /dev/null +++ b/backend/src/controllers/teachers.ts @@ -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 { + 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 { + 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 { + 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' }); + } +} diff --git a/backend/src/data/users/teacher-repository.ts b/backend/src/data/users/teacher-repository.ts index 704ef409..43602ff7 100644 --- a/backend/src/data/users/teacher-repository.ts +++ b/backend/src/data/users/teacher-repository.ts @@ -5,6 +5,9 @@ export class TeacherRepository extends DwengoEntityRepository { public findByUsername(username: string): Promise { return this.findOne({ username: username }); } + public addTeacher(teacher: Teacher): Promise { + return this.save(teacher); + } public deleteByUsername(username: string): Promise { return this.deleteWhere({ username: username }); } diff --git a/backend/src/interfaces/teacher.ts b/backend/src/interfaces/teacher.ts new file mode 100644 index 00000000..15c89520 --- /dev/null +++ b/backend/src/interfaces/teacher.ts @@ -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; +} diff --git a/backend/src/routes/teachers.ts b/backend/src/routes/teachers.ts index 37b3b04b..dab98dea 100644 --- a/backend/src/routes/teachers.ts +++ b/backend/src/routes/teachers.ts @@ -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) => { @@ -55,4 +37,4 @@ router.get('/:id/classes', (req, res) => { }); -export default router \ No newline at end of file +export default router diff --git a/backend/src/services/teachers.ts b/backend/src/services/teachers.ts new file mode 100644 index 00000000..5572d4b0 --- /dev/null +++ b/backend/src/services/teachers.ts @@ -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 { + const teacherRepository = getTeacherRepository(); + const teachers = await teacherRepository.find({}); + + return teachers.map(mapToTeacherDTO); +} + +export async function createTeacher(teacherData: TeacherDTO): Promise { + const teacherRepository = getTeacherRepository(); + const newTeacher = mapToTeacher(teacherData); + + await teacherRepository.addTeacher(newTeacher); + return newTeacher; +} + +export async function fetchTeacherByUsername(username: string): Promise { + const teacherRepository = getTeacherRepository(); + const teacher = await teacherRepository.findByUsername(username); + + return teacher ? mapToTeacherDTO(teacher) : null; +} + +export async function deleteTeacher(username: string): Promise { + const teacherRepository = getTeacherRepository(); + const teacher = await teacherRepository.findByUsername(username); + + if (!teacher) + return null; + + await teacherRepository.deleteByUsername(username); + return teacher; +} +