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

[DDING-000] 지원하기 시 응답기간 검증 로직 추가 #269

Merged
merged 7 commits into from
Feb 16, 2025

Conversation

Seooooo24
Copy link
Collaborator

@Seooooo24 Seooooo24 commented Feb 15, 2025

🚀 작업 내용

사용자가 응답 기간이 지난 폼지에 지원할 수 없도록 응답기간 검증 로직 추가하였습니다.

🤔 고민했던 내용

이 상황에 IllegalStateException을 사용하는 것이 맞는지 궁금합니다..

💬 리뷰 중점사항

Summary by CodeRabbit

  • 신규 기능
    • 양식 제출 시 시작 및 종료 날짜에 대한 유효성 검사를 추가하여 잘못된 날짜 입력을 방지합니다.
    • 사용자 양식 응답에 클럽 정보(클럽명)가 포함되어, 양식 관련 정보가 더욱 풍부해졌습니다.
  • 리팩토링
    • 양식 검증 오류 처리를 개선하여, 오류 발생 시 보다 명확한 메시지가 제공됩니다.

@Seooooo24 Seooooo24 changed the title refactor: 지원하기 시 응답기간 검증 로직 추가 [DDING-000] 지원하기 시 응답기간 검증 로직 추가 Feb 15, 2025
@Seooooo24 Seooooo24 added 🎯리팩토링 리팩토링 및 고도화 이슈 D-3 labels Feb 15, 2025
Copy link

coderabbitai bot commented Feb 15, 2025

Warning

Rate limit exceeded

@Seooooo24 has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 4 minutes and 37 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 63deeb7 and 5d1ad82.

📒 Files selected for processing (2)
  • src/main/java/ddingdong/ddingdongBE/domain/form/service/FacadeCentralFormServiceImpl.java (3 hunks)
  • src/test/java/ddingdong/ddingdongBE/domain/club/service/FacadeCentralClubServiceImplTest.java (1 hunks)

Walkthrough

이 PR은 폼 생성 및 응답 처리 과정에 날짜 검증 로직과 클럽 관련 데이터를 통합하는 변경을 포함합니다. FacadeUserFormApplicationServiceImpl에 폼의 시작/종료 날짜를 검증하는 validateFormPeriod 메서드가 추가되었으며, 유효하지 않은 경우 예외를 발생시킵니다. 또한, UserFormResponse와 UserFormQuery에 clubName 필드가 도입되고, FacadeUserFormServiceImpl의 getUserForm 메서드가 클럽 정보를 처리하도록 수정되었습니다. 테스트 중 UpdateClubInfoCommand의 파라미터도 정리되었으며, 예외 처리 계층이 재구성되었습니다.

Changes

파일 경로 변경 요약
.../domain/formapplication/service/FacadeUserFormApplicationServiceImpl.java
.../domain/form/controller/dto/response/UserFormResponse.java
.../domain/form/service/dto/query/UserFormQuery.java
.../domain/form/service/FacadeUserFormServiceImpl.java
- validateFormPeriod 메서드 추가하여 시작/종료 날짜 검증 실시
- 응답(Query/Response) 객체에 clubName 필드 도입 및 메서드 시그니처 수정(Club 파라미터 포함)
.../domain/form/service/FacadeCentralFormServiceImpl.java - 폼 중복 날짜 검증 메서드에서 기존의 InvalidatedMappingException 예외 대신 새로운 FormException 예외(OverlapFormPeriodException, InvalidFieldTypeException) 사용
.../common/exception/FormException.java
.../common/exception/InvalidatedMappingException.java
- 폼 관련 오류 처리를 위한 새로운 예외 계층(FormException 및 하위 예외) 도입
- InvalidatedMappingException 내 상수 및 예외 클래스 제거
.../domain/club/service/FacadeCentralClubServiceImplTest.java - UpdateClubInfoCommand 생성자 파라미터 정리(타임스탬프와 폼 URL 삭제)

Sequence Diagram(s)

sequenceDiagram
    participant Client as 클라이언트
    participant Service as FacadeUserFormApplicationServiceImpl
    participant Validator as validateFormPeriod
    participant Repo as FormApplication 저장소

    Client->>Service: createFormApplication(폼 데이터)
    Service->>Validator: validateFormPeriod(startDate, endDate, now)
    alt 날짜 검증 실패
        Validator-->>Service: FormPeriodException 발생
        Service-->>Client: 예외 응답 반환
    else 날짜 검증 성공
        Validator-->>Service: 검증 통과
        Service->>Repo: FormApplication 생성 요청
        Service-->>Client: 성공 응답 반환
    end
Loading

Possibly related PRs

Suggested labels

🛠️버그, ✨기능

Suggested reviewers

  • wonjunYou
  • 5uhwann
  • KoSeonJe

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
src/main/java/ddingdong/ddingdongBE/domain/formapplication/service/FacadeUserFormApplicationServiceImpl.java (1)

45-50: 기본 구현은 적절하나 개선 가능한 부분이 있습니다.

폼 응답기간 검증 로직이 잘 구현되어 있습니다. 다만 다음과 같은 개선사항을 고려해 보시기 바랍니다:

  1. 더 정확한 시간 비교를 위해 LocalDate 대신 LocalDateTime 사용
  2. 일반적인 IllegalStateException 대신 커스텀 예외 클래스 사용
  3. startDateendDate가 null인 경우에 대한 방어 로직 추가

다음과 같이 개선된 구현을 제안합니다:

-    private void validateFormStatus(Form form) {
-        LocalDate now = LocalDate.now();
-        if (form.getStartDate().isAfter(now) || form.getEndDate().isBefore(now)) {
-            throw new IllegalStateException(ILLEGAL_FORM_STATUS.getText());
-        }
-    }
+    private void validateFormStatus(Form form) {
+        if (form.getStartDate() == null || form.getEndDate() == null) {
+            throw new IllegalStateException(ILLEGAL_FORM_STATUS.getText());
+        }
+        
+        LocalDateTime now = LocalDateTime.now();
+        LocalDateTime startDateTime = form.getStartDate().atStartOfDay();
+        LocalDateTime endDateTime = form.getEndDate().plusDays(1).atStartOfDay().minusSeconds(1);
+        
+        if (now.isBefore(startDateTime) || now.isAfter(endDateTime)) {
+            throw new IllegalStateException(ILLEGAL_FORM_STATUS.getText());
+        }
+    }
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2293445 and e32663a.

