Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEAT] 시험 문제 생성, 수정, 삭제 기능 구현 #74

Merged
merged 16 commits into from
Nov 17, 2024

Conversation

hyerin315
Copy link
Contributor

관련 이슈

목적

시험 문제 관리를 위한 생성, 수정, 삭제 기능을 구현합니다.

변경 사항

1. 객관식 및 주관식 문제 생성 기능 구현

  • correctAnswer 필드를 추가하여 객관식과 주관식 문제를 통합적으로 관리
  • ChoiceRequestDto를 통해 객관식 문제의 보기 번호 데이터를 처리하도록 구현
  • validateAnswer 메서드를 추가하여 입력된 정답 유효성 검사
  • 문제 번호를 생성 시 자동으로 할당하도록 구현

2. 문제 수정 및 삭제 기능 구현

  • 삭제 로직에서 시험 문제와 시험 간의 관계를 검증하여 데이터 무결성 유지
    • 문제 삭제 시 남은 문제 번호를 자동으로 재정렬하는 메서드 추가

3. ExamService 및 Controller 통합

  • 역할 기반 설계를 기능 중심 설계로 변경
    • InstructorExamServiceStudentExamServiceExamService로 통합
    • InstructorExamControllerStudentExamController 삭제 후 ExamController에서 엔드포인트 관리
  • CRUD 엔드포인트 수정 및 @PreAuthorize를 활용한 역할별 접근 제어 구현

스크린샷

주요 변경사항

기능 스크린샷
주관식 문제 생성 스크린샷 2024-11-17 오후 8 31 14
객관식 문제 생성 스크린샷 2024-11-17 오후 8 31 44
객관식 문제 수정 스크린샷 2024-11-17 오후 8 32 33
문제 삭제 스크린샷 2024-11-17 오후 8 33 01

체크리스트

  • 코드 컨벤션을 준수하였습니까?
  • 모든 테스트를 통과하였습니까?
  • 관련 문서를 업데이트하였습니까?

공유사항

  • 테스트 환경에서 S3 접근을 Mock 데이터로 대체하여 테스트 시 S3 연결 불필요하도록 처리하였습니다.
  • 기존의 역할 기반 설계(Instructor/Student 분리)를 기능 기반 설계로 전환함으로써 중복된 코드를 줄이고, 서비스 로직을 통합하여 코드의 효율성과 유지보수성을 개선하였습니다.

추후 업무

  • 역할별, 상황별 조회 기능 구현
  • 문제별 이미지 업로드 기능 구현
  • 문제 관련 CRUD 리팩토링
  • 문제 삭제 및 재정렬 로직 성능 최적화

- test 환경에 s3 환경을 Mock 데이터로 수정
- InsturctorExamService, StudentExamService 삭제 후 ExamService에 통합
- InstuctorExamController 및 StudentExamController 삭제 후 ExamController에서 엔드포인트 관리
- 시험 목록 조회, 상세조회, 생성, 수정, 삭제 관련 엔드포인트 수정
 - @PreAuthorize를 사용하여 역할별 엔드포인드 처리 구현
- 객관식/주관식 문제를 correctAnswer 하나의 필드로 관리
- 유효성 검사를 위한 validateAnswer 추가
- 시험 문제 번호를 자동으로 재정렬해주기 위한 메소드 추가
- 시험 문제 생성, 정렬, 수정, 삭제를 위한 엔드포인트 구현
- 시험 문제 생성을 요청하는 CreateQuestionRequestDto 클래스 구현
 - 시험 유효성 검사, 객관식/주관식 문제 생성 기능 구현
- 객관식 문제 생성시 보기 번호 생성을 위한 ChoiceRequestDto 클래스 구현
- 시험 문제 조회, 수정 기능에 응답하는 ExamQuestionResponseDto 클래스 구현
 - 시험 유효성 검사, 객관식/주관식 문제 조회 기능 구현
- 객관식 문제 조회를 위한 ChoiceResponseDto 클래스 구현
- 중복 사용되는 시험 조회 컴포넌트 구현
- ExamService를 역할 기반에서 기능 기반으로 수정하여 시험 CRUD 로직을 모두 수행할 수 있도록 수정
- ExamQuestionService로 시험 문제 CRUD 로직을 모두 수행할 수 있도록 기능 구현
- 문제 수정을 위한 UpdateQuestionRequestDto 클래스 구현
- 문제 조회를 위한 ExamQuestionRepository 구현
- Exam 클래스에서 reorderQuestionAfterDelete 메소드 기능 수정
- ExamQuestionService에서 삭제 후 남은 문제의 번호 재정렬을 처리하는 기능 구현
@hyerin315 hyerin315 added the enhancement New feature or request label Nov 17, 2024
@hyerin315 hyerin315 self-assigned this Nov 17, 2024
Copy link
Member

@Chan-GN Chan-GN left a comment

Choose a reason for hiding this comment

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

복잡한 비즈니스 로직을 하나씩 고민하시면서 접근해보신 흔적이 느껴집니다...

중간중간 도메인에 비즈니스 로직과 검증 로직이 담겨있어 좋았습니다.
또, ExamFinder 클래스로 조회 로직을 분리해보신 것도 좋은 방식인듯 합니다!

몇가지 궁금한 점이 있어 코멘트를 남겨드리니 추후 리팩토링간 참고 및 답변 해주시면 좋겠습니다.

고생 많으셨습니다!

@PathVariable Long examId,
@CurrentUserEmail String email,
Authentication authentication) {
String role = authentication.getAuthorities().stream()
Copy link
Member

Choose a reason for hiding this comment

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

역할을 추출하는 코드가 중복되고 있네요!
만약 역할을 추출해야하는 상황이 반복된다면, 커스텀 어노테이션을 정의해보시는 것도 좋은 방법일 것 같습니다!

@CurrentUserEmail과 같은 방식으로요!

String description,
Course course) {
Exam exam = new Exam();
exam.title = title;
Copy link
Member

Choose a reason for hiding this comment

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

필드를 하나씩 지정하셨는데, 그 이유가 있을까요?

관련 필드를 전달받아 새로운 인스턴스를 반환하는 private 생성자를 사용해보시는방법은 어떻게 생각하시는지 궁금합니다!

ExamQuestion targetQuestion = questions.stream()
.filter(q -> q.getId().equals(questionId))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("문제를 찾을 수 없습니다. ID: " + questionId));
Copy link
Member

Choose a reason for hiding this comment

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

추후 커스텀 예외를 생성하여 예외 처리를 일관성 있게 유지해주시면 좋겠습니다!


public ExamQuestion toEntity(Exam exam) {
// exam 유효성 검사
if (exam == null) {
Copy link
Member

Choose a reason for hiding this comment

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

이 유효성 검사가 필요한지 고민해보시면 좋겠습니다!


// 시험 목록 조회
public List<ExamResponseDto> getExams(Long courseId, String email, String role) {
if (role.contains("ROLE_INSTRUCTOR")) {
Copy link
Member

Choose a reason for hiding this comment

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

getExams 메서드를 사용하여 강사와 학생의 시험 조회 기능을 모두 구현하셨군요!

이런 방식을 채택하신 이유가 궁금합니다!!

Copy link
Contributor

@cuteJJong cuteJJong left a comment

Choose a reason for hiding this comment

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

제일 어려운 부분 구현하시느라 고생하셨습니다.


// 시험 문제 생성
@PostMapping
@PreAuthorize("hasRole('INSTRUCTOR')")
Copy link
Contributor

Choose a reason for hiding this comment

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

@PreAuthorize이 동작하려면 @EnableMethodSecurity 필요한데 따로 관리하게 하셨나용? 아니시면 SecurityConfig에 SecurityConfig서 전역으로 관리하는게 좋다고 하네요 저도 컨트롤러마다 작성했는데 이 번에 수정할려구요!

- ExamController와 ExamQuestionController에서 권한 검증 방식 변경
- Exam 생성자의 객체 생성 방식을 public에서 private으로 변경
@hyerin315 hyerin315 merged commit df4d03c into main Nov 17, 2024
@hyerin315 hyerin315 deleted the feature/67-exam-question-management branch November 17, 2024 14:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

[FEAT] 시험 문제 생성, 수정, 삭제 기능 구현
3 participants