Skip to content

feat/#1#2

Open
justhumannn wants to merge 3 commits into
mainfrom
feat/#1
Open

feat/#1#2
justhumannn wants to merge 3 commits into
mainfrom
feat/#1

Conversation

@justhumannn

@justhumannn justhumannn commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

#️⃣ 연관된 이슈

close #1

📝 작업 내용

  • 알람 엔티티 생성
  • 매칭 내부 엔티티 생성
  • 알람 생성 DTO 생성
  • 알람 레포지토리 생성
  • 알람 서비스 생성
  • 알람 컨트롤러 생성
  • 알람 테스트 코드 생성

💬 리뷰 요청 사항 (선택)

  • 코드가 docs의 규칙을 잘 지켰는지 봐주세요

Summary by CodeRabbit

  • New Features

    • 알림 생성 API가 추가되어, 매칭 ID와 설명을 받아 알림을 등록할 수 있게 되었습니다.
    • 인증이 필요한 경로가 알림 관련 요청으로 반영되었습니다.
  • Bug Fixes

    • 매칭 ID 입력 형식이 정수로 정리되었습니다.
    • 요청 검증 실패와 외부 조회 실패에 대해 더 일관된 오류 응답을 제공합니다.
  • Documentation

    • API 응답 예시와 아키텍처/코딩 가이드 문서가 최신 동작에 맞게 갱신되었습니다.
  • Tests

    • 알림 생성, 저장, 예외 처리에 대한 테스트가 추가되었습니다.

@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@justhumannn, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 36 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: f279fa11-f09d-4eaf-9876-d9ba7c05660a

📥 Commits

Reviewing files that changed from the base of the PR and between bae97d5 and 4f93fdc.

📒 Files selected for processing (5)
  • docs/common/architecture-guide.md
  • docs/service-overview.md
  • src/main/java/com/example/alarm/client/MatchingClient.java
  • src/main/java/com/example/alarm/global/exception/MatchingClientException.java
  • src/main/java/com/example/alarm/service/AlarmService.java
📝 Walkthrough

Walkthrough

Alarm 서비스에 알람 생성 기능이 새로 추가되었습니다. Alarm 엔티티/DTO/리포지토리/서비스/컨트롤러가 구현되고, 내부 매칭 서비스 호출을 위한 MatchingClient가 추가되었습니다. 예외 처리, 보안 설정, 애플리케이션 설정이 갱신되고, API 명세와 문서, 테스트가 함께 추가되었습니다.

Changes

알람 생성 기능

Layer / File(s) Summary
알람 도메인 계약
src/main/java/com/example/alarm/entity/Alarm.java, src/main/java/com/example/alarm/dto/request/AlarmCreateRequest.java, src/main/java/com/example/alarm/repository/AlarmRepository.java
Alarm JPA 엔티티, 검증 제약이 포함된 AlarmCreateRequest 레코드, JpaRepository 기반 AlarmRepository가 추가됩니다.
매칭 클라이언트 연동
src/main/java/com/example/alarm/client/MatchingClient.java, src/main/java/com/example/alarm/client/dto/MatchingResponse.java, src/main/java/com/example/alarm/client/dto/MatchingStatus.java, src/main/java/com/example/alarm/global/exception/MatchingClientException.java
내부 매칭 API를 HTTP GET으로 호출하는 MatchingClient와 응답 DTO/상태 enum, 조회 실패 시 사용하는 예외 클래스가 추가됩니다.
서비스/컨트롤러 구현
src/main/java/com/example/alarm/service/AlarmService.java, src/main/java/com/example/alarm/controller/AlarmController.java
매칭 조회 후 Alarm을 저장하는 AlarmService와 요청을 검증해 위임하는 AlarmController가 추가됩니다.
예외 처리 및 보안
src/main/java/com/example/alarm/global/exception/GlobalExceptionHandler.java, src/main/java/com/example/alarm/global/config/SecurityConfig.java, src/main/java/com/example/alarm/global/security/Role.java, src/main/java/com/example/alarm/global/security/JwtFilter.java, JwtProvider.java, UserPrincipal.java, src/main/java/com/example/alarm/global/util/ResponseUtil.java
검증/클라이언트 예외 핸들러가 교체되고, 인증 대상 경로가 `/alarm/**`로 바뀌며 Role enum이 alarm 패키지에 도입되고 기존 matching 패키지 import가 제거됩니다.
설정 및 빌드
src/main/resources/application.yaml, src/test/resources/application.yaml, build.gradle
DB/JPA/JWT/matching-service URL 설정과 테스트용 H2 설정, WebMVC 테스트 의존성이 추가됩니다.
테스트
src/test/java/com/example/alarm/controller/AlarmControllerTest.java, .../service/AlarmServiceTest.java, .../repository/AlarmRepositoryTest.java
성공/검증실패/인증실패/클라이언트예외 시나리오와 리포지토리 저장/조회를 검증하는 테스트가 추가됩니다.
문서 및 API 명세
API_SPEC.yaml, docs/common/architecture-guide.md, docs/common/coding-convention.md
경로 파라미터 타입/응답 스키마가 갱신되고, 아키텍처/코딩 컨벤션 문서가 Alarm 서비스 기준으로 수정됩니다.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant AlarmController
  participant AlarmService
  participant MatchingClient
  participant AlarmRepository

  Client->>AlarmController: POST /alarm/{matching-id}
  AlarmController->>AlarmService: create(matchingId, request)
  AlarmService->>MatchingClient: getMatching(matchingId)
  MatchingClient-->>AlarmService: MatchingResponse(hostId)
  AlarmService->>AlarmRepository: save(Alarm)
  AlarmRepository-->>AlarmService: 저장 완료
  AlarmService-->>AlarmController: 완료
  AlarmController-->>Client: 200 OK
Loading

Poem

알람 소식 들고 깡총깡총 뛰어가요 🐇
매칭 정보 물어물어 호스트를 찾았죠
엔티티에 담아서 저장소에 쏙!
예외도 척척, 502로 톡
새 굴을 파듯 코드를 다졌어요 🥕

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive 제목이 기능과 관련은 있지만 너무 포괄적이라 변경 내용을 식별하기 어렵습니다. 예: '알람 생성 로직 추가'처럼 핵심 변경을 드러내는 구체적인 제목으로 바꿔주세요.
✅ Passed checks (4 passed)
Check name Status Explanation
Description check ✅ Passed 이슈 번호, 작업 내용 체크리스트, 리뷰 요청이 포함되어 템플릿 요구를 대부분 충족합니다.
Linked Issues check ✅ Passed 알람 생성 기능과 내부 매칭 클라이언트 지원까지 포함해 이슈의 핵심 요구사항을 충족합니다.
Out of Scope Changes check ✅ Passed 추가된 문서, 설정, 테스트, 보안, 클라이언트 변경은 알람 생성 기능을 지원하는 범위입니다.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/#1

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

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 6

🧹 Nitpick comments (6)
src/test/java/com/example/alarm/controller/AlarmControllerTest.java (1)

105-118: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

matchingResponse 헬퍼가 AlarmServiceTest와 중복됨.

동일한 MatchingResponse 생성 로직이 AlarmServiceTest.matchingResponse에도 존재합니다. 공통 테스트 픽스처/빌더로 추출하면 매칭 스키마 변경 시 두 곳을 동시에 수정하지 않아도 됩니다.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/test/java/com/example/alarm/controller/AlarmControllerTest.java` around
lines 105 - 118, The matchingResponse helper in AlarmControllerTest duplicates
the same MatchingResponse test fixture used in AlarmServiceTest. Extract the
shared object creation logic into a common test fixture/builder and have both
tests call that shared helper instead of maintaining separate copies, using the
matchingResponse symbol and the MatchingResponse constructor as the main place
to consolidate.
src/main/resources/application.yaml (1)

4-15: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

show-sql: true가 환경 구분 없이 고정됨

모든 프로필에서 SQL 로그가 활성화되어 있어, 운영 환경에서 쿼리 파라미터 등 민감 정보가 로그에 노출되거나 불필요한 I/O 오버헤드가 발생할 수 있습니다. 프로필별로 분리하거나 기본값을 false로 두는 것을 권장합니다.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/resources/application.yaml` around lines 4 - 15, The JPA
configuration currently hardcodes show-sql to true in application.yaml, which
applies to every profile. Update the JPA settings so SQL logging is disabled by
default or split into profile-specific configuration, and ensure the application
uses a profile-aware property around the showSql setting in the datasource/jpa
config section.
src/main/java/com/example/alarm/global/config/SecurityConfig.java (1)

29-32: 🔒 Security & Privacy | 🔵 Trivial

anyRequest().permitAll() + actuator 조합 노출 위험

/alarm/**만 인증을 요구하고 나머지는 모두 permitAll()인 구조에서, build.gradlespring-boot-starter-actuator가 포함되어 있어 /actuator/** 엔드포인트가 기본적으로 인증 없이 노출될 수 있습니다. 이번 diff에서 새로 만든 리스크는 아니지만, 인증 경로가 명시적 화이트리스트가 아닌 기본 허용 구조이므로 향후 엔드포인트 추가 시 의도치 않게 공개될 위험이 있습니다. actuator 경로에 대한 명시적 인증/제한 설정을 검토해 보시길 권장합니다.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/java/com/example/alarm/global/config/SecurityConfig.java` around
lines 29 - 32, The SecurityConfig authorization rules currently use a broad
anyRequest().permitAll() fallback, which can leave actuator endpoints exposed.
Update the HttpSecurity configuration in SecurityConfig to explicitly restrict
/actuator/** (and any other sensitive endpoints) with authenticated or
role-based access instead of relying on the default allow-all rule. Keep the
existing /alarm/** protection, and make the permit-all behavior only apply to
clearly intended public routes.
API_SPEC.yaml (1)

20-21: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

matching_id 경로 파라미터 타입 불일치

POST 엔드포인트의 matching_idinteger/int64로 갱신되었지만(Line 20-21), 같은 경로의 PATCH 엔드포인트(Line 113-118)는 여전히 type: string으로 남아있습니다. 동일 리소스 식별자에 대해 타입이 다르게 문서화되어 있어 클라이언트/SDK 생성 시 혼란을 줄 수 있습니다.

📝 제안 수정
     patch:
       summary: alarmReadUpdate
       ...
       parameters:
         - name: matching_id
           in: path
           description: ''
           required: true
           schema:
-            type: string
+            type: integer
+            format: int64

Also applies to: 113-118

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@API_SPEC.yaml` around lines 20 - 21, The `matching_id` path parameter is
documented inconsistently across the same resource, with POST using
integer/int64 while PATCH still uses string. Update the PATCH endpoint
definition in `API_SPEC.yaml` to match the POST `matching_id` schema, and ensure
the shared path parameter spec uses the same `type: integer` and `format: int64`
so SDK/client generation sees one consistent identifier type.
src/main/java/com/example/alarm/entity/Alarm.java (1)

15-15: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

테이블명 Matchings_Alarm 확인 필요.

엔티티명은 Alarm인데 테이블명은 Matchings_Alarm으로 지정되어 있습니다. 다른 도메인(매칭) 접두사가 붙은 의도가 명확하지 않으면 Alarm으로 통일하는 것을 고려해주세요. 만약 스키마 공유 등 의도된 네이밍이라면 무시해도 좋습니다.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/java/com/example/alarm/entity/Alarm.java` at line 15, The Alarm
entity is mapped with a table name that uses the unrelated Matchings prefix, so
verify whether this is intentional. Review the `@Table` mapping on Alarm and
either rename the table reference to match the Alarm domain consistently or keep
Matchings_Alarm only if the shared-schema naming is deliberate; make the
decision in the Alarm class annotation so the entity/table relationship is
clear.
src/main/java/com/example/alarm/global/exception/MatchingClientException.java (1)

3-8: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

원인 예외를 포함하는 생성자 추가 제안.

MatchingClient에서 하위 RestClientException을 래핑하려면 cause를 전달할 수 있는 생성자가 필요합니다.

♻️ 생성자 추가 제안
 public class MatchingClientException extends RuntimeException {

     public MatchingClientException(String message) {
         super(message);
     }
+
+    public MatchingClientException(String message, Throwable cause) {
+        super(message, cause);
+    }
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/main/java/com/example/alarm/global/exception/MatchingClientException.java`
around lines 3 - 8, Add a cause-aware constructor to MatchingClientException so
MatchingClient can wrap lower-level RestClientException instances. Update the
MatchingClientException class to accept both a message and a Throwable cause,
and delegate to the matching RuntimeException superclass constructor; keep the
existing single-argument constructor intact for current call sites.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/main/java/com/example/alarm/client/MatchingClient.java`:
- Around line 22-33: In MatchingClient.getMatching, 4xx/5xx responses from
restClient.get().retrieve().body(...) are escaping as
RestClientResponseException instead of MatchingClientException. Wrap the
retrieve/body call in MatchingClientException handling, and use the new
MatchingClientException(String, Throwable) constructor to preserve the original
error when the request to /internal/matchings/{matchingId} fails. Keep the
existing null-response guard, but ensure any non-success HTTP status from
getMatching is converted before it leaves the method so GlobalExceptionHandler
can map it correctly.
- Around line 14-20: `MatchingClient`의 생성자에서 `RestClient.builder()`를
`baseUrl`만으로 구성하고 있어 외부 호출 타임아웃이 빠져 있습니다. `MatchingClient` 생성 시점에 connect/read
타임아웃을 설정하도록 `RestClient` 빌더에 요청 설정을 추가하고, 필요하면 공통 HTTP 클라이언트 설정을 재사용할 수 있게
정리하세요. `MatchingClient`와 `RestClient.builder()`를 기준으로 수정 위치를 찾아 적용하면 됩니다.

In
`@src/main/java/com/example/alarm/global/exception/GlobalExceptionHandler.java`:
- Around line 24-28: `GlobalExceptionHandler.matchingClientHandleException` only
maps `MatchingClientException` to 502, while other `RestClient` failures from
`MatchingClient.getMatching(...)` still fall through to the generic 500 handler.
Update the error flow by either wrapping `RestClientException`-type failures in
`MatchingClient` into `MatchingClientException`, or add a dedicated handler in
`GlobalExceptionHandler` for `RestClientException`/its subclasses and map
downstream service failures to 502/504 as appropriate.

In `@src/main/java/com/example/alarm/service/AlarmService.java`:
- Around line 19-26: `AlarmService.create` currently performs
`matchingClient.getMatching()` inside the `@Transactional` method, which keeps
the transaction open during an external HTTP call. Move the external lookup out
of the transactional boundary, then keep only the `alarmRepository.save(...)`
portion inside a transactional method. Use the `create`,
`matchingClient.getMatching`, and `alarmRepository.save` symbols to split the
flow cleanly.
- Around line 3-4: Add explicit connect and read timeout settings to the
RestClient configuration used by MatchingClient so AlarmService does not block
indefinitely on slow or failing matching calls. Locate the MatchingClient
factory/builder code that creates the RestClient with RestClient.builder(), and
configure both connection and response timeouts there; keep the existing
MatchingResponse handling unchanged.

In `@src/main/resources/application.yaml`:
- Around line 19-20: `matching-service.base-url` is silently falling back to a
local default when `MATCHING_SERVICE_BASE_URL` is missing, which should be
fail-fast if this setting is required. Update the `matching-service`
configuration in `application.yaml` to remove the default value and make the
property mandatory, so startup fails clearly when the environment variable is
not provided. Use the `matching-service.base-url` key as the locator for this
change.

---

Nitpick comments:
In `@API_SPEC.yaml`:
- Around line 20-21: The `matching_id` path parameter is documented
inconsistently across the same resource, with POST using integer/int64 while
PATCH still uses string. Update the PATCH endpoint definition in `API_SPEC.yaml`
to match the POST `matching_id` schema, and ensure the shared path parameter
spec uses the same `type: integer` and `format: int64` so SDK/client generation
sees one consistent identifier type.

In `@src/main/java/com/example/alarm/entity/Alarm.java`:
- Line 15: The Alarm entity is mapped with a table name that uses the unrelated
Matchings prefix, so verify whether this is intentional. Review the `@Table`
mapping on Alarm and either rename the table reference to match the Alarm domain
consistently or keep Matchings_Alarm only if the shared-schema naming is
deliberate; make the decision in the Alarm class annotation so the entity/table
relationship is clear.

In `@src/main/java/com/example/alarm/global/config/SecurityConfig.java`:
- Around line 29-32: The SecurityConfig authorization rules currently use a
broad anyRequest().permitAll() fallback, which can leave actuator endpoints
exposed. Update the HttpSecurity configuration in SecurityConfig to explicitly
restrict /actuator/** (and any other sensitive endpoints) with authenticated or
role-based access instead of relying on the default allow-all rule. Keep the
existing /alarm/** protection, and make the permit-all behavior only apply to
clearly intended public routes.

In
`@src/main/java/com/example/alarm/global/exception/MatchingClientException.java`:
- Around line 3-8: Add a cause-aware constructor to MatchingClientException so
MatchingClient can wrap lower-level RestClientException instances. Update the
MatchingClientException class to accept both a message and a Throwable cause,
and delegate to the matching RuntimeException superclass constructor; keep the
existing single-argument constructor intact for current call sites.

In `@src/main/resources/application.yaml`:
- Around line 4-15: The JPA configuration currently hardcodes show-sql to true
in application.yaml, which applies to every profile. Update the JPA settings so
SQL logging is disabled by default or split into profile-specific configuration,
and ensure the application uses a profile-aware property around the showSql
setting in the datasource/jpa config section.

In `@src/test/java/com/example/alarm/controller/AlarmControllerTest.java`:
- Around line 105-118: The matchingResponse helper in AlarmControllerTest
duplicates the same MatchingResponse test fixture used in AlarmServiceTest.
Extract the shared object creation logic into a common test fixture/builder and
have both tests call that shared helper instead of maintaining separate copies,
using the matchingResponse symbol and the MatchingResponse constructor as the
main place to consolidate.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: d7800916-38dd-4f17-a0ad-b5754067fd11

📥 Commits

Reviewing files that changed from the base of the PR and between c2e99f6 and bae97d5.

📒 Files selected for processing (25)
  • API_SPEC.yaml
  • build.gradle
  • docs/common/architecture-guide.md
  • docs/common/coding-convention.md
  • src/main/java/com/example/alarm/client/MatchingClient.java
  • src/main/java/com/example/alarm/client/dto/MatchingResponse.java
  • src/main/java/com/example/alarm/client/dto/MatchingStatus.java
  • src/main/java/com/example/alarm/controller/AlarmController.java
  • src/main/java/com/example/alarm/dto/request/AlarmCreateRequest.java
  • src/main/java/com/example/alarm/entity/Alarm.java
  • src/main/java/com/example/alarm/global/config/SecurityConfig.java
  • src/main/java/com/example/alarm/global/exception/GlobalExceptionHandler.java
  • src/main/java/com/example/alarm/global/exception/MatchingClientException.java
  • src/main/java/com/example/alarm/global/security/JwtFilter.java
  • src/main/java/com/example/alarm/global/security/JwtProvider.java
  • src/main/java/com/example/alarm/global/security/Role.java
  • src/main/java/com/example/alarm/global/security/UserPrincipal.java
  • src/main/java/com/example/alarm/global/util/ResponseUtil.java
  • src/main/java/com/example/alarm/repository/AlarmRepository.java
  • src/main/java/com/example/alarm/service/AlarmService.java
  • src/main/resources/application.yaml
  • src/test/java/com/example/alarm/controller/AlarmControllerTest.java
  • src/test/java/com/example/alarm/repository/AlarmRepositoryTest.java
  • src/test/java/com/example/alarm/service/AlarmServiceTest.java
  • src/test/resources/application.yaml
💤 Files with no reviewable changes (3)
  • src/main/java/com/example/alarm/global/security/JwtProvider.java
  • src/main/java/com/example/alarm/global/security/JwtFilter.java
  • src/main/java/com/example/alarm/global/security/UserPrincipal.java

Comment thread src/main/java/com/example/alarm/client/MatchingClient.java
Comment thread src/main/java/com/example/alarm/client/MatchingClient.java
Comment thread src/main/java/com/example/alarm/service/AlarmService.java
Comment thread src/main/java/com/example/alarm/service/AlarmService.java Outdated
Comment thread src/main/resources/application.yaml
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.

[✨ Feature] 알람 생성 로직 추가

1 participant