📒 Files selected for processing (2)
  • src/main/java/ddingdong/ddingdongBE/common/exception/ErrorMessage.java (1 hunks)
  • src/main/java/ddingdong/ddingdongBE/domain/formapplication/service/FacadeUserFormApplicationServiceImpl.java (4 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Build and analyze
🔇 Additional comments (2)
src/main/java/ddingdong/ddingdongBE/common/exception/ErrorMessage.java (1)

25-26: LGTM! 적절한 에러 메시지 추가

폼 응답기간 검증을 위한 에러 메시지가 명확하고 일관성 있게 추가되었습니다.

src/main/java/ddingdong/ddingdongBE/domain/formapplication/service/FacadeUserFormApplicationServiceImpl.java (1)

31-43: 트랜잭션 범위가 적절합니다.

@Transactional 어노테이션이 메소드 레벨에서 적절하게 적용되어 있어, 폼 생성과 답변 저장이 하나의 트랜잭션으로 처리됩니다.

Copy link
Collaborator

@KoSeonJe KoSeonJe left a comment

Choose a reason for hiding this comment

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

확인하였습니다 코멘트 반영해주세요

Comment on lines 45 to 50
private void validateFormStatus(Form form) {
LocalDate now = LocalDate.now();
if (form.getStartDate().isAfter(now) || form.getEndDate().isBefore(now)) {
throw new IllegalStateException(ILLEGAL_FORM_STATUS.getText());
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

  1. 테스트 하기 어려운 코드라는 것을 인지하고 있으면 좋을 것 같아요.
    따로 validate를 위한 클래스를 사용하여 public으로 사용하지 않고 있기에 private을 활용하여 테스트가 어렵습니다.
    그리고, 컨트롤되지 않는 코드인 LocalDate.now()를 메소드 내부에서 생성하고 있기에 테스트하기 어렵습니다.

현재 이 코드를 테스트하진 않을 것이지만 인지하고 개선해 나갈 방법이 어떤 것이 있는지 알아보면 좋을 것 같네요

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

form을 파라미터로 받는 방식에서
startDate, endDate, now를 파라미터로 받는 방식으로 바꾸어보았습니다!
아직 테스트 짜는 법을 잘 이해하질 못해서... 제가 생각했을 때 테스트 하기 편한 방향으로 개선해보았습니다.
생각해볼 부분 말씀해주셔서 감사합니다!

private void validateFormStatus(Form form) {
LocalDate now = LocalDate.now();
if (form.getStartDate().isAfter(now) || form.getEndDate().isBefore(now)) {
throw new IllegalStateException(ILLEGAL_FORM_STATUS.getText());
Copy link
Collaborator

Choose a reason for hiding this comment

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

p2)
저희가 ErrorMessage 클래스가 구현되어 있지만, 사용하지 않습니다.
exception 패키지에 들어가서 새로운 예외 클래스를 생성해주세요.
중첩 클래스로 사용되고 있긴 합니다.
예외 클래스 이름은 예외와 알맞는 이름으로 지어주시면 좋을 것 같네요

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

FormApplicationException 클래스 생성하고 내부에 FormPeriodException 구현하여 처리했습니다. 이미 있는 InvalidFormPeriod랑 이름이 좀 비슷해서 걸리는데... 괜찮을까요?
메서드명도 하는 일에 더 알맞게 validateFormPeriod로 수정하였습니다!

@github-actions github-actions bot added D-2 and removed D-3 labels Feb 16, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (3)
src/main/java/ddingdong/ddingdongBE/domain/formapplication/service/FacadeUserFormApplicationServiceImpl.java (2)

46-51: 폼 기간 검증 로직이 잘 구현되었습니다만, 테스트 용이성 개선이 필요합니다.

검증 로직은 정확하게 구현되었습니다. 하지만 테스트 용이성을 위해 다음과 같은 개선을 고려해보시기 바랍니다:

  1. 별도의 validator 클래스로 분리하여 public 메소드로 만들기
  2. 테스트에서 시간을 제어할 수 있도록 설계 개선하기

35-36: LocalDate.now()를 주입 가능하도록 개선이 필요합니다.

현재 구현은 LocalDate.now()를 메소드 내부에서 직접 호출하고 있어 테스트하기 어렵습니다. 다음과 같은 방법을 고려해보세요:

  1. Clock 객체를 주입받아 사용
  2. 현재 시간을 파라미터로 전달받도록 수정

예시 리팩토링:

-    public void createFormApplication(CreateFormApplicationCommand createFormApplicationCommand) {
+    public void createFormApplication(CreateFormApplicationCommand createFormApplicationCommand, LocalDate currentDate) {
         Form form = formService.getById(createFormApplicationCommand.formId());
-        LocalDate now = LocalDate.now();
-        validateFormPeriod(form.getStartDate(), form.getEndDate(), now);
+        validateFormPeriod(form.getStartDate(), form.getEndDate(), currentDate);
src/main/java/ddingdong/ddingdongBE/domain/form/controller/dto/response/UserFormResponse.java (1)

13-14: Schema 예시를 더 구체적으로 개선하면 좋겠습니다.

현재 "카우"라는 예시보다는 실제 동아리 이름 형식에 맞는 더 구체적인 예시를 제공하면 API 문서의 품질이 향상될 것 같습니다.

-        @Schema(description = "동아리 이름", example = "카우")
+        @Schema(description = "동아리 이름", example = "중앙동아리 프로그래밍 학회")

Also applies to: 61-61

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e32663a and c4354fc.

📒 Files selected for processing (6)
  • src/main/java/ddingdong/ddingdongBE/common/exception/FormApplicationException.java (1 hunks)
  • src/main/java/ddingdong/ddingdongBE/domain/form/controller/dto/response/UserFormResponse.java (2 hunks)
  • src/main/java/ddingdong/ddingdongBE/domain/form/service/FacadeUserFormServiceImpl.java (2 hunks)
  • src/main/java/ddingdong/ddingdongBE/domain/form/service/dto/query/UserFormQuery.java (2 hunks)
  • src/main/java/ddingdong/ddingdongBE/domain/formapplication/service/FacadeUserFormApplicationServiceImpl.java (4 hunks)
  • src/test/java/ddingdong/ddingdongBE/domain/club/service/FacadeCentralClubServiceImplTest.java (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Build and analyze
🔇 Additional comments (4)
src/main/java/ddingdong/ddingdongBE/common/exception/FormApplicationException.java (1)

5-19: 예외 클래스 구조가 잘 설계되었습니다!

계층 구조가 명확하고, 에러 메시지가 한글로 잘 작성되어 있으며, HTTP 상태 코드도 적절하게 사용되었습니다.

src/main/java/ddingdong/ddingdongBE/domain/form/service/FacadeUserFormServiceImpl.java (1)

3-3: 클럽 정보 추가 구현이 잘 되었습니다!

폼 조회 시 클럽 정보를 포함하도록 하는 변경이 깔끔하게 구현되었습니다.

Also applies to: 31-31, 34-34

src/main/java/ddingdong/ddingdongBE/domain/form/service/dto/query/UserFormQuery.java (1)

12-12: DTO에 클럽 정보가 적절히 추가되었습니다!

UserFormQuery에 클럽 이름 필드를 추가하고 from 메서드를 수정한 것이 적절합니다.

Also applies to: 19-19, 25-25

src/test/java/ddingdong/ddingdongBE/domain/club/service/FacadeCentralClubServiceImplTest.java (1)

99-113: 테스트 코드가 적절히 단순화되었습니다!

불필요한 파라미터(startDateTime, endDateTime, formUrl)를 제거하여 테스트 코드가 더 명확해졌습니다.

@Seooooo24 Seooooo24 merged commit d177fab into develop Feb 16, 2025
1 check passed
@Seooooo24 Seooooo24 deleted the refactor/DDING-000 branch February 16, 2025 16:39
Copy link

Quality Gate Failed Quality Gate failed

Failed conditions
0.0% Coverage on New Code (required ≥ 80%)

See analysis details on SonarQube Cloud

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
D-2 🎯리팩토링 리팩토링 및 고도화 이슈
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants