Skip to content

Feat/#51#70

Merged
fixgramwork merged 2 commits intodevelopfrom
feat/#51
Sep 6, 2025
Merged

Feat/#51#70
fixgramwork merged 2 commits intodevelopfrom
feat/#51

Conversation

@fixgramwork
Copy link
Member

@fixgramwork fixgramwork commented Sep 5, 2025

Summary by CodeRabbit

  • New Features
    • API 응답에 HATEOAS 하이퍼미디어를 도입하여 self 링크를 포함한 링크 탐색 가능한 리소스 제공. 응답 구조가 더 일관되고 확장 가능해졌습니다.
  • Tests
    • 테스트용 데이터베이스 및 JPA 설정을 정비하여 스키마 자동 생성/정리 지원. 테스트 신뢰성과 속도 개선.
  • Chores
    • 빌드 플러그인 리졸버와 프로젝트 메타데이터 설정 추가.
    • 하이퍼미디어 및 테스트용 DB 관련 의존성 구성 업데이트.

@fixgramwork fixgramwork linked an issue Sep 5, 2025 that may be closed by this pull request
@coderabbitai
Copy link

coderabbitai bot commented Sep 5, 2025

Walkthrough

빌드 및 설정 파일에 HATEOAS 의존성과 Gradle 플러그인 구성이 추가되었고, 테스트 리소스에 애플리케이션 설정이 새로 도입되었습니다. TestController의 엔드포인트는 HATEOAS EntityModel을 반환하도록 시그니처와 본문이 변경되었으며, self 링크가 포함됩니다.

Changes

Cohort / File(s) Summary
Build configuration
build.gradle
HATEOAS 의존성 org.springframework.boot:spring-boot-starter-hateoas 추가, 테스트 의존성으로 com.h2database:h2 추가
Gradle settings
settings.gradle
pluginManagement { repositories { gradlePluginPortal() } } 추가, org.gradle.toolchains.foojay-resolver 플러그인 적용, rootProject.name = 'CLUE-Backend' 설정
User test endpoint (HATEOAS 적용)
src/main/java/.../TestController.java
반환 타입을 ResponseEntity<EntityModel<String>>로 변경, 메시지를 EntityModel로 감싸고 self 링크 추가, Authorization 헤더 유지
Test resources config
src/test/resources/application.yml
테스트용 Spring Boot 설정 파일 추가: PostgreSQL 데이터소스 URL/자격증명/드라이버 지정, JPA ddl-auto: create-drop, Hibernate dialect 설정

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant C as Client
    participant T as TestController
    participant H as HATEOAS Builder

    C->>T: GET /test?userId&username&role
    activate T
    T->>T: JWT 발급 및 Authorization 헤더 설정
    T->>H: EntityModel.of("...") 생성 요청
    activate H
    H-->>T: EntityModel<String> (self 링크 포함)
    deactivate H
    T-->>C: 200 OK<br/>Headers: Authorization<br/>Body: EntityModel{message, _links.self}
    deactivate T
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

토끼 발로 톡톡, 빌드에 새 줄 추가해
헤이토스 링크 찰칵, 응답엔 길을 담고
플러그인 문도 열고, 프로젝트 이름 달고
테스트 바람 살살, 설정은 반짝 새로
깡총! 깃 로그에 춤추는 작은 캐롯 🎩🥕

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/#51

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.
    • 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.
  • 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 the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

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

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore or @coderabbit 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

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • 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.

@fixgramwork fixgramwork self-assigned this Sep 5, 2025
@fixgramwork fixgramwork added the 개발 개발과 관련된 이슈 label Sep 5, 2025
@fixgramwork fixgramwork moved this to 📌 Todo in clue_ver_1 Sep 5, 2025
@fixgramwork fixgramwork moved this from 📌 Todo to 🛠 In Progress in clue_ver_1 Sep 5, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🧹 Nitpick comments (4)
build.gradle (1)

25-82: 중복/부적절한 의존성 정리

validation, web, security, oauth2-client가 중복되고 lombok scope가 혼재되어 있습니다. 불필요한 충돌/빌드 시간 증가를 막기 위해 정리하세요.

-    implementation 'org.projectlombok:lombok:1.18.30'
+    // Lombok은 compileOnly + annotationProcessor로만 사용
+    compileOnly 'org.projectlombok:lombok:1.18.30'
+    annotationProcessor 'org.projectlombok:lombok:1.18.30'
@@
-    implementation 'org.springframework.boot:spring-boot-starter-validation'
-    implementation 'org.springframework.boot:spring-boot-starter-validation'
+    implementation 'org.springframework.boot:spring-boot-starter-validation'
@@
-    implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
-    implementation 'org.springframework.boot:spring-boot-starter-security'
-    implementation 'org.springframework.boot:spring-boot-starter-web'
+    // 중복 제거: 위에서 이미 추가됨

추가로, Spring Boot 3.x와 org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE는 호환되지 않습니다. io.awspring.cloud:spring-cloud-aws-starter-s3(v3 계열)로의 마이그레이션을 검토하세요.

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

12-12: 파일 끝 개행 추가

YAML 규약 및 일부 도구 호환성을 위해 EOF 개행을 추가하세요.

-        dialect: org.hibernate.dialect.PostgreSQLDialect
+        dialect: org.hibernate.dialect.PostgreSQLDialect
+
src/main/java/hello/cluebackend/domain/user/presentation/TestController.java (2)

30-34: self 링크는 methodOn 기반으로 생성하는 것이 안전

경로 문자열 결합 대신 메서드 참조를 사용하면 매핑 변경 시 자동 추적됩니다.

-        Link selfLink = linkTo(TestController.class).slash("test").withSelfRel();
-        entityModel.add(selfLink);
+        Link selfLink = linkTo(methodOn(TestController.class)
+                .issueToken(null, null, null, null)).withSelfRel();
+        entityModel.add(selfLink);

27-27: 미사용 파라미터 정리

HttpServletResponse response가 사용되지 않습니다. 불필요하면 제거하세요(앞으로 쿠키 설정 예정이면 유지).

-    public ResponseEntity<EntityModel<String>> issueToken(@RequestParam UUID userId, @RequestParam String username, @RequestParam String role, HttpServletResponse response) {
+    public ResponseEntity<EntityModel<String>> issueToken(@RequestParam UUID userId, @RequestParam String username, @RequestParam String role) {
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 49ac0dd and ae6e2af.

📒 Files selected for processing (4)
  • build.gradle (2 hunks)
  • settings.gradle (1 hunks)
  • src/main/java/hello/cluebackend/domain/user/presentation/TestController.java (2 hunks)
  • src/test/resources/application.yml (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-07-13T16:08:21.631Z
Learnt from: Hgyeol
PR: EscapeFrame/clueBackend#36
File: src/main/java/hello/cluebackend/domain/classroom/presentation/ClassRoomController.java:34-39
Timestamp: 2025-07-13T16:08:21.631Z
Learning: In this Spring Boot application, JWT validation is handled at the filter level before requests reach the controllers, so JWT token extraction and user ID retrieval in controllers like ClassRoomController don't require additional exception handling for invalid or missing tokens.

Applied to files:

  • src/main/java/hello/cluebackend/domain/user/presentation/TestController.java
🧬 Code graph analysis (1)
src/main/java/hello/cluebackend/domain/user/presentation/TestController.java (1)
src/main/java/hello/cluebackend/global/config/JWTUtil.java (1)
  • Component (17-79)
🪛 YAMLlint (1.37.1)
src/test/resources/application.yml

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

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

🔇 Additional comments (2)
build.gradle (1)

31-31: HATEOAS 의존성 추가 LGTM

컨트롤러 변경사항과 일치합니다.

settings.gradle (1)

1-10: Gradle 최소 버전(7.6) 호환 확인 완료 — 현재 래퍼가 8.13으로 설정되어 org.gradle.toolchains.foojay-resolver 1.0.0의 최소 요구 Gradle 버전(7.6)을 충족합니다.

developmentOnly 'org.springframework.boot:spring-boot-devtools'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.security:spring-security-test'
testImplementation 'com.h2database:h2'
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

테스트 DB 설정 불일치(H2 추가 vs 테스트 YML은 PostgreSQL 사용)

둘 중 하나로 정리하세요. 아래 두 가지 옵션 중 선택 권장.

옵션 A: PostgreSQL로 일원화(권장: Testcontainers 사용)

-    testImplementation 'com.h2database:h2'
+    testImplementation 'org.testcontainers:junit-jupiter'
+    testImplementation 'org.testcontainers:postgresql'

옵션 B: H2 인메모리로 일원화

  • build.gradle 유지
  • src/test/resources/application.yml을 H2로 변경(아래 코멘트 참고)

CI/로컬 모두에서 재현성 높은 Testcontainers 사용을 권장합니다.


검증을 위해 아래 스크립트를 실행합니다.


🏁 Script executed:

#!/bin/bash
set -e
# 테스트 리소스 파일 목록 확인
find . -type f -path '*/src/test/resources/*' -maxdepth 4

# application.yml 내용 상단 200줄 출력
if [ -f src/test/resources/application.yml ]; then
  sed -n '1,200p' src/test/resources/application.yml
fi

# 테스트 리소스에서 PostgreSQL 참조 검색
grep -R "postgres" -n src/test/resources || true

# 테스트 리소스에서 H2 참조 검색
grep -R "h2" -n src/test/resources || true

Length of output: 775


테스트 DB 설정 통일 필요
build.gradle 44행에서 H2를 추가하셨지만, src/test/resources/application.yml은 PostgreSQL을 사용하고 있습니다. 둘 중 하나로 정리하세요:

옵션 A (권장 – Testcontainers 사용)

-    testImplementation 'com.h2database:h2'
+    testImplementation 'org.testcontainers:junit-jupiter'
+    testImplementation 'org.testcontainers:postgresql'

옵션 B (H2 인메모리 사용 일원화)

  • build.gradle 유지
  • src/test/resources/application.yml의 datasource 설정을 H2(jdbc:h2:mem:testdb, org.h2.Driver, org.hibernate.dialect.H2Dialect)로 변경

CI/로컬 양쪽에서 재현성 높은 Testcontainers 기반 옵션 A를 권장합니다.

📝 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
testImplementation 'com.h2database:h2'
dependencies {
// … other dependencies …
// use Testcontainers for PostgreSQL in tests
testImplementation 'org.testcontainers:junit-jupiter'
testImplementation 'org.testcontainers:postgresql'
// … other dependencies …
}
🤖 Prompt for AI Agents
In build.gradle around line 44, tests currently add H2 but
src/test/resources/application.yml is configured for PostgreSQL; choose and
implement one of two fixes: Option A (recommended) — remove H2-only test
dependency if present, add Testcontainers PostgreSQL dependency and
Testcontainers JUnit integration, and update test bootstrap/config to start/use
the PostgreSQL container so application.yml remains PostgreSQL-compatible;
Option B — keep the H2 test dependency and change
src/test/resources/application.yml datasource to H2 (jdbc:h2:mem:testdb, driver
org.h2.Driver, Hibernate dialect org.hibernate.dialect.H2Dialect) and ensure any
PostgreSQL-specific SQL or dialect usage in tests is adapted for H2.


@PostMapping("/test")
public ResponseEntity<?> issueToken(@RequestParam UUID userId, @RequestParam String username, @RequestParam String role, HttpServletResponse response) {
public ResponseEntity<EntityModel<String>> issueToken(@RequestParam UUID userId, @RequestParam String username, @RequestParam String role, HttpServletResponse response) {
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

dev 전용 엔드포인트 보호

실서버 노출을 방지하기 위해 프로파일/플래그로 가드하세요(클래스 레벨 권장).

 @RestController
 @RequiredArgsConstructor
+@org.springframework.context.annotation.Profile("dev")
 public class TestController {

🏁 Script executed:

#!/bin/bash
# Locate TestController.java and display its first 200 lines
fd "TestController.java" -e java -x sed -n '1,200p' {}

echo ""
echo "Existing @Profile annotations in the repo:"
rg -n '@Profile' -n src

Length of output: 1789


🏁 Script executed:

#!/bin/bash
# locate application config files
echo "Config files:"
fd -t f -g 'application*.yml' -g 'application*.properties'

Length of output: 208


🏁 Script executed:

#!/bin/bash
# 프로젝트 루트에서 Spring Boot 설정 파일 검색
find . -type f \( -name "application*.yml" -o -name "application*.properties" \)

Length of output: 245


dev 전용 엔드포인트 보호: @Profile("dev") 클래스 레벨 적용
실서비스(prod) 프로파일에서 빈 등록 방지 위해 TestController 클래스에 @Profile("dev") 애노테이션 추가 필요

 @RestController
 @RequiredArgsConstructor
+@org.springframework.context.annotation.Profile("dev")
 public class TestController {
📝 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
public ResponseEntity<EntityModel<String>> issueToken(@RequestParam UUID userId, @RequestParam String username, @RequestParam String role, HttpServletResponse response) {
@RestController
@RequiredArgsConstructor
@org.springframework.context.annotation.Profile("dev")
public class TestController {
public ResponseEntity<EntityModel<String>> issueToken(
@RequestParam UUID userId,
@RequestParam String username,
@RequestParam String role,
HttpServletResponse response) {
// …
}
// …
}
🤖 Prompt for AI Agents
In src/main/java/hello/cluebackend/domain/user/presentation/TestController.java
around line 27, the TestController must be restricted to the dev profile; add
the Spring profile annotation to the class by annotating the controller class
with @Profile("dev") (and import org.springframework.context.annotation.Profile)
so the bean is only registered when the "dev" profile is active; keep existing
controller annotations and ensure imports compile.

Comment on lines +30 to +31
EntityModel<String> entityModel = EntityModel.of("JWT access token and refresh token issued for dev use.");

Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

⚠️ Potential issue

응답 메시지가 실제 동작과 불일치(리프레시 토큰 미발급)

현재 access 토큰만 발급합니다. 메시지를 정확히 수정하거나 실제로 refresh 토큰을 발급·쿠키로 설정하세요.

(간단 수정안)

-        EntityModel<String> entityModel = EntityModel.of("JWT access token and refresh token issued for dev use.");
+        EntityModel<String> entityModel = EntityModel.of("JWT access token issued for dev use.");
📝 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
EntityModel<String> entityModel = EntityModel.of("JWT access token and refresh token issued for dev use.");
EntityModel<String> entityModel = EntityModel.of("JWT access token issued for dev use.");

Comment on lines 35 to +37
return ResponseEntity.ok()
.header("Authorization", "Bearer " + access)
.body("JWT access token and refresh token issued for dev use.");
.body(entityModel);
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Authorization 헤더는 캐시 금지 헤더와 함께 반환

토큰이 캐시/프록시에 남지 않도록 Cache-Control: no-store, Pragma: no-cache를 함께 설정하고, HttpHeaders#setBearerAuth를 사용하세요.

-        return ResponseEntity.ok()
-                .header("Authorization", "Bearer " + access)
-                .body(entityModel);
+        return ResponseEntity.ok()
+                .headers(h -> {
+                    h.setBearerAuth(access);
+                    h.add("Cache-Control", "no-store");
+                    h.add("Pragma", "no-cache");
+                })
+                .body(entityModel);
📝 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
return ResponseEntity.ok()
.header("Authorization", "Bearer " + access)
.body("JWT access token and refresh token issued for dev use.");
.body(entityModel);
return ResponseEntity.ok()
.headers(h -> {
h.setBearerAuth(access);
h.add("Cache-Control", "no-store");
h.add("Pragma", "no-cache");
})
.body(entityModel);
🤖 Prompt for AI Agents
In src/main/java/hello/cluebackend/domain/user/presentation/TestController.java
around lines 35 to 37, the response sets the Authorization header directly but
lacks cache-prevention headers; update the response to use
HttpHeaders#setBearerAuth to set the bearer token and add cache-control headers
(Cache-Control: no-store and Pragma: no-cache) before building the
ResponseEntity so the token is not stored by caches or proxies.

Comment on lines +1 to +12
spring:
datasource:
url: jdbc:postgresql://localhost:5432/testdb
username: testuser
password: testpass
driver-class-name: org.postgresql.Driver
jpa:
hibernate:
ddl-auto: create-drop # 테스트 끝나면 테이블 삭제
properties:
hibernate:
dialect: org.hibernate.dialect.PostgreSQLDialect No newline at end of file
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

⚠️ Potential issue

테스트 DB를 PostgreSQL로 강제하고 있어 H2 의존성과 충돌

H2를 사용할 계획이면 다음처럼 변경하세요:

 spring:
   datasource:
-    url: jdbc:postgresql://localhost:5432/testdb
-    username: testuser
-    password: testpass
-    driver-class-name: org.postgresql.Driver
+    url: jdbc:h2:mem:testdb;MODE=PostgreSQL;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
+    driver-class-name: org.h2.Driver
+    username: sa
+    password:
   jpa:
     hibernate:
       ddl-auto: create-drop   # 테스트 끝나면 테이블 삭제
     properties:
       hibernate:
-        dialect: org.hibernate.dialect.PostgreSQLDialect
+        dialect: org.hibernate.dialect.H2Dialect

PostgreSQL을 유지하려면 build.gradle에서 H2를 제거하고(또는 Testcontainers를 추가) 테스트 인프라에서 로컬 DB 가용성을 보장해야 합니다.

📝 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
spring:
datasource:
url: jdbc:postgresql://localhost:5432/testdb
username: testuser
password: testpass
driver-class-name: org.postgresql.Driver
jpa:
hibernate:
ddl-auto: create-drop # 테스트 끝나면 테이블 삭제
properties:
hibernate:
dialect: org.hibernate.dialect.PostgreSQLDialect
spring:
datasource:
url: jdbc:h2:mem:testdb;MODE=PostgreSQL;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
driver-class-name: org.h2.Driver
username: sa
password:
jpa:
hibernate:
ddl-auto: create-drop # 테스트 끝나면 테이블 삭제
properties:
hibernate:
dialect: org.hibernate.dialect.H2Dialect
🧰 Tools
🪛 YAMLlint (1.37.1)

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

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

🤖 Prompt for AI Agents
In src/test/resources/application.yml around lines 1 to 12, the test
configuration forces PostgreSQL which conflicts with using H2; either switch the
test datasource to an embedded H2 URL/driver/profile for tests (update url,
driver-class-name, and Hibernate dialect to H2 or activate a test profile that
does so), or keep PostgreSQL and remove H2 from build.gradle (or add
Testcontainers and configure tests to use a containerized Postgres) and ensure
the test environment provides a reachable local Postgres instance; apply one of
these fixes so the test runtime and dependencies match.

@fixgramwork fixgramwork merged commit e572dfa into develop Sep 6, 2025
1 check passed
@github-project-automation github-project-automation bot moved this from 🛠 In Progress to ✅ Done in clue_ver_1 Sep 6, 2025
@coderabbitai coderabbitai bot mentioned this pull request Sep 17, 2025
4 tasks
@fixgramwork fixgramwork deleted the feat/#51 branch November 19, 2025 06:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

개발 개발과 관련된 이슈

Projects

Status: ✅ Done

Development

Successfully merging this pull request may close these issues.

HATEOAS 설정

1 participant