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 learningObjectRoutes from './routes/learning-objects.js';
|
||||||
|
|
||||||
import studentRoutes from './routes/students.js';
|
import studentRoutes from './routes/students.js';
|
||||||
|
import teacherRoutes from './routes/teachers.js'
|
||||||
import groupRoutes from './routes/groups.js';
|
import groupRoutes from './routes/groups.js';
|
||||||
import submissionRoutes from './routes/submissions.js';
|
import submissionRoutes from './routes/submissions.js';
|
||||||
import classRoutes from './routes/classes.js';
|
import classRoutes from './routes/classes.js';
|
||||||
|
@ -16,6 +17,8 @@ const app: Express = express();
|
||||||
const port: string | number = getNumericEnvVar(EnvVars.Port);
|
const port: string | number = getNumericEnvVar(EnvVars.Port);
|
||||||
|
|
||||||
|
|
||||||
|
app.use(express.json());
|
||||||
|
|
||||||
// TODO Replace with Express routes
|
// TODO Replace with Express routes
|
||||||
app.get('/', (_, res: Response) => {
|
app.get('/', (_, res: Response) => {
|
||||||
res.json({
|
res.json({
|
||||||
|
@ -24,6 +27,7 @@ app.get('/', (_, res: Response) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
app.use('/student', studentRoutes);
|
app.use('/student', studentRoutes);
|
||||||
|
app.use('/teacher', teacherRoutes);
|
||||||
app.use('/group', groupRoutes);
|
app.use('/group', groupRoutes);
|
||||||
app.use('/submission', submissionRoutes);
|
app.use('/submission', submissionRoutes);
|
||||||
app.use('/class', classRoutes);
|
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> {
|
public findByUsername(username: string): Promise<Teacher | null> {
|
||||||
return this.findOne({ username: username });
|
return this.findOne({ username: username });
|
||||||
}
|
}
|
||||||
|
public addTeacher(teacher: Teacher): Promise<void> {
|
||||||
|
return this.save(teacher);
|
||||||
|
}
|
||||||
public deleteByUsername(username: string): Promise<void> {
|
public deleteByUsername(username: string): Promise<void> {
|
||||||
return this.deleteWhere({ username: username });
|
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 express from 'express'
|
||||||
|
import {createTeacherHandler, deleteTeacherHandler, getTeacherHandler} from "../controllers/teachers.js";
|
||||||
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('/', getTeacherHandler);
|
||||||
res.json({
|
|
||||||
teachers: [
|
|
||||||
'0',
|
|
||||||
'1',
|
|
||||||
]
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// information about a teacher
|
router.post('/', createTeacherHandler);
|
||||||
router.get('/:id', (req, res) => {
|
|
||||||
res.json({
|
router.delete('/:username', deleteTeacherHandler);
|
||||||
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`,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
})
|
|
||||||
|
|
||||||
// the questions students asked a teacher
|
// the questions students asked a teacher
|
||||||
router.get('/:id/questions', (req, res) => {
|
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;
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue