Skip to content

Conversation

@pedroafmonteiro
Copy link
Member

@pedroafmonteiro pedroafmonteiro commented Dec 27, 2025

Closes #52

Copilot AI review requested due to automatic review settings December 27, 2025 22:11
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a Course entity and establishes a many-to-many relationship between Courses and Faculties. It includes API endpoints for CRUD operations on courses and enhances the faculty endpoints to support course associations.

Key Changes:

  • Added Course entity with many-to-many relationship to Faculty
  • Created CoursesModule with full CRUD endpoints (controller, service, DTOs)
  • Refactored Faculty entity location to entities folder and added courses relationship
  • Implemented global EntityNotFoundFilter for standardized error handling
  • Updated database seeding to support courses and their associations

Reviewed changes

Copilot reviewed 24 out of 24 changed files in this pull request and generated 11 comments.

Show a summary per file
File Description
src/courses/entities/course.entity.ts New Course entity with id, name, acronym, and many-to-many relationship to faculties
src/courses/courses.service.ts Service implementing CRUD operations for courses with faculty relationship management
src/courses/courses.controller.ts REST controller exposing course endpoints with authentication guards
src/courses/dto/create-course.dto.ts DTO for course creation with validation and optional faculty IDs
src/courses/dto/update-course.dto.ts DTO extending CreateCourseDto for partial updates
src/courses/courses.module.ts Module configuration importing Course and Faculty repositories
src/courses/courses.service.spec.ts Basic test file for CoursesService
src/courses/courses.controller.spec.ts Basic test file for CoursesController
src/faculties/entities/faculty.entity.ts Faculty entity relocated with added many-to-many courses relationship
src/faculties/faculties.service.ts Updated to handle course associations in create, update, and delete operations
src/faculties/faculties.module.ts Updated to import Course repository
src/faculties/dto/create-faculty.dto.ts Extended with optional courseIds array field
src/faculties/faculties.service.spec.ts Updated import path for Faculty entity
src/faculties/faculties.controller.ts Updated import path for Faculty entity
src/faculties/faculties.controller.spec.ts Updated import path for Faculty entity
src/filters/entity-not-found.filter.ts New global filter to convert TypeORM EntityNotFoundError to NotFoundException
src/database/factories/course.factory.ts Factory for generating realistic course test data
src/database/seeds/course.seeder.ts Seeder to create 20 course records
src/database/seeds/faculty.seeder.ts Updated to associate faculties with random courses
src/database/seed.ts Updated entity list to include Course
src/database/factories/faculty.factory.ts Updated import path for Faculty entity
src/app.module.ts Registered CoursesModule
src/main.ts Registered EntityNotFoundFilter globally

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 1 to 79
import { Injectable, NotFoundException } from '@nestjs/common';
import { CreateCourseDto } from './dto/create-course.dto';
import { UpdateCourseDto } from './dto/update-course.dto';
import { InjectRepository } from '@nestjs/typeorm';
import { Course } from './entities/course.entity';
import { In, Repository } from 'typeorm';
import { Faculty } from '../faculties/entities/faculty.entity';

@Injectable()
export class CoursesService {
constructor(
@InjectRepository(Course)
private courseRepository: Repository<Course>,
@InjectRepository(Faculty)
private facultyRepository: Repository<Faculty>,
) {}

async create(createCourseDto: CreateCourseDto): Promise<Course> {
const { facultyIds, ...courseData } = createCourseDto;
const course = this.courseRepository.create(courseData);

if (facultyIds && facultyIds.length > 0) {
const faculties = await this.facultyRepository.findBy({
id: In(facultyIds),
});
if (faculties.length !== facultyIds.length) {
throw new NotFoundException(`One or more faculties not found`);
}
course.faculties = faculties;
} else {
course.faculties = [];
}

return this.courseRepository.save(course);
}

findAll(): Promise<Course[]> {
return this.courseRepository.find({ relations: ['faculties'] });
}

findOne(id: number): Promise<Course> {
return this.courseRepository.findOneOrFail({
where: { id },
relations: ['faculties'],
});
}

async update(id: number, updateCourseDto: UpdateCourseDto): Promise<Course> {
const { facultyIds, ...courseData } = updateCourseDto;

const course = await this.courseRepository.findOneBy({ id });

if (!course) {
throw new NotFoundException(`Course with id ${id} not found`);
}

this.courseRepository.merge(course, courseData);

if (facultyIds && facultyIds.length > 0) {
const faculties = await this.facultyRepository.findBy({
id: In(facultyIds),
});
if (faculties.length !== facultyIds.length) {
throw new NotFoundException(`One or more faculties not found`);
}
course.faculties = faculties;
} else {
course.faculties = [];
}

return this.courseRepository.save(course);
}

async remove(id: number): Promise<Course> {
const course = await this.courseRepository.findOneByOrFail({ id });
await this.courseRepository.delete(id);
return course;
}
}
Copy link

Copilot AI Dec 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Significant code duplication exists between CoursesService and FacultiesService. The create, update, and remove methods have nearly identical logic for handling many-to-many relationships. Consider extracting the common relationship handling logic into a shared utility function or base service class to improve maintainability and reduce code duplication.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Create Course model

2 participants