/
foult080
/
college-schedule-app
Обзор
Документация
Войти
/
foult080
/
college-schedule-app
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
src/controllers/classrooms.controller.ts
158 строк
6 KB
Foult080
feat(api): update api and tests
06 июл 2026, 12:54
06 июл 2026, 12:54
6f27c7e
Код
Авторство
О чём код?
import { NextFunction, Request, Response } from 'express'; import { DatabaseHelper } from '../utils/database.js'; import { BadRequestError, ConflictError, NotFoundError, } from '../utils/http-errors.js'; import { IClassroom, ICreateClassroomDto, IUpdateClassroomDto } from '../types/types.js'; /** * Get all classrooms * GET /api/classrooms */ export const getAllClassrooms = async (_req: Request, res: Response, next: NextFunction): Promise<void> => { try { const result = await DatabaseHelper.select<IClassroom>('classrooms', ['id', 'room_number', 'building', 'capacity', 'has_projector', 'has_whiteboard']); res.status(200).json(result.rows); } catch (error) { next(error); } }; /** * Get classroom by ID * GET /api/classrooms/:id */ export const getClassroomById = async (req: Request, res: Response, next: NextFunction): Promise<void> => { try { const { id } = req.params; const classroomId = parseInt(id as string, 10); if (isNaN(classroomId) || classroomId <= 0) { throw new BadRequestError('Invalid classroom ID'); } const result = await DatabaseHelper.select<IClassroom>('classrooms', ['id', 'room_number', 'building', 'capacity', 'has_projector', 'has_whiteboard'], { id: classroomId }); if (result.rows.length === 0) { throw new NotFoundError('Classroom not found'); } res.status(200).json(result.rows[0]); } catch (error) { next(error); } }; /** * Create new classroom * POST /api/classrooms */ export const createClassroom = async (req: Request, res: Response, next: NextFunction): Promise<void> => { try { const { room_number, building, capacity, has_projector, has_whiteboard }: ICreateClassroomDto = req.body; // Validation if (!room_number || !building || capacity === undefined) { throw new BadRequestError('Room number, building, and capacity are required'); } if (typeof capacity !== 'number' || capacity <= 0) { throw new BadRequestError('Capacity must be a positive number'); } // Check if classroom with same room_number and building already exists const existingClassroom = (await DatabaseHelper.select('classrooms', ['id'], { room_number, building })).rows[0]; if (existingClassroom) { throw new ConflictError('Classroom with this room number and building already exists'); } const newClassroomData: Record<string, unknown> = { room_number, building, capacity }; if (has_projector !== undefined) newClassroomData.has_projector = has_projector; if (has_whiteboard !== undefined) newClassroomData.has_whiteboard = has_whiteboard; const result = await DatabaseHelper.insert<IClassroom>('classrooms', newClassroomData, ['id', 'room_number', 'building', 'capacity', 'has_projector', 'has_whiteboard']); res.status(201).json(result.rows[0]); } catch (error) { next(error); } }; /** * Update classroom by ID * PUT /api/classrooms/:id */ export const updateClassroom = async (req: Request, res: Response, next: NextFunction): Promise<void> => { try { const { id } = req.params; const { room_number, building, capacity, has_projector, has_whiteboard }: IUpdateClassroomDto = req.body; const classroomId = parseInt(id as string, 10); if (isNaN(classroomId) || classroomId <= 0) { throw new BadRequestError('Invalid classroom ID'); } // Check if classroom exists const existingClassroom = (await DatabaseHelper.select('classrooms', ['id', 'room_number', 'building'], { id: classroomId })).rows[0]; if (!existingClassroom) { throw new NotFoundError('Classroom not found'); } // Validation if (capacity !== undefined && (typeof capacity !== 'number' || capacity <= 0)) { throw new BadRequestError('Capacity must be a positive number'); } // Check if new room_number and building combination already exists (if being changed) if ((room_number && room_number !== existingClassroom.room_number) || (building && building !== existingClassroom.building)) { const newRoomNumber = room_number || existingClassroom.room_number; const newBuilding = building || existingClassroom.building; const exists = (await DatabaseHelper.select('classrooms', ['id'], { room_number: newRoomNumber, building: newBuilding })).rows[0]; if (exists && exists.id !== classroomId) { throw new ConflictError('Classroom with this room number and building already exists'); } } const updateData: Record<string, unknown> = {}; if (room_number !== undefined) updateData.room_number = room_number; if (building !== undefined) updateData.building = building; if (capacity !== undefined) updateData.capacity = capacity; if (has_projector !== undefined) updateData.has_projector = has_projector; if (has_whiteboard !== undefined) updateData.has_whiteboard = has_whiteboard; const result = await DatabaseHelper.update<IClassroom>('classrooms', updateData, { id: classroomId }, ['id', 'room_number', 'building', 'capacity', 'has_projector', 'has_whiteboard']); res.status(200).json(result.rows[0]); } catch (error) { next(error); } }; /** * Delete classroom by ID * DELETE /api/classrooms/:id */ export const deleteClassroom = async (req: Request, res: Response, next: NextFunction): Promise<void> => { try { const { id } = req.params; const classroomId = parseInt(id as string, 10); if (isNaN(classroomId) || classroomId <= 0) { throw new BadRequestError('Invalid classroom ID'); } // Check if classroom exists const existingClassroom = (await DatabaseHelper.select('classrooms', ['id'], { id: classroomId })).rows[0]; if (!existingClassroom) { throw new NotFoundError('Classroom not found'); } await DatabaseHelper.delete('classrooms', { id: classroomId }); res.status(204).send(); } catch (error) { if (error instanceof Error && error.message.includes('foreign key')) { throw new ConflictError('Cannot delete classroom: it is referenced by schedules'); } next(error); } };