Skip to content

Feat/#72 AI 매칭 리포트 분석 기능 구현#73

Merged
1winhyun merged 3 commits into
mainfrom
feat/#72
May 29, 2026
Merged

Feat/#72 AI 매칭 리포트 분석 기능 구현#73
1winhyun merged 3 commits into
mainfrom
feat/#72

Conversation

@1winhyun

@1winhyun 1winhyun commented May 29, 2026

Copy link
Copy Markdown
Collaborator

🔗 관련 이슈


✅ PR 유형

어떤 변경 사항이 있었나요?

  • 새로운 기능 추가
  • 버그 수정
  • 리팩토링
  • 코드에 영향을 주지 않는 변경사항(주석, 개행 등등..)
  • 문서 수정
  • 빌드 부분 혹은 패키지 매니저 수정
  • 테스트 코드 추가

✏️ 작업 내용

AI 매칭 리포트 분석 기능을 구현합니다.

  • 유저 간 체크리스트를 비교하여 매칭을 진행하고 리포트를 반환합니다.
image

💡 추가 사항

Summary by CodeRabbit

Release Notes

  • New Features

    • Added AI-powered match report analysis to evaluate compatibility between potential roommates, providing match rates, key compatibility factors, conversation starters, and personalized insights.
  • Chores

    • Updated security configuration to support additional deployment environment.

Review Change Stack

@1winhyun 1winhyun self-assigned this May 29, 2026
@1winhyun 1winhyun added ✅Test 테스트 코드 작성 ✨Feat 새로운 기능 개발 labels May 29, 2026
@1winhyun 1winhyun linked an issue May 29, 2026 that may be closed by this pull request
1 task
@coderabbitai

coderabbitai Bot commented May 29, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

This PR implements an AI match-report analysis feature enabling users to compare themselves against another user. The implementation flows from domain port definition through data loading, external AI integration, use case orchestration, and REST exposure, with comprehensive test coverage at the loader and use case levels.

Changes

AI Match Report Analysis Feature

Layer / File(s) Summary
Domain port contract
src/main/java/com/project/bangjjack/domain/user/domain/port/matchreport/MatchReportPort.java
MatchReportPort defines the boundary contract: accepts a MatchAnalysisCommand and returns a MatchAnalysisResult from external analysis.
Data loader and validation
src/main/java/com/project/bangjjack/domain/user/application/loader/MatchReportDataLoader.java, src/test/java/com/project/bangjjack/domain/user/application/loader/MatchReportDataLoaderTest.java
MatchReportDataLoader gathers user profiles (checklists, sleep habits, roommate preferences), enforces self-match rejection, and builds the analysis command; test suite validates success and all failure paths (missing data, self-match, registration exceptions).
External AI integration
src/main/java/com/project/bangjjack/domain/user/external/aimatch/AiMatchReportClient.java
AiMatchReportClient calls the external /match-detail endpoint, maps request/response DTOs, applies null-safe field defaults, and translates HTTP/client errors to AiServiceUnavailableException.
Use case orchestration and response building
src/main/java/com/project/bangjjack/domain/user/application/usecase/MatchReportUseCase.java, src/test/java/com/project/bangjjack/domain/user/application/usecase/MatchReportUseCaseTest.java
MatchReportUseCase orchestrates the complete flow: loads command via data loader, executes analysis via port, converts influential feature keys to labels, and composes MatchRateResponse with all analysis data; tests verify normal path, empty collections, and exception propagation from loader and AI service.
REST endpoint and configuration
src/main/java/com/project/bangjjack/domain/user/presentation/MatchReportController.java, src/main/java/com/project/bangjjack/domain/user/presentation/response/UserResponseCode.java, src/main/java/com/project/bangjjack/global/config/security/SecurityConfig.java
MatchReportController exposes GET endpoint at /api/v1/match-reports/{targetUserId} with OpenAPI documentation; UserResponseCode adds MATCH_REPORT_ANALYZED response constant; CORS configuration includes the Vercel frontend origin.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related issues

Possibly related PRs

  • Bangjjack/Bangjjack-Backend#26: This PR's match-report data loading and port/client pattern closely mirrors the post-domain match analysis pattern, suggesting shared design principles and potential code reuse opportunities.

Suggested reviewers

  • xEzIxX

Poem

🐰 A match report blooms, where two souls align,
User profiles dance through the data line,
AI whispers secrets of compatibility,
While controllers serve responses with civility,
Tests ensure the journey stays true.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main feature being implemented: AI matching report analysis functionality (AI 매칭 리포트 분석 기능 구현), which aligns directly with the primary changes across all modified files.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/#72

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 and usage tips.

@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: 1

