Skip to content

Refactor/mosu 130 신청 리팩토링#137

Merged
chominju02 merged 4 commits intodevelopfrom
refactor/mosu-130
Jul 26, 2025
Merged

Refactor/mosu 130 신청 리팩토링#137
chominju02 merged 4 commits intodevelopfrom
refactor/mosu-130

Conversation

@chominju02
Copy link
Contributor

@chominju02 chominju02 commented Jul 26, 2025

✨ 구현한 기능

📢 논의하고 싶은 내용

🎸 기타

Summary by CodeRabbit

  • New Features

    • Introduced several new data structures and processing components to support application and exam management, including context and command objects for streamlined data handling.
    • Added new validation logic to prevent duplicate exam applications and ensure valid lunch selections.
    • Enhanced error handling with a new error code for duplicate exam applications.
    • Added new utility methods for subject and exam entities.
  • Refactor

    • Streamlined application processing and retrieval, delegating validation and registration to dedicated components for improved modularity and maintainability.
  • Bug Fixes

    • Improved subject validation logic to better handle invalid subject names.
  • Style

    • Cleaned up imports and minor formatting in several files.
  • Documentation

    • Updated method and class names for clarity and consistency.

@coderabbitai
Copy link

coderabbitai bot commented Jul 26, 2025

Caution

Review failed

The pull request is closed.

Walkthrough

This update introduces several new records and processor classes to modularize and streamline application processing, validation, and data assembly in the application service layer. It refactors ApplicationService to delegate validation and registration logic to dedicated validator and processor components, introduces an ApplicationContext for aggregating and assembling application data, and adds supporting DTOs and enums.

Changes

File(s) / Group Change Summary
.../application/ApplicationContext.java New record ApplicationContext encapsulating application-related entities, fetchers, and DTO assembly methods.
.../application/ApplicationProcessingContext.java New record ApplicationProcessingContext with static factory method.
.../application/ApplicationService.java Refactored: delegates validation and registration to new validator/processors; uses ApplicationContext.
.../application/RegisterApplicationStepProcessor.java New processor class for registering exam applications and subjects in a transactional step.
.../application/dto/AppExam.java
.../dto/AppExamSubject.java
.../dto/AppPayment.java
New record DTOs for exam, subject, and payment associations with static factory methods.
.../application/dto/RegisterApplicationCommand.java New record DTO for application registration command with static factory method.
.../application/processor/SaveApplicationStepProcessor.java New processor class stub for saving applications (method currently returns null).
.../application/processor/SaveExamTicketStepProcessor.java New processor class for saving exam ticket images conditionally.
.../application/stream/IdStream.java New functional interface for extracting IDs from ExamSubjectJpaEntity.
.../application/vaildator/ApplicationValidator.java New validator class with methods for duplicate exams, exam/lunch validation, and duplicate application checks.
.../auth/processor/SignUpAccountStepProcessor.java Now explicitly implements StepProcessor<UserJpaEntity>.
.../auth/processor/SignUpProfileStepProcessor.java Added missing import for StepProcessor.
.../exam/cache/ExamQuotaCacheManager.java Removed unused imports; minor formatting.
.../domain/application/ApplicationJpaEntity.java Removed extraneous blank line in constructor.
.../domain/application/Subject.java Changed display name for SOCIETY_AND_CULTURE; added static getSubject(String) method with error handling.
.../domain/exam/ExamJpaEntity.java Added providesLunch() method.
.../global/exception/ErrorCode.java Added new error code EXAM_DUPLICATED; minor punctuation fix.
.../global/processor/StepProcessor.java Moved interface to global.processor package (package declaration change only).
.../presentation/a/Test.java New test file with placeholder classes (Test, Item, Cart).
.../presentation/application/dto/ApplicationRequest.java Renamed and refactored validatedSubjects() to getSubjects(); changed subject mapping logic.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant ApplicationService
    participant ApplicationValidator
    participant RegisterApplicationStepProcessor
    participant SaveExamTicketStepProcessor
    participant ApplicationContext

    User->>ApplicationService: apply(userId, ApplicationRequest)
    ApplicationService->>ApplicationValidator: RequestNoDuplicateExams, ExamIdsAndLunchSelection, NoDuplicateApplication
    ApplicationService->>RegisterApplicationStepProcessor: process(RegisterApplicationCommand)
    RegisterApplicationStepProcessor-->>ApplicationService: RegisterApplicationCommand
    ApplicationService->>SaveExamTicketStepProcessor: process(ApplicationProcessingContext)
    SaveExamTicketStepProcessor-->>ApplicationService: ApplicationProcessingContext
    ApplicationService-->>User: CreateApplicationResponse

    User->>ApplicationService: getApplications(userId)
    ApplicationService->>ApplicationContext: new ApplicationContext(...)
    ApplicationContext->>ApplicationContext: fetchExams(fetcher)
    ApplicationContext->>ApplicationContext: fetchSubjects(fetcher)
    ApplicationContext->>ApplicationContext: fetchPayments(fetcher)
    ApplicationContext->>ApplicationService: assemble()
    ApplicationService-->>User: List<ApplicationResponse>
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~40 minutes

Possibly related PRs

Suggested reviewers

  • wlgns12370
  • jbh010204

Poem

In fields of code where rabbits play,
New contexts bloom and logic finds its way.
Processors hop, validators leap,
Applications tidy, no bugs to keep.
With DTOs fresh and errors few,
This patch brings springtime—code anew!
🐇✨

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8ed6b2f and fba39e4.

📒 Files selected for processing (22)
  • src/main/java/life/mosu/mosuserver/application/application/ApplicationContext.java (1 hunks)
  • src/main/java/life/mosu/mosuserver/application/application/ApplicationProcessingContext.java (1 hunks)
  • src/main/java/life/mosu/mosuserver/application/application/ApplicationService.java (2 hunks)
  • src/main/java/life/mosu/mosuserver/application/application/RegisterApplicationStepProcessor.java (1 hunks)
  • src/main/java/life/mosu/mosuserver/application/application/dto/AppExam.java (1 hunks)
  • src/main/java/life/mosu/mosuserver/application/application/dto/AppExamSubject.java (1 hunks)
  • src/main/java/life/mosu/mosuserver/application/application/dto/AppPayment.java (1 hunks)
  • src/main/java/life/mosu/mosuserver/application/application/dto/RegisterApplicationCommand.java (1 hunks)
  • src/main/java/life/mosu/mosuserver/application/application/processor/SaveApplicationStepProcessor.java (1 hunks)
  • src/main/java/life/mosu/mosuserver/application/application/processor/SaveExamTicketStepProcessor.java (1 hunks)
  • src/main/java/life/mosu/mosuserver/application/application/stream/IdStream.java (1 hunks)
  • src/main/java/life/mosu/mosuserver/application/application/vaildator/ApplicationValidator.java (1 hunks)
  • src/main/java/life/mosu/mosuserver/application/auth/processor/SignUpAccountStepProcessor.java (1 hunks)
  • src/main/java/life/mosu/mosuserver/application/auth/processor/SignUpProfileStepProcessor.java (1 hunks)
  • src/main/java/life/mosu/mosuserver/application/exam/cache/ExamQuotaCacheManager.java (2 hunks)
  • src/main/java/life/mosu/mosuserver/domain/application/ApplicationJpaEntity.java (0 hunks)
  • src/main/java/life/mosu/mosuserver/domain/application/Subject.java (3 hunks)
  • src/main/java/life/mosu/mosuserver/domain/exam/ExamJpaEntity.java (1 hunks)
  • src/main/java/life/mosu/mosuserver/global/exception/ErrorCode.java (2 hunks)
  • src/main/java/life/mosu/mosuserver/global/processor/StepProcessor.java (1 hunks)
  • src/main/java/life/mosu/mosuserver/presentation/a/Test.java (1 hunks)
  • src/main/java/life/mosu/mosuserver/presentation/application/dto/ApplicationRequest.java (1 hunks)
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch refactor/mosu-130

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ 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.
    • Explain this complex logic.
    • 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 explain this code block.
    • @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 explain its main purpose.
    • @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.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

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.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @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.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

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.

@chominju02 chominju02 merged commit 3173069 into develop Jul 26, 2025
0 of 2 checks passed
@chominju02 chominju02 deleted the refactor/mosu-130 branch July 26, 2025 02:19
Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Summary of Changes

Hello @chominju02, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request focuses on a significant refactoring of the application (신청) module to enhance code organization, readability, and maintainability. It achieves this by extracting responsibilities into specialized components for validation, multi-step processing, and data assembly, thereby simplifying the main application service logic.

Highlights

  • Refactoring Application Service Logic: The core ApplicationService has been significantly refactored. Complex validation logic has been extracted into a new ApplicationValidator component, and multi-step processing (like registering exam applications and saving exam tickets) has been delegated to dedicated StepProcessor implementations (RegisterApplicationStepProcessor, SaveExamTicketStepProcessor). This greatly simplifies the apply method.
  • Streamlined Data Assembly with ApplicationContext: A new ApplicationContext record has been introduced to centralize and simplify the retrieval and assembly of application-related data for responses. The getApplications method in ApplicationService now leverages this context object to fetch exams, subjects, and payments, and then assemble the final ApplicationResponse list, replacing a large amount of previously inline and fragmented logic.
  • Generalization of StepProcessor Interface: The StepProcessor interface, previously located within the auth.processor package, has been moved to a more general global.processor package. This indicates its intended use as a reusable pattern across different application domains.
  • Improved Subject Handling and Validation: The Subject enum now includes a static getSubject method for robust conversion from string names, and a new EXAM_DUPLICATED error code has been added to ErrorCode for better validation of application requests.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in issue comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments or fill out our survey to provide feedback.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request is a great refactoring of the application submission logic. It significantly improves the code's structure by separating concerns into a validator, step processors, and a context object, making the ApplicationService much cleaner. I've identified some areas for improvement, mainly concerning leftover code from the refactoring, a package name typo, and a minor inconsistency. Addressing these points will make this a very strong contribution.

Comment on lines +1 to +21
package life.mosu.mosuserver.presentation.a;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;

class Item {

}

class Cart {

private final List<Item> items = new ArrayList<>();
Stream
}

public class Test {

List<Item> items;
Cart cart;
}

Choose a reason for hiding this comment

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

critical

This file appears to be temporary scratch code that was committed by mistake. It's located in the src/main/java source tree, is in a temporary package presentation.a, and contains non-compiling code. Please remove this file from the pull request.

Comment on lines +6 to +12
public class SaveApplicationStepProcessor implements StepProcessor<ApplicationProcessingContext> {

@Override
public ApplicationProcessingContext process(ApplicationProcessingContext request) {
return null;
}
}

Choose a reason for hiding this comment

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

high

This class appears to be either incomplete or dead code. The process method returns null, and the class is not used anywhere in the changes. It should be removed if it's not part of a feature being developed in this PR to avoid cluttering the codebase.

Comment on lines +6 to +11
@FunctionalInterface
public interface IdStream extends Function<ExamSubjectJpaEntity, Long> {

Long apply(ExamSubjectJpaEntity examSubject);

}

Choose a reason for hiding this comment

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

high

This functional interface IdStream is not used anywhere in the codebase. It appears to be dead code and should be removed to keep the codebase clean.

@@ -0,0 +1,69 @@
package life.mosu.mosuserver.application.application.vaildator;

Choose a reason for hiding this comment

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

high

The package name life.mosu.mosuserver.application.application.vaildator contains a typo. It should be validator.

This should be corrected by renaming the directory and updating all related import statements (e.g., in ApplicationService.java) to improve maintainability and prevent confusion.

Suggested change
package life.mosu.mosuserver.application.application.vaildator;
package life.mosu.mosuserver.application.application.validator;

}

private Map.Entry<Long, ExamApplicationResponse> createExamApplicationResponse(
ExamApplicationJpaEntity examApp) throws RuntimeException {

Choose a reason for hiding this comment

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

medium

The throws RuntimeException clause is redundant here. RuntimeException and its subclasses are unchecked exceptions, so you don't need to declare them in the method signature. Removing it will make the code slightly cleaner.

    private Map.Entry<Long, ExamApplicationResponse> createExamApplicationResponse(
            ExamApplicationJpaEntity examApp) {

@@ -0,0 +1,43 @@
package life.mosu.mosuserver.application.application;

import jakarta.transaction.Transactional;

Choose a reason for hiding this comment

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

medium

This class uses jakarta.transaction.Transactional, while other services like ApplicationService use org.springframework.transaction.annotation.Transactional. To ensure consistent transaction management behavior across the application, it's recommended to use Spring's annotation throughout. Please switch to org.springframework.transaction.annotation.Transactional.

Suggested change
import jakarta.transaction.Transactional;
import org.springframework.transaction.annotation.Transactional;

Long applicationId = context.applicationId();
FileRequest fileReq = context.fileRequest();

if (fileReq.fileName() != null && fileReq.s3Key() != null) {

Choose a reason for hiding this comment

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

medium

The condition fileReq.fileName() != null && fileReq.s3Key() != null can be simplified by adding a helper method to the FileRequest record, for example isValid(). This would improve readability and encapsulate the logic within the FileRequest object itself.

Comment on lines +69 to +83
// Set<Subject> subjectSet;
// try {
// subjectSet = subjects.stream()
// .map(Subject::valueOf)
// .collect(Collectors.toSet());
// } catch (IllegalArgumentException e) {
// throw new CustomRuntimeException(ErrorCode.WRONG_SUBJECT_TYPE);
// }
//
// if (subjectSet.size() != 2) {
// throw new CustomRuntimeException(ErrorCode.WRONG_SUBJECT_COUNT);
// }
//
// return subjectSet;
// }

Choose a reason for hiding this comment

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

medium

This large block of commented-out code should be removed. Leaving commented-out code in the codebase can cause confusion and reduces maintainability. If this logic is needed for reference, it should be available in the version control history.

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.

1 participant