/
foult080
/
college-schedule-app
Обзор
Документация
Войти
/
foult080
/
college-schedule-app
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
src/controllers/courses.controller.ts
140 строк
4 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 { ICourse } from '../types/types.js'; import { CreateCourseBody, UpdateCourseBody } from '../schemas/validation.schemas.js'; /** * Get all courses * GET /api/courses */ export const getAllCourses = async (_req: Request, res: Response, next: NextFunction): Promise<void> => { try { const result = await DatabaseHelper.select<ICourse>('courses', ['id', 'name', 'code', 'credits', 'description']); res.status(200).json(result.rows); } catch (error) { next(error); } }; /** * Get course by ID * GET /api/courses/:id */ export const getCourseById = async (req: Request, res: Response, next: NextFunction): Promise<void> => { try { const { id } = req.params; const courseId = parseInt(id as string, 10); if (isNaN(courseId) || courseId <= 0) { throw new BadRequestError('Invalid course ID'); } const result = await DatabaseHelper.select<ICourse>('courses', ['id', 'name', 'code', 'credits', 'description'], { id: courseId }); if (result.rows.length === 0) { throw new NotFoundError('Course not found'); } res.status(200).json(result.rows[0]); } catch (error) { next(error); } }; /** * Create new course * POST /api/courses */ export const createCourse = async (req: Request, res: Response, next: NextFunction): Promise<void> => { try { const { name, code, credits, description }: CreateCourseBody = req.body; // Check if code already exists const existingCourse = (await DatabaseHelper.select('courses', ['id'], { code })).rows[0]; if (existingCourse) { throw new ConflictError('Course with this code already exists'); } const newCourseData: Record<string, unknown> = { name, code, credits }; if (description !== undefined) { newCourseData.description = description; } const result = await DatabaseHelper.insert<ICourse>('courses', newCourseData, ['id', 'name', 'code', 'credits', 'description']); res.status(201).json(result.rows[0]); } catch (error) { next(error); } }; /** * Update course by ID * PUT /api/courses/:id */ export const updateCourse = async (req: Request, res: Response, next: NextFunction): Promise<void> => { try { const { id } = req.params; const courseId = parseInt(id as string, 10); if (isNaN(courseId) || courseId <= 0) { throw new BadRequestError('Invalid course ID'); } const { name, code, credits, description }: UpdateCourseBody = req.body; // Check if course exists const existingCourse = (await DatabaseHelper.select('courses', ['id'], { id: courseId })).rows[0]; if (!existingCourse) { throw new NotFoundError('Course not found'); } // Check if new code already exists (if code is being changed) if (code && code !== existingCourse.code) { const codeExists = (await DatabaseHelper.select('courses', ['id'], { code })).rows[0]; if (codeExists) { throw new ConflictError('Course with this code already exists'); } } const updateData: Record<string, unknown> = {}; if (name !== undefined) updateData.name = name; if (code !== undefined) updateData.code = code; if (credits !== undefined) updateData.credits = credits; if (description !== undefined) updateData.description = description; const result = await DatabaseHelper.update<ICourse>('courses', updateData, { id }, ['id', 'name', 'code', 'credits', 'description']); res.status(200).json(result.rows[0]); } catch (error) { next(error); } }; /** * Delete course by ID * DELETE /api/courses/:id */ export const deleteCourse = async (req: Request, res: Response, next: NextFunction): Promise<void> => { try { const { id } = req.params; const courseId = parseInt(id as string, 10); if (isNaN(courseId) || courseId <= 0) { throw new BadRequestError('Invalid course ID'); } // Check if course exists const existingCourse = (await DatabaseHelper.select('courses', ['id'], { id: courseId })).rows[0]; if (!existingCourse) { throw new NotFoundError('Course not found'); } await DatabaseHelper.delete('courses', { id: courseId }); res.status(204).send(); } catch (error) { if (error instanceof Error && error.message.includes('foreign key')) { throw new ConflictError('Cannot delete course: it is referenced by schedules'); } next(error); } };