🤖 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/project/bangjjack/domain/user/external/aimatch/AiMatchReportClient.java`:
- Around line 110-131: callMatchReport performs a blocking external call on
aiMatchRestClient so you must enforce the configured timeout bounds from
AiMatchApiProperties to avoid occupying request threads: ensure
AiMatchClientConfig.buildClient(...) actually applies AiMatchApiProperties
connect/read timeouts to the underlying client used by
aiMatchRestClient/aiMatchBatchRestClient, and wrap the blocking call in
callMatchReport with a timeout guard (e.g. execute the blocking
aiMatchRestClient.post() call on a bounded executor or use
CompletableFuture.orTimeout/completeOnTimeout with the read timeout value) so
the thread is released when the configured timeout elapses; reference
AiMatchClientConfig.buildClient, AiMatchApiProperties, aiMatchRestClient, and
callMatchReport when making changes.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3f13f373-60f7-4a47-ac92-2b0c76675078

📥 Commits

Reviewing files that changed from the base of the PR and between 3ded562 and cefdd61.

📒 Files selected for processing (9)
  • src/main/java/com/project/bangjjack/domain/user/application/loader/MatchReportDataLoader.java
  • src/main/java/com/project/bangjjack/domain/user/application/usecase/MatchReportUseCase.java
  • src/main/java/com/project/bangjjack/domain/user/domain/port/matchreport/MatchReportPort.java
  • src/main/java/com/project/bangjjack/domain/user/external/aimatch/AiMatchReportClient.java
  • src/main/java/com/project/bangjjack/domain/user/presentation/MatchReportController.java
  • src/main/java/com/project/bangjjack/domain/user/presentation/response/UserResponseCode.java
  • src/main/java/com/project/bangjjack/global/config/security/SecurityConfig.java
  • src/test/java/com/project/bangjjack/domain/user/application/loader/MatchReportDataLoaderTest.java
  • src/test/java/com/project/bangjjack/domain/user/application/usecase/MatchReportUseCaseTest.java

Comment on lines +110 to +131
private AiMatchResponse callMatchReport(AiMatchRequest request) {
try {
AiMatchResponse response = aiMatchRestClient.post()
.uri(MATCH_REPORT_PATH)
.contentType(MediaType.APPLICATION_JSON)
.body(request)
.retrieve()
.body(AiMatchResponse.class);

if (response == null) {
log.warn("AI match-report API returned null body");
throw new AiServiceUnavailableException();
}
return response;
} catch (HttpStatusCodeException e) {
log.error("AI match-report API failed: status={}", e.getStatusCode());
throw new AiServiceUnavailableException();
} catch (RestClientException e) {
log.error("AI match-report API call failed", e);
throw new AiServiceUnavailableException();
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Locate the aiMatchRestClient bean definition and check for timeout configuration.
rg -nP -C5 'aiMatchRestClient' --type=java -g '!**/external/aimatch/AiMatchReportClient.java'
rg -nP -C3 '(setConnectTimeout|setReadTimeout|ClientHttpRequestFactory|requestFactory|ConnectTimeout|ReadTimeout)' --type=java

Repository: Bangjjack/Bangjjack-Backend

Length of output: 7698


🏁 Script executed:

#!/bin/bash
# Find where AiMatchReportClient is defined/injected and what RestClient bean it uses.
rg -n "class AiMatchReportClient|AiMatchReportClient\(" src/main/java -S
rg -n "aiMatchRestClient" src/main/java/com/project/bangjjack/domain/user/external/aimatch -S || true
rg -n "AiMatchClientConfig|buildClient\\(|connectTimeout\\(|readTimeout\\(" src/main/java/com/project/bangjjack/domain -S

Repository: Bangjjack/Bangjjack-Backend

Length of output: 1698


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Show AiMatchReportClient constructor and injection annotations (if any)
sed -n '1,140p' src/main/java/com/project/bangjjack/domain/user/external/aimatch/AiMatchReportClient.java

# Show bean definitions and buildClient implementation in AiMatchClientConfig
sed -n '1,220p' src/main/java/com/project/bangjjack/domain/post/external/aimatch/AiMatchClientConfig.java

Repository: Bangjjack/Bangjjack-Backend

Length of output: 8500


🏁 Script executed:

#!/bin/bash
set -euo pipefail
rg -n "aiMatchTaskExecutor|taskExecutor|`@Async`\\b" src/main/java/com/project/bangjjack/domain/user/external/aimatch -S || true
rg -n "aiMatchTaskExecutor|taskExecutor|`@Async`\\b" src/main/java/com/project/bangjjack/domain/post/external/aimatch -S || true

Repository: Bangjjack/Bangjjack-Backend

Length of output: 369


AiMatchReportClient already uses a RestClient with connect/read timeouts configured.

  • AiMatchClientConfig.buildClient(...) sets SimpleClientHttpRequestFactory#setConnectTimeout and #setReadTimeout from AiMatchApiProperties, and both aiMatchRestClient and aiMatchBatchRestClient are built via this method.
  • The external call is still blocking on the request thread, so ensure the configured timeout values are appropriate to bound thread occupancy.
🧰 Tools
🪛 PMD (7.24.0)

[Low] 128-128: InvalidLogMessageFormat (Error Prone): Too many arguments, expected 0 argument but found 1

(InvalidLogMessageFormat (Error Prone))

🤖 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/project/bangjjack/domain/user/external/aimatch/AiMatchReportClient.java`
around lines 110 - 131, callMatchReport performs a blocking external call on
aiMatchRestClient so you must enforce the configured timeout bounds from
AiMatchApiProperties to avoid occupying request threads: ensure
AiMatchClientConfig.buildClient(...) actually applies AiMatchApiProperties
connect/read timeouts to the underlying client used by
aiMatchRestClient/aiMatchBatchRestClient, and wrap the blocking call in
callMatchReport with a timeout guard (e.g. execute the blocking
aiMatchRestClient.post() call on a bounded executor or use
CompletableFuture.orTimeout/completeOnTimeout with the read timeout value) so
the thread is released when the configured timeout elapses; reference
AiMatchClientConfig.buildClient, AiMatchApiProperties, aiMatchRestClient, and
callMatchReport when making changes.

@1winhyun 1winhyun merged commit 07d78ec into main May 29, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

✨Feat 새로운 기능 개발 ✅Test 테스트 코드 작성

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEAT] AI 매칭 리포트 분석 기능 구현

1 participant