MOSU-86 refactor: 한국어 Enum 반환 시 한글 반환으로 변경#87
Conversation
WalkthroughThis update standardizes repository interface naming by renaming all Changes
Sequence Diagram(s)sequenceDiagram
participant Frontend
participant UserController
participant UserService
participant UserJpaRepository
Frontend->>UserController: GET /user/customer-key?userId=...
UserController->>UserService: getCustomerKey(userId)
UserService->>UserJpaRepository: findById(userId)
UserJpaRepository-->>UserService: UserJpaEntity or not found
UserService-->>UserController: customerKey or error
UserController-->>Frontend: ApiResponseWrapper<CustomerKeyResponse>
sequenceDiagram
participant OAuthProvider
participant Frontend
participant OAuthController
OAuthProvider-->>Frontend: Redirect with code (& state)
Frontend->>OAuthController: GET /authorize-code?code=...&state=...
OAuthController->>Frontend: HTTP 302 redirect to /api/v1/oauth2/callback/kakao?code=...&state=...
Possibly related PRs
Suggested reviewers
Poem
✨ Finishing Touches
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed 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)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Summary of Changes
Hello @wlgns12370, 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 implements significant refactoring and introduces new features to enhance the mosuserver application. The core changes involve localizing Enum values to Korean for better user readability, standardizing repository naming conventions, and introducing a new API for retrieving user CustomerKeys. The changes also refine OAuth user management, streamline the security filter chain, and improve the development environment setup with a new database initializer and updated Swagger configuration.
Highlights
- Enum Localization: Changed various Enum fields (e.g., Gender, Education, Grade) in DTOs and query results to return their Korean string representations instead of English Enum names, improving user experience in Korean interfaces. This impacts admin application lists, student lists, and user profile details.
- Repository Naming Refactor: Standardized the naming convention for JPA repository interfaces across multiple domains (FAQ, Inquiry, Notice, Inquiry Answer) by renaming them from
*Repositoryto*JpaRepository. This is a widespread refactoring for consistency and clarity. - CustomerKey Feature: Implemented a new feature allowing retrieval of a user's unique
CustomerKey. This includes a newUserServicemethod (getCustomerKey) and a corresponding REST endpoint (/user/customer-key) inUserController. - OAuth User Management Enhancements: Improved the logic for creating and updating OAuth users. New OAuth users now have their
customerKeyautomatically generated, their initialuserRoleset toROLE_PENDING, and their agreement to terms/privacy policies set by default. Existing OAuth users' gender, name, and birth information can now be updated. - Profile Registration Flow Update: Modified the profile registration process to automatically update a user's role from
ROLE_PENDINGtoROLE_USERupon successful profile completion, ensuring correct user status management. - Security Filter Streamlining: Removed the
AccessTokenFilterandTokenExceptionFilterfrom the Spring Security configuration and commented out their source files. This indicates a simplification or re-evaluation of the token validation and exception handling strategy. - Development Setup Improvements: Introduced a
DatabaseInitializercomponent to automatically populate the database with dummy data on application startup, facilitating easier development and testing. Additionally, a local development server URL (http://localhost:8080/api/v1) was added to the Swagger configuration for convenience.
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 is currently in preview and 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 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
-
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. ↩
There was a problem hiding this comment.
Code Review
This pull request refactors repository naming conventions, changes Enum return types to Korean strings in DTOs, and updates the OAuth and customer key functionalities. The changes are well-aligned with the PR's goals.
My review highlights several points to enhance correctness and maintainability. I've identified an incorrect error code, a critical data integrity issue in the new database initializer, and some hardcoded values that could cause issues in production. Addressing these points will improve the overall quality and robustness of the code.
| for (int i = 1; i <= 10; i++) { | ||
| InquiryJpaEntity inquiryToAnswer = inquiries.get(random.nextInt(inquiries.size())); | ||
|
|
||
| UserJpaEntity answerer = users.get(random.nextInt(users.size())); | ||
| inquiryAnswerJpaRepository.save(InquiryAnswerJpaEntity.builder() | ||
| .title("Re: " + inquiryToAnswer.getTitle()) | ||
| .content("문의하신 내용에 대한 답변입니다. " + i + "번째 답변입니다.") | ||
| .inquiryId(inquiryToAnswer.getId()) | ||
| .userId(answerer.getId()) | ||
| .build()); | ||
| inquiryToAnswer.updateStatusToComplete(); | ||
| inquiryJpaRepository.save(inquiryToAnswer); | ||
| } |
There was a problem hiding this comment.
The current logic for creating inquiry answers can assign multiple answers to the same inquiry because it randomly picks an inquiry from the list in a loop. This violates the business logic in InquiryAnswerService, which ensures only one answer per inquiry. This could lead to data integrity issues.
To fix this, ensure each inquiry is answered at most once. A good approach is to shuffle the list of inquiries and then iterate through a portion of it to create answers.
// Create answers for 5 random inquiries to avoid multiple answers for one inquiry
Collections.shuffle(inquiries, random);
for (int i = 0; i < 5; i++) {
InquiryJpaEntity inquiryToAnswer = inquiries.get(i);
UserJpaEntity answerer = users.get(random.nextInt(users.size()));
inquiryAnswerJpaRepository.save(InquiryAnswerJpaEntity.builder()
.title("Re: " + inquiryToAnswer.getTitle())
.content("문의하신 내용에 대한 답변입니다. " + (i + 1) + "번째 답변입니다.")
.inquiryId(inquiryToAnswer.getId())
.userId(answerer.getId())
.build());
inquiryToAnswer.updateStatusToComplete();
inquiryJpaRepository.save(inquiryToAnswer);
}| final UserJpaEntity newUser = UserJpaEntity.builder() | ||
| .loginId(info.email()) | ||
| .gender(Gender.MALE) | ||
| .gender(info.gender() != null ? info.gender() : Gender.MALE) | ||
| .name(info.name()) | ||
| .password("") | ||
| .birth(LocalDate.now()) | ||
| .userRole(UserRole.ROLE_USER) | ||
| .birth(info.birthDay() != null ? info.birthDay() | ||
| : LocalDate.of(1900, 1, 1)) | ||
| .userRole(UserRole.ROLE_PENDING) | ||
| .agreedToTermsOfService(true) | ||
| .agreedToPrivacyPolicy(true) | ||
| .agreedToMarketing(false) | ||
| .build(); |
There was a problem hiding this comment.
When creating a new UserJpaEntity for an OAuth user, the password field is not being set, which means it will be null. The previous implementation set it to an empty string (""). A null password could lead to NullPointerExceptions. It would be safer to initialize it to an empty string.
| final UserJpaEntity newUser = UserJpaEntity.builder() | |
| .loginId(info.email()) | |
| .gender(Gender.MALE) | |
| .gender(info.gender() != null ? info.gender() : Gender.MALE) | |
| .name(info.name()) | |
| .password("") | |
| .birth(LocalDate.now()) | |
| .userRole(UserRole.ROLE_USER) | |
| .birth(info.birthDay() != null ? info.birthDay() | |
| : LocalDate.of(1900, 1, 1)) | |
| .userRole(UserRole.ROLE_PENDING) | |
| .agreedToTermsOfService(true) | |
| .agreedToPrivacyPolicy(true) | |
| .agreedToMarketing(false) | |
| .build(); | |
| final UserJpaEntity newUser = UserJpaEntity.builder() | |
| .loginId(info.email()) | |
| .gender(info.gender() != null ? info.gender() : Gender.MALE) | |
| .name(info.name()) | |
| .password("") // It's safer to set an empty password for OAuth users | |
| .birth(info.birthDay() != null ? info.birthDay() | |
| : LocalDate.of(1900, 1, 1)) | |
| .userRole(UserRole.ROLE_PENDING) | |
| .agreedToTermsOfService(true) | |
| .agreedToPrivacyPolicy(true) | |
| .agreedToMarketing(false) | |
| .build(); |
| public UserJpaEntity(String loginId, String password, Gender gender, String name, | ||
| LocalDate birth, | ||
| String customerKey, boolean agreedToTermsOfService, boolean agreedToPrivacyPolicy, | ||
| LocalDate birth, boolean agreedToTermsOfService, boolean agreedToPrivacyPolicy, | ||
| boolean agreedToMarketing, UserRole userRole) { |
There was a problem hiding this comment.
The constructor signature has changed to remove customerKey, which is now generated internally. However, the builder is still being used without providing a password, which will result in a null value for the password field. For OAuth users, it's safer to provide a default non-null value, like an empty string, to avoid potential NullPointerExceptions downstream.
| public void deleteFaq(Long faqId) { | ||
| FaqJpaEntity faqEntity = faqRepository.findById(faqId) | ||
| FaqJpaEntity faqEntity = faqJpaRepository.findById(faqId) | ||
| .orElseThrow(() -> new CustomRuntimeException(ErrorCode.FILE_NOT_FOUND)); |
There was a problem hiding this comment.
There was a problem hiding this comment.
Actionable comments posted: 11
🔭 Outside diff range comments (1)
src/main/java/life/mosu/mosuserver/global/config/SecurityConfig.java (1)
77-84: Critical: All endpoints are publicly accessible.The authorization configuration has all rules commented out, making every endpoint publicly accessible (
anyRequest().permitAll()).If this is intended for development/testing, consider:
- Adding a profile-specific configuration
- Documenting the security model being implemented
- Ensuring this doesn't reach production
.authorizeHttpRequests(authorize -> authorize -// .requestMatchers( -// "/api/v1/profile/**", -// "/api/v1/admin/**" -// ) -// .hasRole("ADMIN") + .requestMatchers( + "/api/v1/profile/**", + "/api/v1/admin/**" + ) + .hasRole("ADMIN") .anyRequest().permitAll() )
🧹 Nitpick comments (7)
src/main/java/life/mosu/mosuserver/domain/admin/ApplicationQueryRepositoryImpl.java (1)
195-201: Enum-to-string conversion looks good but consider null safety.The conversion to Korean strings using
.getGenderName(),.getEducationName(), and.getGradeName()aligns well with the localization effort.Consider adding null safety checks to prevent potential NPEs:
- tuple.get(profile.gender).getGenderName(), + Optional.ofNullable(tuple.get(profile.gender)) + .map(Gender::getGenderName) + .orElse("Unknown"),Apply similar patterns for
educationandgradefields.src/main/java/life/mosu/mosuserver/global/util/KeyGeneratorUtil.java (1)
5-10: Suggest minor improvements for utility class best practices.The implementation is correct and functional. Consider these improvements:
- Make the class final and add a private constructor to prevent instantiation
- Consider a more concise method name
- Add documentation for the use case
+/** + * Utility class for generating unique keys for entities. + */ -public class KeyGeneratorUtil { +public final class KeyGeneratorUtil { + + private KeyGeneratorUtil() { + // Prevent instantiation + } + /** + * Generates a unique customer key using UUID. + * @return A unique UUID string for customer identification + */ public static String generateUUIDCustomerKey() { return UUID.randomUUID().toString(); } }src/test/java/life/mosu/mosuserver/FaqServiceTest.java (1)
13-36: Test adapts to renamed repository – minor nitpick on namingVariable
faqJpaRepositoryis still mocked but the field name remains the same – 👍.
Optional: rename the parameter in thesetUp()method (faqJpaRepository) to keep IDE “name shadowing” warnings away.No functional issues.
Also applies to: 46-55
src/main/java/life/mosu/mosuserver/application/inquiry/InquiryService.java (1)
53-64: Potential double query & redundant existence-check
inquiryAnswerJpaRepository.findByInquiryId(postId).ifPresent(...)performs an extra select beforeinquiryAnswerService.deleteInquiryAnswer(postId), which almost certainly queries again.
Either:- inquiryAnswerJpaRepository.findByInquiryId(postId).ifPresent(answer -> { - inquiryAnswerService.deleteInquiryAnswer(postId); - }); + inquiryAnswerService.deleteInquiryAnswer(postId); // make delete idempotentor move the existence check inside
InquiryAnswerService.src/main/java/life/mosu/mosuserver/presentation/oauth/OAuthController.java (1)
26-26: Consider supporting multiple OAuth providersThe path is hardcoded to
/api/v1/oauth2/callback/kakao, limiting support to only Kakao. Consider making the provider configurable or accepting it as a parameter to support multiple OAuth providers in the future.src/main/java/life/mosu/mosuserver/domain/user/UserJpaEntity.java (1)
80-86: Consider adding validation to update methodThe
updateOAuthUsermethod should validate inputs to ensure data integrity.public void updateOAuthUser( Gender gender, String name, LocalDate birth) { + if (name == null || name.trim().isEmpty()) { + throw new IllegalArgumentException("Name cannot be null or empty"); + } this.gender = gender; this.name = name; this.birth = birth; }src/main/java/life/mosu/mosuserver/global/initializer/DatabaseInitializer.java (1)
60-65: Add environment check for additional safetyWhile the count check prevents re-initialization, consider adding an explicit environment check as an additional safety measure.
@PostConstruct public void init() { + String activeProfile = System.getProperty("spring.profiles.active", ""); + if (activeProfile.contains("prod")) { + log.warn("Database initializer is disabled in production environment"); + return; + } + if (userRepository.count() > 0 || schoolRepository.count() > 0) { log.info("이미 더미 데이터가 존재하여 전체 초기화를 건너뜁니다."); return; }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (40)
src/main/java/life/mosu/mosuserver/application/faq/FaqAttachmentService.java(4 hunks)src/main/java/life/mosu/mosuserver/application/faq/FaqService.java(4 hunks)src/main/java/life/mosu/mosuserver/application/inquiry/InquiryAnswerAttachmentService.java(2 hunks)src/main/java/life/mosu/mosuserver/application/inquiry/InquiryAnswerService.java(4 hunks)src/main/java/life/mosu/mosuserver/application/inquiry/InquiryAttachmentService.java(4 hunks)src/main/java/life/mosu/mosuserver/application/inquiry/InquiryService.java(5 hunks)src/main/java/life/mosu/mosuserver/application/notice/NoticeAttachmentService.java(5 hunks)src/main/java/life/mosu/mosuserver/application/notice/NoticeService.java(4 hunks)src/main/java/life/mosu/mosuserver/application/oauth/OAuthUserService.java(1 hunks)src/main/java/life/mosu/mosuserver/application/profile/ProfileService.java(2 hunks)src/main/java/life/mosu/mosuserver/application/user/UserService.java(1 hunks)src/main/java/life/mosu/mosuserver/domain/admin/ApplicationQueryRepositoryImpl.java(1 hunks)src/main/java/life/mosu/mosuserver/domain/application/Lunch.java(0 hunks)src/main/java/life/mosu/mosuserver/domain/event/EventJpaEntity.java(0 hunks)src/main/java/life/mosu/mosuserver/domain/faq/FaqAttachmentJpaRepository.java(1 hunks)src/main/java/life/mosu/mosuserver/domain/faq/FaqJpaRepository.java(1 hunks)src/main/java/life/mosu/mosuserver/domain/inquiry/InquiryAttachmentJpaRepository.java(1 hunks)src/main/java/life/mosu/mosuserver/domain/inquiry/InquiryJpaRepository.java(1 hunks)src/main/java/life/mosu/mosuserver/domain/inquiryAnswer/InquiryAnswerAttachmentJpaRepository.java(1 hunks)src/main/java/life/mosu/mosuserver/domain/inquiryAnswer/InquiryAnswerJpaRepository.java(1 hunks)src/main/java/life/mosu/mosuserver/domain/notice/NoticeAttachmentJpaRepository.java(1 hunks)src/main/java/life/mosu/mosuserver/domain/notice/NoticeJpaRepository.java(1 hunks)src/main/java/life/mosu/mosuserver/domain/serviceterm/ServiceTermAgreementJpaEntity.java(0 hunks)src/main/java/life/mosu/mosuserver/domain/serviceterm/ServiceTermJpaEntity.java(0 hunks)src/main/java/life/mosu/mosuserver/domain/user/UserJpaEntity.java(2 hunks)src/main/java/life/mosu/mosuserver/global/config/SecurityConfig.java(1 hunks)src/main/java/life/mosu/mosuserver/global/initializer/DatabaseInitializer.java(1 hunks)src/main/java/life/mosu/mosuserver/global/initializer/SchoolInitializer.java(0 hunks)src/main/java/life/mosu/mosuserver/global/initializer/UserAndProfileInitializer.java(0 hunks)src/main/java/life/mosu/mosuserver/global/util/KeyGeneratorUtil.java(1 hunks)src/main/java/life/mosu/mosuserver/infra/config/SwaggerConfig.java(1 hunks)src/main/java/life/mosu/mosuserver/presentation/admin/dto/ApplicationListResponse.java(2 hunks)src/main/java/life/mosu/mosuserver/presentation/admin/dto/StudentListResponse.java(1 hunks)src/main/java/life/mosu/mosuserver/presentation/oauth/AccessTokenFilter.java(1 hunks)src/main/java/life/mosu/mosuserver/presentation/oauth/OAuthController.java(2 hunks)src/main/java/life/mosu/mosuserver/presentation/oauth/TokenExceptionFilter.java(1 hunks)src/main/java/life/mosu/mosuserver/presentation/profile/dto/ProfileDetailResponse.java(3 hunks)src/main/java/life/mosu/mosuserver/presentation/user/CustomerKeyResponse.java(1 hunks)src/main/java/life/mosu/mosuserver/presentation/user/UserController.java(1 hunks)src/test/java/life/mosu/mosuserver/FaqServiceTest.java(4 hunks)
💤 Files with no reviewable changes (6)
- src/main/java/life/mosu/mosuserver/domain/application/Lunch.java
- src/main/java/life/mosu/mosuserver/domain/event/EventJpaEntity.java
- src/main/java/life/mosu/mosuserver/domain/serviceterm/ServiceTermJpaEntity.java
- src/main/java/life/mosu/mosuserver/domain/serviceterm/ServiceTermAgreementJpaEntity.java
- src/main/java/life/mosu/mosuserver/global/initializer/SchoolInitializer.java
- src/main/java/life/mosu/mosuserver/global/initializer/UserAndProfileInitializer.java
🧰 Additional context used
🧬 Code Graph Analysis (1)
src/main/java/life/mosu/mosuserver/domain/user/UserJpaEntity.java (1)
src/main/java/life/mosu/mosuserver/global/util/KeyGeneratorUtil.java (1)
KeyGeneratorUtil(5-10)
🔇 Additional comments (32)
src/main/java/life/mosu/mosuserver/presentation/admin/dto/StudentListResponse.java (1)
26-26: LGTM! Swagger example updated for better user experience.The update from enum-like
"HIGH_1"to Korean"고등학교 1학년"improves API documentation clarity and aligns with the localization effort.src/main/java/life/mosu/mosuserver/presentation/admin/dto/ApplicationListResponse.java (1)
23-24: Field type changes and Swagger examples updated consistently.The conversion of
gender,educationLevel, andgradefrom enum types to String types with Korean examples improves API usability and aligns with the localization effort.Also applies to: 35-36, 41-42
src/main/java/life/mosu/mosuserver/presentation/profile/dto/ProfileDetailResponse.java (1)
44-49: Factory method enum conversions implemented correctly.The conversion to Korean strings using
.getGenderName(),.getEducationName(), and.getGradeName()is consistent with the repository implementation and maintains the localization pattern.src/main/java/life/mosu/mosuserver/domain/notice/NoticeAttachmentJpaRepository.java (1)
6-7: LGTM: Consistent interface renaming.The renaming from
NoticeAttachmentRepositorytoNoticeAttachmentJpaRepositoryaligns with the standardization effort mentioned in the PR summary. The interface functionality remains unchanged.src/main/java/life/mosu/mosuserver/domain/notice/NoticeJpaRepository.java (1)
5-5: LGTM: Consistent interface renaming.The renaming from
NoticeRepositorytoNoticeJpaRepositoryfollows the same standardization pattern as other repository interfaces in this PR.src/main/java/life/mosu/mosuserver/presentation/oauth/TokenExceptionFilter.java (1)
1-29: Critical: Confirm OAuth exception handling strategy after removing TokenExceptionFilterOur search shows that
TokenExceptionFilteris fully commented out and no other*ExceptionFilterexists to catchCustomRuntimeExceptionduring the OAuth filter chain. WhileGlobalExceptionHandlerhandlesCustomRuntimeExceptionin controllers, exceptions thrown in servlet filters may bypass it.Files needing your attention:
- src/main/java/life/mosu/mosuserver/presentation/oauth/TokenExceptionFilter.java
- src/main/java/life/mosu/mosuserver/global/exception/GlobalExceptionHandler.java
Please verify that:
- The removal of
TokenExceptionFilteris intentional (not a temporary change).- A replacement mechanism captures and converts OAuth-related token exceptions early in the filter chain.
- Security and integration tests cover token errors to prevent raw stack traces or default HTTP 500 responses.
src/main/java/life/mosu/mosuserver/global/config/SecurityConfig.java (1)
45-45: Verify reliance on method-level security and intentional CORS disablementIt looks like you’ve switched all HTTP-level authorization to
permitAll()and disabled CORS, but you still have:
@EnableWebSecurityand@EnableMethodSecurityin SecurityConfig- Controller-level
@PreAuthorizeon ProfileController and ApplicationControllerThis means you’re relying entirely on Spring’s method-level security for access control, and no filters will enforce token validation at the HTTP layer.
Please confirm:
• Is it intentional to leave the HTTP security chain fully open (no token filters or URL-based rules)?
• Are all secured endpoints covered by method-level annotations today, and will you add annotations for admin routes?
• Should CORS remain disabled, or do you plan to configure allowed origins?src/main/java/life/mosu/mosuserver/domain/faq/FaqAttachmentJpaRepository.java (1)
6-9: Rename looks good – consider adding@Repositoryonly if custom behaviour is added laterSpring Data will auto-detect because it extends
JpaRepository; no functional issues observed.src/main/java/life/mosu/mosuserver/domain/faq/FaqJpaRepository.java (1)
6-8: Consistent JPA suffix – OKInterface rename aligns with the new convention; no further comments.
src/main/java/life/mosu/mosuserver/domain/inquiry/InquiryJpaRepository.java (1)
5-7: Signature remains intact after renameExtending
InquiryQueryRepositoryis preserved; nothing else changed.src/main/java/life/mosu/mosuserver/domain/inquiry/InquiryAttachmentJpaRepository.java (1)
6-9: Repository rename looks goodThe rename to
InquiryAttachmentJpaRepositorycleanly conveys the persistence technology in use without altering behaviour. No issues spotted.src/main/java/life/mosu/mosuserver/domain/inquiryAnswer/InquiryAnswerJpaRepository.java (1)
6-9: Interface rename acknowledgedConsistent with the new naming convention, no functional or stylistic issues found.
src/main/java/life/mosu/mosuserver/domain/inquiryAnswer/InquiryAnswerAttachmentJpaRepository.java (1)
6-9: No concernsThe JPA-specific interface is clear and concise.
src/main/java/life/mosu/mosuserver/application/notice/NoticeService.java (1)
35-42: Possibility of N+1 attachment queries
getNoticeWithAttachmentsmaps eachNoticeJpaEntitytotoNoticeResponse, which in turn callsattachmentService.toAttachmentResponses. If attachments are lazily loaded, this loops N queries. Consider fetching notices with attachments in a single query or batching viajoin fetch.src/main/java/life/mosu/mosuserver/infra/config/SwaggerConfig.java (1)
21-23: LGTM! Good addition for local development support.The addition of a local development server configuration is a practical improvement that enhances the developer experience by allowing API testing through Swagger UI in local environments.
src/main/java/life/mosu/mosuserver/application/inquiry/InquiryAnswerAttachmentService.java (2)
6-6: LGTM! Repository interface renaming improves naming consistency.The repository interface renaming from
InquiryAnswerAttachmentRepositorytoInquiryAnswerAttachmentJpaRepositoryis part of a systematic refactoring effort to standardize repository naming across the codebase.
23-23: LGTM! Field declaration updated consistently.The field declaration has been updated to use the renamed repository interface, maintaining consistency with the import change.
src/main/java/life/mosu/mosuserver/presentation/user/CustomerKeyResponse.java (1)
3-10: LGTM! Well-structured response record.The
CustomerKeyResponserecord is well-designed with:
- Appropriate use of Java records for data transfer
- Clean static factory method following common patterns
- Simple and focused structure
src/main/java/life/mosu/mosuserver/application/faq/FaqAttachmentService.java (3)
6-6: LGTM! Repository interface renaming maintains consistency.The import change from
FaqAttachmentRepositorytoFaqAttachmentJpaRepositoryis consistent with the systematic repository interface renaming across the codebase.
23-23: LGTM! Field declaration updated consistently.The repository field has been updated to use the renamed interface, maintaining consistency with the import change.
34-34: LGTM! Repository usage updated consistently.All repository method calls have been updated to use the renamed field consistently throughout the service.
src/main/java/life/mosu/mosuserver/application/notice/NoticeAttachmentService.java (3)
6-6: LGTM! Repository interface renaming maintains consistency.The import change from
NoticeAttachmentRepositorytoNoticeAttachmentJpaRepositorycompletes the systematic repository interface renaming pattern across the attachment services.
24-24: LGTM! Field declaration updated consistently.The repository field has been updated to use the renamed interface, maintaining consistency with the import change.
34-34: LGTM! Repository usage updated consistently.All repository method calls throughout the service have been updated to use the renamed field consistently.
src/main/java/life/mosu/mosuserver/application/profile/ProfileService.java (3)
21-21: Good addition of user validation dependency.The addition of
UserJpaRepositorydependency enables proper user existence validation before profile registration, which improves data integrity.
26-28: Excellent user validation implementation.The user existence check with proper error handling using
USER_NOT_FOUNDerror code follows consistent error handling patterns throughout the codebase.
33-33: Good integration of user state management.The call to
user.registerProfile()appropriately updates the user's state during profile registration, maintaining consistency between user and profile entities.src/main/java/life/mosu/mosuserver/application/inquiry/InquiryAttachmentService.java (1)
6-6: Consistent repository interface refactoring.The systematic replacement of
InquiryAttachmentRepositorywithInquiryAttachmentJpaRepositoryacross imports, field declarations, and method calls is well-executed and maintains all existing functionality.Also applies to: 21-21, 31-31, 43-43, 45-45, 51-51
src/main/java/life/mosu/mosuserver/application/faq/FaqService.java (1)
5-5: Consistent repository interface refactoring.The systematic replacement of
FaqRepositorywithFaqJpaRepositoryacross imports, field declarations, and method calls is well-executed and maintains all existing functionality.Also applies to: 24-24, 30-30, 38-38, 47-47, 55-55, 59-59, 70-70
src/main/java/life/mosu/mosuserver/application/user/UserService.java (1)
1-22: Well-implemented new service class.The
UserServiceclass provides a clean and efficient implementation for retrieving customer keys. The use ofOptional.map()andorElseThrow()demonstrates good functional programming practices and proper error handling. This aligns well with the PR objectives for adding customer key return functionality.src/main/java/life/mosu/mosuserver/application/inquiry/InquiryAnswerService.java (1)
4-4: Consistent repository interface refactoring.The systematic replacement of
InquiryRepositoryandInquiryAnswerRepositorywith their JPA-specific counterparts across imports, field declarations, and method calls is well-executed and maintains all existing functionality.Also applies to: 6-6, 23-24, 30-30, 34-34, 45-45, 48-48, 56-56, 68-68, 72-72, 79-79
src/main/java/life/mosu/mosuserver/domain/user/UserJpaEntity.java (1)
64-78: LGTM! Clean customer key generationThe automatic UUID generation for customer keys in the constructor is a good approach that ensures uniqueness and removes the burden from callers.
| @Schema(description = "학력 (예: ENROLLED, GRADUATED)", example = "ENROLLED") | ||
| Education education, | ||
| String education, |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Update Swagger examples for consistency.
The field type changes are correct, but the Swagger examples should be updated to Korean strings for consistency with other DTOs.
Update the Swagger examples to match the localization pattern:
- @Schema(description = "학력 (예: ENROLLED, GRADUATED)", example = "ENROLLED")
+ @Schema(description = "학력 (예: 재학생, 졸업생)", example = "재학생")
String education,
- @Schema(description = "학년", example = "HIGH_1")
+ @Schema(description = "학년", example = "고등학교 1학년")
String gradeAlso applies to: 34-35
🤖 Prompt for AI Agents
In
src/main/java/life/mosu/mosuserver/presentation/profile/dto/ProfileDetailResponse.java
around lines 28-29 and 34-35, the Swagger @Schema example values for the
education field are currently in English ("ENROLLED"). Update these example
values to their Korean equivalents to maintain consistency with other DTOs and
the localization pattern used in the project.
| //package life.mosu.mosuserver.presentation.oauth; | ||
| // | ||
| //import static org.springframework.http.HttpHeaders.AUTHORIZATION; | ||
| // | ||
| //import jakarta.servlet.FilterChain; | ||
| //import jakarta.servlet.ServletException; | ||
| //import jakarta.servlet.http.HttpServletRequest; | ||
| //import jakarta.servlet.http.HttpServletResponse; | ||
| //import java.io.IOException; | ||
| //import life.mosu.mosuserver.application.auth.AccessTokenService; | ||
| //import lombok.RequiredArgsConstructor; | ||
| //import org.springframework.beans.factory.annotation.Value; | ||
| //import org.springframework.security.core.Authentication; | ||
| //import org.springframework.security.core.context.SecurityContextHolder; | ||
| //import org.springframework.stereotype.Component; | ||
| //import org.springframework.util.ObjectUtils; | ||
| //import org.springframework.web.filter.OncePerRequestFilter; | ||
| // | ||
| //@Component | ||
| //@RequiredArgsConstructor | ||
| //public class AccessTokenFilter extends OncePerRequestFilter { | ||
| // | ||
| // private static final String TOKEN_PREFIX = "Bearer "; | ||
| // private final AccessTokenService accessTokenService; | ||
| // | ||
| // @Value("${endpoints.reissue}") | ||
| // private String reissueEndpoint; | ||
| // | ||
| // @Override | ||
| // protected void doFilterInternal( | ||
| // final HttpServletRequest request, | ||
| // final HttpServletResponse response, | ||
| // final FilterChain filterChain | ||
| // ) throws ServletException, IOException { | ||
| // if (request.getRequestURI().equals(reissueEndpoint)) { | ||
| // filterChain.doFilter(request, response); | ||
| // return; | ||
| // } | ||
| // | ||
| // if (request.getRequestURI().startsWith("/api/v1/oauth2")) { | ||
| // filterChain.doFilter(request, response); | ||
| // return; | ||
| // } | ||
| // | ||
| // final String accessToken = resolveToken(request); | ||
| // if (accessToken != null) { | ||
| // setAuthentication(accessToken); | ||
| // } | ||
| // filterChain.doFilter(request, response); | ||
| // } | ||
| // | ||
| // private void setAuthentication(final String accessToken) { | ||
| // final Authentication authentication = accessTokenService.getAuthentication(accessToken); | ||
| // SecurityContextHolder.getContext().setAuthentication(authentication); | ||
| // } | ||
| // | ||
| // private String resolveToken(final HttpServletRequest request) { | ||
| // final String token = request.getHeader(AUTHORIZATION); | ||
| // if (ObjectUtils.isEmpty(token) || !token.startsWith(TOKEN_PREFIX)) { | ||
| // return null; | ||
| // } | ||
| // return token.substring(TOKEN_PREFIX.length()); | ||
| // } | ||
| //} No newline at end of file |
There was a problem hiding this comment.
Fully-commented source file introduces maintenance & security risks – delete or formally deprecate instead
The entire compilation unit now contains only comments.
Side effects:
- ✂️ No
AccessTokenFilterclass is produced, but the file is still compiled, creating dead weight in every build. - 🛡 OAuth authentication previously enforced by this filter disappears silently; unless a replacement filter is configured the API is now publicly accessible.
- 🧭 Future readers waste time deciphering whether this filter is meant to be active.
Action items
-// (commented code)
+// @Deprecated – kept for reference only. Will be removed in MOSU-XXX.
+
+/* If historical reference is really required, move the block to
+ docs/legacy/AccessTokenFilter.md and delete this .java file. */Or simply delete the file altogether and rely on VCS history.
Also double-check SecurityConfig to confirm another filter (e.g. JwtAuthenticationFilter) now guards the protected endpoints.
Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In src/main/java/life/mosu/mosuserver/presentation/oauth/AccessTokenFilter.java
lines 1 to 64, the entire AccessTokenFilter class is commented out, leaving no
active code and causing potential security risks by removing OAuth enforcement
silently. To fix this, either delete the file entirely to remove dead code or
formally deprecate it with proper annotations and comments explaining its
status. Additionally, verify in SecurityConfig that another filter like
JwtAuthenticationFilter is properly configured to protect the endpoints before
removing this filter.
| private final InquiryAttachmentService inquiryAttachmentService; | ||
| private final InquiryRepository inquiryRepository; | ||
| private final InquiryJpaRepository inquiryJpaRepository; | ||
| private final InquiryAnswerService inquiryAnswerService; | ||
| private final InquiryAnswerRepository inquiryAnswerRepository; | ||
| private final InquiryAnswerJpaRepository inquiryAnswerJpaRepository; | ||
|
|
There was a problem hiding this comment.
🛠️ Refactor suggestion
Avoid mixing service & repository layers for the same aggregate
Injecting both InquiryAnswerService and InquiryAnswerJpaRepository in the same service breaks layer isolation and makes future refactors harder.
deleteInquiry only needs a presence-check before delegating to InquiryAnswerService. Expose that check via the service (or let the delete method be idempotent) and drop the direct repository dependency here.
🤖 Prompt for AI Agents
In src/main/java/life/mosu/mosuserver/application/inquiry/InquiryService.java
around lines 24 to 28, avoid injecting both InquiryAnswerService and
InquiryAnswerJpaRepository to maintain layer isolation. Remove the direct
dependency on InquiryAnswerJpaRepository and instead expose a presence-check
method in InquiryAnswerService or make the deleteInquiry method idempotent so
that the repository is only accessed through the service layer.
| public void deleteNotice(Long noticeId) { | ||
| NoticeJpaEntity noticeEntity = getNoticeOrThrow(noticeId); | ||
| noticeRepository.delete(noticeEntity); | ||
| noticeJpaRepository.delete(noticeEntity); | ||
| attachmentService.deleteAttachment(noticeEntity); | ||
| } |
There was a problem hiding this comment.
Delete child entities before parent to avoid FK violations
noticeJpaRepository.delete(noticeEntity); executes before attachment deletion.
Unless the DB FK is ON DELETE CASCADE, this can break referential integrity. Safer order:
- noticeJpaRepository.delete(noticeEntity);
- attachmentService.deleteAttachment(noticeEntity);
+ attachmentService.deleteAttachment(noticeEntity);
+ noticeJpaRepository.delete(noticeEntity);📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| public void deleteNotice(Long noticeId) { | |
| NoticeJpaEntity noticeEntity = getNoticeOrThrow(noticeId); | |
| noticeRepository.delete(noticeEntity); | |
| noticeJpaRepository.delete(noticeEntity); | |
| attachmentService.deleteAttachment(noticeEntity); | |
| } | |
| public void deleteNotice(Long noticeId) { | |
| NoticeJpaEntity noticeEntity = getNoticeOrThrow(noticeId); | |
| attachmentService.deleteAttachment(noticeEntity); | |
| noticeJpaRepository.delete(noticeEntity); | |
| } |
🤖 Prompt for AI Agents
In src/main/java/life/mosu/mosuserver/application/notice/NoticeService.java
around lines 52 to 56, the current code deletes the parent notice entity before
deleting its child attachments, which can cause foreign key constraint
violations if the database does not have ON DELETE CASCADE enabled. To fix this,
reorder the deletion calls to first delete the attachments via
attachmentService.deleteAttachment(noticeEntity) and only then delete the notice
entity with noticeJpaRepository.delete(noticeEntity).
| FaqJpaEntity faqEntity = faqJpaRepository.findById(faqId) | ||
| .orElseThrow(() -> new CustomRuntimeException(ErrorCode.FILE_NOT_FOUND)); |
There was a problem hiding this comment.
Fix inconsistent error code usage.
The error code should be FAQ_NOT_FOUND instead of FILE_NOT_FOUND to be consistent with other methods in this service that use the correct FAQ-specific error code.
- FaqJpaEntity faqEntity = faqJpaRepository.findById(faqId)
- .orElseThrow(() -> new CustomRuntimeException(ErrorCode.FILE_NOT_FOUND));
+ FaqJpaEntity faqEntity = faqJpaRepository.findById(faqId)
+ .orElseThrow(() -> new CustomRuntimeException(ErrorCode.FAQ_NOT_FOUND));📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| FaqJpaEntity faqEntity = faqJpaRepository.findById(faqId) | |
| .orElseThrow(() -> new CustomRuntimeException(ErrorCode.FILE_NOT_FOUND)); | |
| FaqJpaEntity faqEntity = faqJpaRepository.findById(faqId) | |
| .orElseThrow(() -> new CustomRuntimeException(ErrorCode.FAQ_NOT_FOUND)); |
🤖 Prompt for AI Agents
In src/main/java/life/mosu/mosuserver/application/faq/FaqService.java at lines
68-69, the error code used when throwing the exception for a missing FAQ is
incorrectly set to FILE_NOT_FOUND. Change this error code to FAQ_NOT_FOUND to
maintain consistency with other methods in the service that handle FAQ-related
errors.
| @GetMapping("/customer-key") | ||
| public ResponseEntity<ApiResponseWrapper<CustomerKeyResponse>> getCustomerKey( | ||
| @RequestParam Long userId | ||
| ) { | ||
| String customerKey = userService.getCustomerKey(userId); | ||
|
|
||
| return ResponseEntity.ok(ApiResponseWrapper.success(HttpStatus.OK, "CustomerKey 조회 성공", | ||
| CustomerKeyResponse.from(customerKey))); | ||
| } |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Add input validation for userId parameter
The userId parameter should be validated to ensure it's not null and potentially check for positive values.
Apply this diff to add validation:
+import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.Positive;
+import org.springframework.validation.annotation.Validated;
+@Validated
@RestController
@RequestMapping("/user")
@RequiredArgsConstructor
public class UserController {
private final UserService userService;
@GetMapping("/customer-key")
public ResponseEntity<ApiResponseWrapper<CustomerKeyResponse>> getCustomerKey(
- @RequestParam Long userId
+ @RequestParam @NotNull @Positive Long userId
) {
String customerKey = userService.getCustomerKey(userId);
return ResponseEntity.ok(ApiResponseWrapper.success(HttpStatus.OK, "CustomerKey 조회 성공",
CustomerKeyResponse.from(customerKey)));
}🤖 Prompt for AI Agents
In src/main/java/life/mosu/mosuserver/presentation/user/UserController.java
around lines 20 to 28, the userId parameter in the getCustomerKey method lacks
validation. Add validation annotations to ensure userId is not null and is a
positive value, such as using @NotNull and @Positive on the userId parameter.
Also, enable validation by adding @Validated on the controller class if not
already present.
| return userRepository.findByLoginId(info.email()) | ||
| .map(existingUser -> { | ||
| existingUser.updateOAuthUser(info.gender(), info.name(), | ||
| info.birthDay() != null ? info.birthDay() : LocalDate.of(1900, 1, 1)); |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Consider using null instead of placeholder date
Using LocalDate.of(1900, 1, 1) as a default birth date could lead to incorrect age calculations or business logic issues. Consider keeping it null if the birth date is not provided.
Also applies to: 57-58
🤖 Prompt for AI Agents
In src/main/java/life/mosu/mosuserver/application/oauth/OAuthUserService.java at
lines 49 and 57-58, replace the placeholder date LocalDate.of(1900, 1, 1) with
null when the birthDay is not provided. This means changing the conditional
expressions to return null instead of the default date to avoid incorrect age
calculations or business logic errors.
| .userRole(UserRole.ROLE_USER) | ||
| .birth(info.birthDay() != null ? info.birthDay() | ||
| : LocalDate.of(1900, 1, 1)) | ||
| .userRole(UserRole.ROLE_PENDING) |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Verify ROLE_PENDING workflow
The change from ROLE_USER to ROLE_PENDING suggests users must complete additional steps before full access. Ensure:
- Security configurations properly handle ROLE_PENDING users
- There's a clear flow for users to transition from ROLE_PENDING to ROLE_USER
- Existing functionality expecting ROLE_USER is updated
🏁 Script executed:
#!/bin/bash
# Search for ROLE_PENDING and ROLE_USER usage to verify proper handling
echo "=== Searching for ROLE_PENDING usage ==="
rg "ROLE_PENDING" -A 3 -B 3
echo -e "\n=== Searching for security configurations ==="
fd -e java -e yml -e properties | xargs rg -l "hasRole|hasAuthority|SecurityConfig"
echo -e "\n=== Checking registerProfile usage (transitions to ROLE_USER) ==="
ast-grep --pattern 'registerProfile()'Length of output: 3129
Fix ROLE_PENDING access and transition logic
It looks like we’re setting new users to ROLE_PENDING, but:
- SecurityConfig.java doesn’t include ROLE_PENDING anywhere (all
hasRole()checks still target USER/ADMIN). - There’s no code path that upgrades a pending user to ROLE_USER (we didn’t find any
registerProfile()or similar transition method). - Controllers guarded by
hasRole("USER")will reject all pending accounts.
Please update as follows:
• In global/config/SecurityConfig.java
– Define which endpoints pending users may access (e.g. profile completion, email verification)
– Ensure pending users are explicitly denied or redirected elsewhere for protected routes
• In the user‐management flow (e.g. OAuthUserService or a new service)
– Implement a clear “approve” or “complete profile” endpoint that updates UserRole.ROLE_PENDING → ROLE_USER
– Add and wire a method (e.g. approvePendingUser(userId)) and call it after required steps
• In any controllers currently using hasRole("USER")
– Consider adding a custom exception or handler for pending users to guide them through completion
🤖 Prompt for AI Agents
In src/main/java/life/mosu/mosuserver/application/oauth/OAuthUserService.java at
line 59 and related files, the issue is that new users are assigned ROLE_PENDING
but the security configuration and user flow do not handle this role properly.
To fix this, update SecurityConfig.java to define accessible endpoints for
ROLE_PENDING users and restrict protected routes accordingly. Implement a method
in OAuthUserService or a new service to transition users from ROLE_PENDING to
ROLE_USER after profile completion or verification, such as an
approvePendingUser(userId) method. Also, modify controllers using
hasRole("USER") to handle pending users gracefully, possibly by adding custom
exceptions or handlers to guide them through the completion process.
| .agreedToTermsOfService(true) | ||
| .agreedToPrivacyPolicy(true) | ||
| .agreedToMarketing(false) |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Verify user consent for agreement flags
Hardcoding agreement flags (especially setting agreedToMarketing to false while others are true) may not accurately reflect user consent obtained during OAuth login. Consider:
- Obtaining these consents from the OAuth provider if available
- Deferring consent collection to a separate user flow
- Setting all to false initially and prompting users to agree
🏁 Script executed:
#!/bin/bash
# Show the beginning of OAuthUserService to understand how consents are set
sed -n '1,120p' src/main/java/life/mosu/mosuserver/application/oauth/OAuthUserService.java
# Locate all occurrences of consent flags in the file
rg -n "agreedTo" -A2 src/main/java/life/mosu/mosuserver/application/oauth/OAuthUserService.javaLength of output: 3417
Reconsider default consent flags in OAuthUserService
Hardcoding agreedToTermsOfService(true) and agreedToPrivacyPolicy(true)—and only setting marketing to false—risks recording consents that the user never explicitly granted. Update this logic to accurately capture or defer consent:
• File: src/main/java/life/mosu/mosuserver/application/oauth/OAuthUserService.java
Lines 60–62 currently read:
.agreedToTermsOfService(true)
.agreedToPrivacyPolicy(true)
.agreedToMarketing(false)
• Suggested approaches:
- Pull consent flags from
OAuthUserInfoif the provider returns them. - Initialize all three flags to
falseby default, then prompt the user in a follow-up flow. - If you do receive explicit consent via OAuth, map those values instead of hardcoding.
Example diff:
- .agreedToTermsOfService(true)
- .agreedToPrivacyPolicy(true)
- .agreedToMarketing(false)
+ .agreedToTermsOfService(info.termsAccepted() != null
+ ? info.termsAccepted() : false)
+ .agreedToPrivacyPolicy(info.privacyAccepted() != null
+ ? info.privacyAccepted() : false)
+ .agreedToMarketing(info.marketingAccepted() != null
+ ? info.marketingAccepted() : false)Or, if your provider doesn’t supply these fields, default all to false and implement a UI step to collect and persist user consent.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| .agreedToTermsOfService(true) | |
| .agreedToPrivacyPolicy(true) | |
| .agreedToMarketing(false) | |
| .agreedToTermsOfService(info.termsAccepted() != null | |
| ? info.termsAccepted() : false) | |
| .agreedToPrivacyPolicy(info.privacyAccepted() != null | |
| ? info.privacyAccepted() : false) | |
| .agreedToMarketing(info.marketingAccepted() != null | |
| ? info.marketingAccepted() : false) |
🤖 Prompt for AI Agents
In src/main/java/life/mosu/mosuserver/application/oauth/OAuthUserService.java
around lines 60 to 62, the consent flags for terms of service and privacy policy
are hardcoded to true, which may inaccurately record user consent. Modify the
code to either extract these consent flags from the OAuthUserInfo object if
available or default all consent flags (terms of service, privacy policy,
marketing) to false. Then ensure that explicit user consent is collected and
persisted in a subsequent user interaction flow rather than assuming consent at
this stage.
| @Slf4j | ||
| @Component | ||
| @RequiredArgsConstructor | ||
| public class DatabaseInitializer { |
There was a problem hiding this comment.
Restrict initializer to non-production environments
This database initializer should not run in production environments. Consider using Spring profiles to control when it's active.
Apply this change:
-@Component
+@Component
+@Profile({"dev", "test", "local"})
@RequiredArgsConstructor
public class DatabaseInitializer {Or use a configuration property:
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
@Component
+@ConditionalOnProperty(
+ name = "app.database.initialize",
+ havingValue = "true",
+ matchIfMissing = false
+)
@RequiredArgsConstructor
public class DatabaseInitializer {🤖 Prompt for AI Agents
In
src/main/java/life/mosu/mosuserver/global/initializer/DatabaseInitializer.java
around lines 44 to 47, the DatabaseInitializer class should be restricted to run
only in non-production environments. To fix this, annotate the class with
@Profile specifying the profiles where it should be active, such as
@Profile("!prod") to exclude production. Alternatively, use a configuration
property with @ConditionalOnProperty to enable or disable the initializer based
on environment-specific settings.
✨ 구현한 기능
📢 논의하고 싶은 내용
🎸 기타
Summary by CodeRabbit
New Features
Improvements
Refactor
Bug Fixes
Chores