Skip to content

Conversation

@chominju02
Copy link
Contributor

@chominju02 chominju02 commented Jul 21, 2025

✨ 구현한 기능

📢 논의하고 싶은 내용

🎸 기타

Summary by CodeRabbit

  • Refactor

    • Renamed a field in refund-related data to improve clarity.
    • Updated enum handling and annotations in file storage logic for better consistency.
    • Improved method naming and encapsulation in inquiry answer handling.
    • Removed unused cache manager reference in application service.
  • Documentation

    • Added descriptive comments to clarify the structure of application requests.
  • Tests

    • Introduced new test dependencies for containerized integration testing.
    • Added an empty test method for future test expansion.
    • Added new configuration files for test and security environments.

…mApplicationId and adjust related constructor; enhance ApplicationRequest with additional documentation for examApplication field
…gic and add validation for existing answers; enhance File class to use equals for visibility comparison
@chominju02 chominju02 self-assigned this Jul 21, 2025
@coderabbitai
Copy link

coderabbitai bot commented Jul 21, 2025

Walkthrough

The changes introduce new test dependencies for containerized testing, refactor and clarify code in several service and domain classes, and add two YAML configuration files for test environments. Minor documentation and annotation improvements are made, and a placeholder test method is added to the main test class.

Changes

File(s) Change Summary
build.gradle Added Testcontainers and Spring Boot Testcontainers dependencies for containerized test support.
src/main/java/life/mosu/mosuserver/application/application/ApplicationService.java Removed ExamQuotaCacheManager field and added clarifying comments in the apply method. Minor whitespace cleanup.
src/main/java/life/mosu/mosuserver/application/inquiry/InquiryAnswerService.java Refactored inquiry answer existence checks and renamed inquiry retrieval method. Added encapsulated existence check method.
src/main/java/life/mosu/mosuserver/domain/refund/RefundJpaEntity.java Renamed field and column from applicationSchoolId to examApplicationId and updated imports to be explicit.
src/main/java/life/mosu/mosuserver/infra/storage/domain/File.java Added @MappedSuperclass, explicit enum and column annotations, and improved enum comparison in isPublic() method.
src/main/java/life/mosu/mosuserver/presentation/application/dto/ApplicationRequest.java Added a clarifying Javadoc comment to the agreement field.
src/test/java/life/mosu/mosuserver/MosuServerApplicationTests.java Added an empty test method annotated with @Test.
src/test/resources/application.yml Added new YAML config for test environment with database, Redis, AWS, and other service settings.
src/test/resources/test-security-config.yml Added new YAML config for test security environment with database, Redis, AWS, and service settings.

Sequence Diagram(s)

sequenceDiagram
    participant Test as Test (JUnit/Testcontainers)
    participant SpringBoot as Spring Boot App
    participant MySQL as MySQL (Testcontainers)
    participant Redis as Redis (Testcontainers)
    participant AWS as AWS S3 (Mock/Real)

    Test->>SpringBoot: Start test with @Test
    SpringBoot->>MySQL: Initialize Testcontainers MySQL
    SpringBoot->>Redis: Initialize Testcontainers Redis
    SpringBoot->>AWS: Connect using test credentials
    Test-->>SpringBoot: Run integration tests
    SpringBoot-->>Test: Return test results
Loading

Estimated code review effort

3 (30–60 minutes)

Poem

In the warren of code where containers now dwell,
Test dependencies join, so our tests run well.
Refactored a service, renamed a field,
With YAMLs for settings, our configs are sealed.
A rabbit hops by, with a test in its paw—
"Review me," it squeaks, "with a hop and a hurrah!"
🐇✨

✨ Finishing Touches
  • 📝 Generate Docstrings

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 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.

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 primarily focuses on integrating Querydsl to enable type-safe database interactions across various entities. It also significantly enhances the project's testing infrastructure by introducing Testcontainers for MySQL, ensuring a more robust and isolated environment for integration tests. Additionally, several minor code refactorings and dependency updates contribute to overall code quality.

Highlights

  • Querydsl Integration: This pull request introduces Querydsl by generating Q-classes for a wide range of existing JPA entities, including Application, Event, Exam, Inquiry, Payment, Profile, User, and various associated attachment and file entities. This enables type-safe and more readable database queries throughout the application.
  • Test Infrastructure Enhancement: The testing environment has been significantly upgraded with the addition of Testcontainers for MySQL. This setup, configured in build.gradle and new test YAML files, provides a consistent, isolated, and ephemeral database instance for integration tests, improving test reliability and development workflow.
  • Refactoring and Code Cleanup: Minor refactorings and code improvements were applied across several service and domain classes. This includes removing an unused dependency in ApplicationService, enhancing inquiry answer logic in InquiryAnswerService, and updating enum comparison best practices in File.java.
  • Database Schema Adjustment: The RefundJpaEntity was updated to rename the applicationSchoolId column to examApplicationId, providing a more accurate and descriptive representation of the relationship in the database schema.
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

  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 introduces Querydsl-generated classes and includes several other refactorings and additions. The changes are generally positive, but I've identified a critical bug in InquiryAnswerService related to duplicate-checking logic that must be fixed. I've also provided feedback on improving code clarity and maintainability by removing temporary comments, correcting misplaced documentation, and reducing duplication in test configuration files.

Comment on lines +96 to +100
private void isAnswerAlreadyRegister(Long postId) {
if (inquiryAnswerJpaRepository.existsById(postId)) {
throw new CustomRuntimeException(ErrorCode.INQUIRY_ANSWER_ALREADY_EXISTS);
}
}

Choose a reason for hiding this comment

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

critical

This method contains a critical bug. It uses inquiryAnswerJpaRepository.existsById(postId), which checks the primary key of InquiryAnswerJpaEntity. However, postId is the ID of the parent InquiryJpaEntity. This will not correctly detect if an answer for the given inquiry already exists and could lead to data integrity issues, such as multiple answers for a single inquiry.

The method name isAnswerAlreadyRegister is also a bit unconventional for a validation method that throws an exception. A name like validateAnswerDoesNotExist would be more descriptive.

Suggested change
private void isAnswerAlreadyRegister(Long postId) {
if (inquiryAnswerJpaRepository.existsById(postId)) {
throw new CustomRuntimeException(ErrorCode.INQUIRY_ANSWER_ALREADY_EXISTS);
}
}
private void isAnswerAlreadyRegister(Long postId) {
if (inquiryAnswerJpaRepository.findByInquiryId(postId).isPresent()) {
throw new CustomRuntimeException(ErrorCode.INQUIRY_ANSWER_ALREADY_EXISTS);
}
}

@Transactional
public void createInquiryAnswer(Long postId, InquiryAnswerRequest request) {
InquiryJpaEntity inquiryEntity = getInquiryOrThrow(postId);
isAnswerAlreadyRegister(postId);

Choose a reason for hiding this comment

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

high

The call to isAnswerAlreadyRegister is redundant. There is another check for the same condition on lines 36-38 (if (inquiryAnswerJpaRepository.findByInquiryId(postId).isPresent())).

You should only have one check to avoid confusion and unnecessary database queries. Given that the newly added isAnswerAlreadyRegister method contains a bug, I recommend removing this line and the isAnswerAlreadyRegister method entirely, relying on the existing correct check.

Comment on lines +54 to +56
// examId 가 동일 하냐?
//다른 exam 인데 시간이 같나?
//exam_id lunch_id 쌍으로 포함된 exam_application 이 존재하냐

Choose a reason for hiding this comment

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

medium

These comments appear to be temporary developer notes. To maintain code clarity, they should be removed, or replaced with proper documentation. If they represent important logic that still needs to be implemented, consider creating a ticket in your issue tracker and referencing it here.

Comment on lines +28 to +30
/**
* ExamApplication = exam_id, lunch_id 를 포함하고 있음
*/

Choose a reason for hiding this comment

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

medium

This comment seems to be for the examApplication field but is misplaced. For better readability, it should be a Javadoc comment placed directly above the field it describes.

Comment on lines +1 to +90
server:
port: ${SPRING_PORT}
servlet:
context-path: ${BASE_PATH}
session:
cookie:
same-site: none
secure: false
error:
include-stacktrace: never

spring:
config:
import:
- security-config.yml
datasource:
url: jdbc:tc:mysql:9.0.0:///;
driver-class-name: org.testcontainers.jdbc.ContainerDatabaseDriver
hikari:
maximum-pool-size: 15
minimum-idle: 15

servlet:
multipart:
max-file-size: ${MAX_FILE_SIZE}
max-request-size: ${MAX_REQUEST_SIZE}
jpa:
open-in-view: false
show-sql: true
hibernate:
ddl-auto: create-drop
properties:
hibernate:
show_sql: true
format_sql: true
highlight_sql: true
use_sql_comments: true
jdbc:
time_zone: Asia/Seoul
dialect: org.hibernate.dialect.MySQLDialect
data:
redis:
host: ${REDIS_HOST}
port: ${VELKEY_PORT}
messages:
basename: messages
encoding: UTF-8
mvc:
view:
prefix: /WEB-INF/views/
suffix: .jsp

management:
endpoints:
web:
exposure:
include: "*"

aws:
s3:
bucket-name: ${AWS_BUCKET_NAME}
region: ${AWS_REGION}
access-key: ${AWS_ACCESS_KEY}
secret-key: ${AWS_SECRET_KEY}
presigned-url-expiration-minutes: ${S3_PRESIGNED_URL_EXPIRATION_MINUTES}

logging:
file:
path: ./logs
name: app.log
level:
org:
type:
descriptor:
sql:
BasicBinder: TRACE

toss:
secret-key: test_sk_kYG57Eba3GYBMGeobgbLrpWDOxmA
api:
base-url: https://api.tosspayments.com/v1/payments

alimtalk:
user-id: ${ALIMTALK_USER_ID}
api-key: ${ALIMTALK_API_KEY}
api:
base-url: ${ALIMTALK_URL}

kakao:
channel-id: ${KAKAO_CHANNEL_ID} No newline at end of file

Choose a reason for hiding this comment

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

medium

This configuration file is almost an exact duplicate of src/test/resources/application.yml. This level of duplication can lead to maintenance issues, as changes might be made in one file but forgotten in the other.

To improve maintainability, I recommend refactoring to reduce this duplication. You could create a base common-test.yml with shared properties, and then have other test configuration files import it and override only the necessary values.

Additionally, I noticed the MySQL version in this file (9.0.0) is different from the one in application.yml (8.4.4). If this is intentional, it would be beneficial to add a comment explaining why.

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: 5

🔭 Outside diff range comments (1)
src/main/java/life/mosu/mosuserver/application/inquiry/InquiryAnswerService.java (1)

33-38: Remove redundant duplicate check.

The duplicate answer check is performed twice: once by isAnswerAlreadyRegister(postId) at line 33 and again by the existing logic at lines 36-38. Remove the redundant check to improve code clarity.

     isAnswerAlreadyRegister(postId);
     InquiryJpaEntity inquiryEntity = getInquiry(postId);

-    if (inquiryAnswerJpaRepository.findByInquiryId(postId).isPresent()) {
-        throw new CustomRuntimeException(ErrorCode.INQUIRY_ANSWER_ALREADY_EXISTS);
-    }

     InquiryAnswerJpaEntity answerEntity = inquiryAnswerJpaRepository.save(
🧹 Nitpick comments (4)
src/test/resources/test-security-config.yml (1)

90-90: Add missing newline at end of file.

 kakao:
-  channel-id: ${KAKAO_CHANNEL_ID}
+  channel-id: ${KAKAO_CHANNEL_ID}
+
src/test/java/life/mosu/mosuserver/MosuServerApplicationTests.java (1)

9-11: Improve the placeholder test method.

The empty test method lacks descriptive naming and implementation. Consider either removing it if not needed or implementing actual test logic.

-    @Test
-    void test() {
-    }
+    @Test
+    void contextLoads() {
+        // This test will pass if the application context loads successfully
+    }
src/main/java/life/mosu/mosuserver/application/application/ApplicationService.java (1)

54-56: Consider using English for code comments.

The clarifying comments are helpful but written in Korean. For better code maintainability in international teams, consider using English.

-        // examId 가 동일 하냐?
-        //다른 exam 인데 시간이 같나?
-        //exam_id lunch_id 쌍으로 포함된 exam_application 이 존재하냐
+        // Check if examId is identical
+        // Check if different exams have the same time
+        // Check if exam_application exists with exam_id lunch_id pair
src/test/resources/application.yml (1)

90-90: Add missing newline at end of file.

 kakao:
-  channel-id: ${KAKAO_CHANNEL_ID}
+  channel-id: ${KAKAO_CHANNEL_ID}
+
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between fca6bc4 and ead3254.

⛔ Files ignored due to path filters (33)
  • src/main/generated/life/mosu/mosuserver/domain/application/QApplicationJpaEntity.java is excluded by !**/generated/**
  • src/main/generated/life/mosu/mosuserver/domain/application/QExamTicketImageJpaEntity.java is excluded by !**/generated/**
  • src/main/generated/life/mosu/mosuserver/domain/base/QBaseTimeEntity.java is excluded by !**/generated/**
  • src/main/generated/life/mosu/mosuserver/domain/event/QDurationJpaVO.java is excluded by !**/generated/**
  • src/main/generated/life/mosu/mosuserver/domain/event/QEventAttachmentJpaEntity.java is excluded by !**/generated/**
  • src/main/generated/life/mosu/mosuserver/domain/event/QEventImage.java is excluded by !**/generated/**
  • src/main/generated/life/mosu/mosuserver/domain/event/QEventJpaEntity.java is excluded by !**/generated/**
  • src/main/generated/life/mosu/mosuserver/domain/exam/QAddressJpaVO.java is excluded by !**/generated/**
  • src/main/generated/life/mosu/mosuserver/domain/exam/QExamJpaEntity.java is excluded by !**/generated/**
  • src/main/generated/life/mosu/mosuserver/domain/examapplication/QExamApplicationJpaEntity.java is excluded by !**/generated/**
  • src/main/generated/life/mosu/mosuserver/domain/examapplication/QExamSubjectJpaEntity.java is excluded by !**/generated/**
  • src/main/generated/life/mosu/mosuserver/domain/faq/QFaqAttachmentJpaEntity.java is excluded by !**/generated/**
  • src/main/generated/life/mosu/mosuserver/domain/faq/QFaqFile.java is excluded by !**/generated/**
  • src/main/generated/life/mosu/mosuserver/domain/faq/QFaqJpaEntity.java is excluded by !**/generated/**
  • src/main/generated/life/mosu/mosuserver/domain/inquiry/QInquiryAttachmentJpaEntity.java is excluded by !**/generated/**
  • src/main/generated/life/mosu/mosuserver/domain/inquiry/QInquiryFile.java is excluded by !**/generated/**
  • src/main/generated/life/mosu/mosuserver/domain/inquiry/QInquiryJpaEntity.java is excluded by !**/generated/**
  • src/main/generated/life/mosu/mosuserver/domain/inquiryAnswer/QInquiryAnswerAttachmentEntity.java is excluded by !**/generated/**
  • src/main/generated/life/mosu/mosuserver/domain/inquiryAnswer/QInquiryAnswerFile.java is excluded by !**/generated/**
  • src/main/generated/life/mosu/mosuserver/domain/inquiryAnswer/QInquiryAnswerJpaEntity.java is excluded by !**/generated/**
  • src/main/generated/life/mosu/mosuserver/domain/lunch/QLunchJpaEntity.java is excluded by !**/generated/**
  • src/main/generated/life/mosu/mosuserver/domain/notice/QNoticeAttachmentJpaEntity.java is excluded by !**/generated/**
  • src/main/generated/life/mosu/mosuserver/domain/notice/QNoticeFile.java is excluded by !**/generated/**
  • src/main/generated/life/mosu/mosuserver/domain/notice/QNoticeJpaEntity.java is excluded by !**/generated/**
  • src/main/generated/life/mosu/mosuserver/domain/payment/QPaymentAmountVO.java is excluded by !**/generated/**
  • src/main/generated/life/mosu/mosuserver/domain/payment/QPaymentJpaEntity.java is excluded by !**/generated/**
  • src/main/generated/life/mosu/mosuserver/domain/profile/QProfileJpaEntity.java is excluded by !**/generated/**
  • src/main/generated/life/mosu/mosuserver/domain/profile/QSchoolInfoJpaVO.java is excluded by !**/generated/**
  • src/main/generated/life/mosu/mosuserver/domain/refund/QRefundJpaEntity.java is excluded by !**/generated/**
  • src/main/generated/life/mosu/mosuserver/domain/user/QUserJpaEntity.java is excluded by !**/generated/**
  • src/main/generated/life/mosu/mosuserver/infra/storage/domain/QAdmissionTicketFileEntity.java is excluded by !**/generated/**
  • src/main/generated/life/mosu/mosuserver/infra/storage/domain/QFile.java is excluded by !**/generated/**
  • src/main/generated/life/mosu/mosuserver/infra/storage/domain/QFileMoveFailLog.java is excluded by !**/generated/**
📒 Files selected for processing (9)
  • build.gradle (1 hunks)
  • src/main/java/life/mosu/mosuserver/application/application/ApplicationService.java (1 hunks)
  • src/main/java/life/mosu/mosuserver/application/inquiry/InquiryAnswerService.java (4 hunks)
  • src/main/java/life/mosu/mosuserver/domain/refund/RefundJpaEntity.java (3 hunks)
  • src/main/java/life/mosu/mosuserver/infra/storage/domain/File.java (2 hunks)
  • src/main/java/life/mosu/mosuserver/presentation/application/dto/ApplicationRequest.java (1 hunks)
  • src/test/java/life/mosu/mosuserver/MosuServerApplicationTests.java (1 hunks)
  • src/test/resources/application.yml (1 hunks)
  • src/test/resources/test-security-config.yml (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
src/main/java/life/mosu/mosuserver/domain/refund/RefundJpaEntity.java (1)
src/main/java/life/mosu/mosuserver/domain/application/ApplicationJpaEntity.java (1)
  • Entity (15-52)
🪛 Gitleaks (8.27.2)
src/test/resources/application.yml

79-79: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

src/test/resources/test-security-config.yml

79-79: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

🪛 YAMLlint (1.37.1)
src/test/resources/application.yml

[error] 90-90: no new line character at the end of file

(new-line-at-end-of-file)

src/test/resources/test-security-config.yml

[error] 90-90: no new line character at the end of file

(new-line-at-end-of-file)

🔇 Additional comments (12)
src/main/java/life/mosu/mosuserver/infra/storage/domain/File.java (2)

3-6: Excellent improvement to explicit imports.

Replacing wildcard imports with explicit JPA imports improves code clarity and makes dependencies more obvious.


33-33: Good practice using .equals() for enum comparison.

While == works for enums due to their singleton nature, using .equals() is more defensive and consistent with general object comparison practices.

src/main/java/life/mosu/mosuserver/domain/refund/RefundJpaEntity.java (1)

3-9: Good improvement to explicit imports.

Replacing wildcard imports with explicit JPA imports enhances code readability and makes dependencies clear.

src/test/resources/test-security-config.yml (2)

1-90: Well-structured test configuration for containerized testing.

The configuration appropriately sets up a comprehensive test environment with Testcontainers MySQL, detailed JPA logging, and proper test-specific settings like create-drop DDL mode.


1-90: Inconsistent with PR objectives - no Querydsl query types found.

The PR title mentions "Add Querydsl query types for various entities" but this file (and the entire PR) doesn't contain any actual Querydsl Q-type classes or query implementations. The changes appear to be infrastructure and code quality improvements instead.

Likely an incorrect or invalid review comment.

src/test/java/life/mosu/mosuserver/MosuServerApplicationTests.java (1)

1-13: Inconsistent with PR objectives: No Querydsl-related changes found.

The PR title indicates "Add Querydsl query types for various entities" but this file contains only basic test infrastructure setup. Please verify that the correct files were included in this PR.

Likely an incorrect or invalid review comment.

src/main/java/life/mosu/mosuserver/application/application/ApplicationService.java (1)

1-156: Inconsistent with PR objectives: No Querydsl implementation found.

This service class shows no Querydsl query types or related imports despite the PR title indicating "Add Querydsl query types for various entities".

Likely an incorrect or invalid review comment.

src/test/resources/application.yml (3)

1-90: Inconsistent with PR objectives: Test configuration doesn't relate to Querydsl.

This YAML configuration file sets up test infrastructure but contains no Querydsl-related configuration despite the PR title indicating "Add Querydsl query types for various entities".

Likely an incorrect or invalid review comment.


79-79: Test API key is acceptable for test configuration.

The static analysis tool flagged this as a potential security issue, but this appears to be a legitimate test API key from Toss (indicated by the test_sk_ prefix) which is appropriate for test configurations.


17-18: Testcontainers MySQL 8.4.4 tag is available

MySQL 8.4.4 (including variants 8.4.4, 8.4.4-oracle, 8.4.4-oraclelinux9) is published on Docker Hub, so the URL in src/test/resources/application.yml is valid. No changes to the code are required—just ensure this version matches your application and production requirements.

• File: src/test/resources/application.yml
url: jdbc:tc:mysql:8.4.4:///;
driver-class-name: org.testcontainers.jdbc.ContainerDatabaseDriver

src/main/java/life/mosu/mosuserver/application/inquiry/InquiryAnswerService.java (2)

1-104: Inconsistent with PR objectives: No Querydsl implementation found.

This service class shows refactoring improvements but no Querydsl query types or related functionality despite the PR title indicating "Add Querydsl query types for various entities".

Likely an incorrect or invalid review comment.


91-94: Method refactoring improves code readability.

The rename from getInquiryOrThrow to getInquiry is a good simplification while maintaining the same functionality.

Comment on lines +93 to +96
testImplementation 'org.springframework.boot:spring-boot-testcontainers:3.3.5'
testImplementation 'org.testcontainers:testcontainers:1.19.3'
testImplementation 'org.testcontainers:junit-jupiter:1.19.3'
testImplementation 'org.testcontainers:mysql:1.20.0'
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Verify Testcontainers version compatibility.

The Testcontainers dependencies use different versions (MySQL 1.20.0 vs core/junit-jupiter 1.19.3) and the Spring Boot Testcontainers starter (3.3.5) might be outdated compared to the Spring Boot version (3.4.5).


🏁 Script executed:

#!/bin/bash
# Check latest available versions for Testcontainers dependencies
echo "Checking latest Testcontainers versions:"
curl -s https://repo1.maven.org/maven2/org/testcontainers/testcontainers/maven-metadata.xml | grep -o '<version>[^<]*</version>' | tail -5

echo -e "\nChecking Spring Boot Testcontainers starter versions:"
curl -s https://repo1.maven.org/maven2/org/springframework/boot/spring-boot-testcontainers/maven-metadata.xml | grep -o '<version>[^<]*</version>' | tail -5

Length of output: 768


Align Testcontainers versions and update Spring Boot Testcontainers starter

All Testcontainers modules should share the same version and the Spring Boot Testcontainers starter should match your Spring Boot minor version.

• In build.gradle (around lines 93–96):
– Replace
groovy testImplementation 'org.springframework.boot:spring-boot-testcontainers:3.3.5' testImplementation 'org.testcontainers:testcontainers:1.19.3' testImplementation 'org.testcontainers:junit-jupiter:1.19.3' testImplementation 'org.testcontainers:mysql:1.20.0'
– With (for example, using the latest 3.4.x starter and Testcontainers 1.21.3):
groovy testImplementation 'org.springframework.boot:spring-boot-testcontainers:3.4.7' testImplementation 'org.testcontainers:testcontainers:1.21.3' testImplementation 'org.testcontainers:junit-jupiter:1.21.3' testImplementation 'org.testcontainers:mysql:1.21.3'
• Verify your Spring Boot version (3.4.5) is compatible with the chosen starter (3.4.7).
• Optionally review Maven Central for the exact latest patch releases before finalizing.

🤖 Prompt for AI Agents
In build.gradle around lines 93 to 96, the Testcontainers dependencies use
inconsistent versions and the Spring Boot Testcontainers starter version does
not align with your Spring Boot version. Update all Testcontainers dependencies
to the same version, for example 1.21.3, and update the Spring Boot
Testcontainers starter to a version matching your Spring Boot minor version,
such as 3.4.7. Verify compatibility between your Spring Boot version and the
starter version before finalizing.

Comment on lines +96 to +100
private void isAnswerAlreadyRegister(Long postId) {
if (inquiryAnswerJpaRepository.existsById(postId)) {
throw new CustomRuntimeException(ErrorCode.INQUIRY_ANSWER_ALREADY_EXISTS);
}
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix incorrect logic in answer existence check.

The isAnswerAlreadyRegister method incorrectly uses existsById(postId) which checks if an answer exists with the given ID as primary key, but it should check if an answer exists for the given inquiry ID.

-    private void isAnswerAlreadyRegister(Long postId) {
-        if (inquiryAnswerJpaRepository.existsById(postId)) {
-            throw new CustomRuntimeException(ErrorCode.INQUIRY_ANSWER_ALREADY_EXISTS);
-        }
-    }
+    private void isAnswerAlreadyRegister(Long postId) {
+        if (inquiryAnswerJpaRepository.existsByInquiryId(postId)) {
+            throw new CustomRuntimeException(ErrorCode.INQUIRY_ANSWER_ALREADY_EXISTS);
+        }
+    }
📝 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.

Suggested change
private void isAnswerAlreadyRegister(Long postId) {
if (inquiryAnswerJpaRepository.existsById(postId)) {
throw new CustomRuntimeException(ErrorCode.INQUIRY_ANSWER_ALREADY_EXISTS);
}
}
private void isAnswerAlreadyRegister(Long postId) {
if (inquiryAnswerJpaRepository.existsByInquiryId(postId)) {
throw new CustomRuntimeException(ErrorCode.INQUIRY_ANSWER_ALREADY_EXISTS);
}
}
🤖 Prompt for AI Agents
In
src/main/java/life/mosu/mosuserver/application/inquiry/InquiryAnswerService.java
around lines 96 to 100, the method isAnswerAlreadyRegister incorrectly checks
existence by using existsById(postId), which checks for an answer with the
primary key equal to postId. Instead, modify the repository method call to check
if an answer exists for the given inquiry ID (postId) by using a method like
existsByInquiryId(postId) or the appropriate query method that checks the
inquiry ID field.

Comment on lines +27 to +28
@Column(name = "exam_application_id")
private Long examApplicationId;
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Verify consistent field renaming across the codebase.

The field rename from applicationSchoolId to examApplicationId makes the domain model more precise. Ensure all references to this field have been updated consistently.

Also applies to: 41-42, 46-46


🏁 Script executed:

#!/bin/bash
# Search for any remaining references to the old field name
echo "Searching for old field name references:"
rg -i "applicationSchoolId|application_school_id" --type java

echo -e "\nSearching for new field name usage:"  
rg -i "examApplicationId|exam_application_id" --type java

Length of output: 10784


Inconsistent usage of applicationSchoolId remains—please rename to examApplicationId across the codebase

The following files still reference the old field name applicationSchoolId and should be updated (or confirmed correct if they refer to a different concept):

  • src/main/java/life/mosu/mosuserver/presentation/payment/dto/PaymentRequest.java
  • src/main/java/life/mosu/mosuserver/domain/admin/ApplicationQueryRepositoryImpl.java
  • src/main/java/life/mosu/mosuserver/domain/admin/RefundQueryRepositoryImpl.java
  • src/main/java/life/mosu/mosuserver/domain/refund/RefundJpaRepository.java
  • src/main/java/life/mosu/mosuserver/domain/payment/PaymentJpaEntity.java
  • src/main/generated/life/mosu/mosuserver/domain/payment/QPaymentJpaEntity.java
  • src/main/java/life/mosu/mosuserver/infra/respository/BulkRepository.java
  • src/main/java/life/mosu/mosuserver/application/payment/PaymentEvent.java
  • src/main/java/life/mosu/mosuserver/application/payment/PaymentFailureHandler.java
  • src/main/java/life/mosu/mosuserver/application/payment/PaymentService.java
  • src/main/java/life/mosu/mosuserver/application/notify/NotifyVariableFactory.java

After renaming, rerun rg -i "applicationSchoolId" to confirm no lingering references.

🤖 Prompt for AI Agents
In src/main/java/life/mosu/mosuserver/domain/refund/RefundJpaEntity.java around
lines 27-28, the field applicationSchoolId has been renamed to
examApplicationId, but other files still reference the old name. Update all
occurrences of applicationSchoolId to examApplicationId in the listed files to
maintain consistency. After making these changes, run rg -i
"applicationSchoolId" to verify no references remain.

Comment on lines +28 to +30
/**
* ExamApplication = exam_id, lunch_id 를 포함하고 있음
*/
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Move the Javadoc comment to the correct field.

The comment describes ExamApplication containing exam_id and lunch_id, but it's placed above the agreement field instead of the examApplication field.

         @NotNull
         List<ExamApplicationRequest> examApplication,
-        /**
-         * ExamApplication = exam_id, lunch_id 를 포함하고 있음
-         */
         @Schema(description = "약관 동의 정보", required = true)
         @NotNull
         AgreementRequest agreement,

And add it above the examApplication field:

         @Schema(description = "시험 신청 Id 목록", required = true)
         @NotNull
+        /**
+         * ExamApplication = exam_id, lunch_id 를 포함하고 있음
+         */
         List<ExamApplicationRequest> examApplication,
📝 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.

Suggested change
/**
* ExamApplication = exam_id, lunch_id 포함하고 있음
*/
/**
* ExamApplication = exam_id, lunch_id 포함하고 있음
*/
@Schema(description = "시험 신청 Id 목록", required = true)
@NotNull
List<ExamApplicationRequest> examApplication,
@Schema(description = "약관 동의 정보", required = true)
@NotNull
AgreementRequest agreement,
🤖 Prompt for AI Agents
In
src/main/java/life/mosu/mosuserver/presentation/application/dto/ApplicationRequest.java
around lines 28 to 30, the Javadoc comment describing that ExamApplication
contains exam_id and lunch_id is incorrectly placed above the agreement field.
Move this Javadoc comment so that it is directly above the examApplication field
to correctly document it.

BasicBinder: TRACE

toss:
secret-key: test_sk_kYG57Eba3GYBMGeobgbLrpWDOxmA
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Remove hardcoded API key even for testing.

Although this appears to be a test key, hardcoding API keys in configuration files is a security risk and bad practice.

 toss:
-  secret-key: test_sk_kYG57Eba3GYBMGeobgbLrpWDOxmA
+  secret-key: ${TOSS_SECRET_KEY}
   api:
     base-url: https://api.tosspayments.com/v1/payments
📝 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.

Suggested change
secret-key: test_sk_kYG57Eba3GYBMGeobgbLrpWDOxmA
toss:
secret-key: ${TOSS_SECRET_KEY}
api:
base-url: https://api.tosspayments.com/v1/payments
🧰 Tools
🪛 Gitleaks (8.27.2)

79-79: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

🤖 Prompt for AI Agents
In src/test/resources/test-security-config.yml at line 79, remove the hardcoded
secret-key value to avoid security risks. Replace it with a reference to an
environment variable or a placeholder that can be securely injected during
testing, ensuring no sensitive keys are stored directly in the configuration
file.

@wlgns12370 wlgns12370 merged commit 69a4945 into develop Jul 21, 2025
2 checks passed
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.

2 participants