Skip to content

Feat(#76): 챗봇 API 프록시 구현 - #78

Merged
LATE-BL00MER merged 2 commits into
developfrom
feat/76-chat-proxy
Aug 2, 2026
Merged

Feat(#76): 챗봇 API 프록시 구현#78
LATE-BL00MER merged 2 commits into
developfrom
feat/76-chat-proxy

Conversation

@LATE-BL00MER

@LATE-BL00MER LATE-BL00MER commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

📋 작업 내용

  • 인증 기반 POST /api/v1/chat Spring 챗봇 프록시 엔드포인트를 추가했습니다.
  • 클라이언트가 전달한 analysisId로 본인 소유 분석 결과를 조회하고, 위험 점수·등급·피싱 유형·설명·탐지 근거를 FastAPI 컨텍스트로 자동 변환합니다.
  • 멀티턴 USER/ASSISTANT 메시지를 FastAPI POST /api/chat 계약으로 전달합니다.
  • AI 연결 실패, 타임아웃, 비정상 응답을 앱이 처리할 수 있는 Spring 공통 오류 응답으로 매핑했습니다.
  • Compose와 환경 변수 예시에 AI chat 주소 및 타임아웃 설정을 추가했습니다.
  • Swagger, README, 백엔드 API 문서에 챗봇 엔드포인트와 FE 요청 스키마를 반영했습니다.
  • Flutter는 분석 컨텍스트 전체 대신 analysisId와 현재 대화 이력만 전송하며, 응답은 data.message에서 확인합니다.

🧪 테스트 결과

  • .\gradlew.bat test — 전체 144개 테스트 통과
  • .\gradlew.bat bootJar — Spring Boot JAR 빌드 성공
  • docker compose config --quiet — 일회성 더미 환경변수로 Compose 문법 검증
  • docker compose build/up — PostgreSQL, RabbitMQ, Spring Backend 모두 healthy 및 Swagger /api/v1/chat 반영 확인

🔗 관련 이슈

Closes #76

✅ 체크리스트

  • 관련 이슈를 연결했습니다.
  • 구현 범위와 변경 이유를 설명했습니다.
  • 로컬 테스트를 통과했습니다.
  • API 변경 사항을 Swagger에 반영했습니다.
  • DB 변경 사항과 마이그레이션을 포함했습니다. (해당 없음 — DB 변경 없음)
  • 민감 정보가 코드·로그·테스트 데이터에 포함되지 않았습니다.
  • 프론트엔드에 영향을 주는 응답 스키마 또는 Enum 변경을 공유했습니다.
  • 병합 전 작업 브랜치를 삭제하지 않았습니다.

Summary by CodeRabbit

  • New Features

    • Added an authenticated chat API at POST /api/v1/chat.
    • Supports multi-turn conversations with up to 50 messages.
    • Generates responses using completed analysis results and indicators.
    • Added clear handling for unavailable, timed-out, incomplete, or invalid responses.
  • Documentation

    • Updated API documentation, configuration examples, setup instructions, and Swagger categorization.
  • Tests

    • Added coverage for successful chats, access restrictions, pending analyses, service failures, timeouts, and invalid responses.

@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Changes

Chat proxy feature

Layer / File(s) Summary
Chat API contract and endpoint
src/main/java/com/gold/safefam/domain/chat/dto/*, src/main/java/com/gold/safefam/domain/chat/controller/ChatController.java, src/test/java/com/gold/safefam/SafefamApplicationTests.java, docs/safefam-backend.md
Adds validated multi-turn chat DTOs, USER and ASSISTANT roles, and secured POST /api/v1/chat handling.
Analysis context workflow
src/main/java/com/gold/safefam/domain/analysis/repository/AnalysisRepository.java, src/main/java/com/gold/safefam/domain/chat/service/ChatService.java, src/test/java/com/gold/safefam/domain/chat/service/ChatServiceTest.java
Loads user-owned analyses with indicators, validates readiness, converts analysis results, and forwards chat messages.
FastAPI bridge and runtime configuration
src/main/java/com/gold/safefam/domain/chat/client/AiChatClient.java, src/main/java/com/gold/safefam/global/exception/ErrorCode.java, src/main/resources/application.yml, .env.example, .env.prod.example, docker-compose.yml, src/test/java/com/gold/safefam/domain/chat/client/AiChatClientTest.java, README.md
Adds FastAPI request handling, timeout configuration, response validation, error mapping, integration tests, and runtime documentation.
Swagger tag ordering
src/main/java/com/gold/safefam/domain/*/controller/*.java
Updates existing OpenAPI tag names with numeric formatting changes.

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

Sequence Diagram(s)

sequenceDiagram
  actor Client
  participant ChatController
  participant ChatService
  participant AnalysisRepository
  participant AiChatClient
  participant FastAPI
  Client->>ChatController: POST /api/v1/chat
  ChatController->>ChatService: chat(userId, request)
  ChatService->>AnalysisRepository: Load analysis and indicators
  AnalysisRepository-->>ChatService: Analysis context
  ChatService->>AiChatClient: Forward context and messages
  AiChatClient->>FastAPI: POST /api/chat
  FastAPI-->>AiChatClient: Chat response
  AiChatClient-->>ChatService: AiChatResponse
  ChatService-->>ChatController: ChatResponse
  ChatController-->>Client: ApiResponse success
Loading

Possibly related PRs

Suggested labels: feat

Suggested reviewers: ch0412

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The chatbot work is in scope, but unrelated Swagger tag renumbering changes were added to multiple existing controllers. Remove the unrelated Swagger tag renumbering changes or move them to a separate pull request.
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The PR implements the Spring proxy, DTOs, error mapping, configurable AI URL, multi-turn messages, and analysis context required for the Spring scope of issue #76.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the main change: implementing the chatbot API proxy described in issue #76.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/76-chat-proxy

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.

@LATE-BL00MER
LATE-BL00MER marked this pull request as ready for review August 2, 2026 13:46

@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

🧹 Nitpick comments (3)
src/test/java/com/gold/safefam/domain/chat/client/AiChatClientTest.java (1)

1-112: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Add a test for the timeout-mapping branch.

The tests cover the success path, a 5xx failure, and a missing-message response, but none exercise hasSocketTimeoutCause in AiChatClient.java (Lines 80-89), which maps a SocketTimeoutException cause to CHAT_SERVICE_TIMEOUT. This branch is called out directly in the PR objectives as a required failure mapping. Add a test that injects a RestTemplate whose request factory throws a ResourceAccessException wrapping a SocketTimeoutException, and assert ErrorCode.CHAT_SERVICE_TIMEOUT.

🤖 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/gold/safefam/domain/chat/client/AiChatClientTest.java`
around lines 1 - 112, Add a test method to AiChatClientTest that uses a
RestTemplate configured with a request factory throwing a
ResourceAccessException whose cause is SocketTimeoutException, then invokes
AiChatClient.chat(request()) and asserts the resulting BusinessException has
ErrorCode.CHAT_SERVICE_TIMEOUT. Keep the existing request fixture and test
coverage unchanged.
src/main/java/com/gold/safefam/domain/chat/controller/ChatController.java (1)

34-43: 🚀 Performance & Scalability | 🔵 Trivial

Consider rate limiting for this AI-backed endpoint.

This endpoint forwards every request to an external AI chat service, which is latency-sensitive and potentially costly per call. The codebase already defines ANALYSIS_RATE_LIMIT_EXCEEDED for a similar costly flow (analysis submission). Consider applying a comparable rate limit to /api/v1/chat to prevent abuse or runaway costs, since a single authenticated user can otherwise issue unlimited multi-turn requests to the AI service.

🤖 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/gold/safefam/domain/chat/controller/ChatController.java`
around lines 34 - 43, Apply the existing rate-limiting mechanism used by the
analysis submission flow to the ChatController.chat endpoint, using the
established ANALYSIS_RATE_LIMIT_EXCEEDED response or equivalent configured limit
for authenticated users. Ensure requests exceeding the per-user limit are
rejected before invoking chatService.chat, while preserving the current
successful response behavior.
src/main/java/com/gold/safefam/domain/chat/client/AiChatClient.java (1)

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

Use an HTTP client that supports custom request timeouts.

RestClient does not expose SimpleClientHttpRequestFactory-style connect/read timeout settings the way this constructor does. If this is a new synchronous chat client on Spring Boot 4.1.0, build it with the timeout requirements in mind instead of adding another RestTemplate path.

🤖 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/gold/safefam/domain/chat/client/AiChatClient.java` around
lines 24 - 43, Update the primary AiChatClient constructor to use the Spring
HTTP client implementation that supports configuring both connectTimeout and
readTimeout, rather than constructing a RestTemplate with
SimpleClientHttpRequestFactory. Preserve the injected timeout properties and the
existing chatUrl normalization, and keep the package-private constructor’s
injected client behavior consistent with the selected client type.
🤖 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/gold/safefam/domain/chat/client/AiChatClient.java`:
- Around line 45-72: Add a logger to AiChatClient and, in the final catch
(RuntimeException exception) branch of chat, log the caught exception with its
stack trace and relevant context before converting it to
BusinessException(ErrorCode.CHAT_INVALID_RESPONSE). Leave the existing handling
for expected BusinessException, ResourceAccessException, and
HttpStatusCodeException cases unchanged.

---

Nitpick comments:
In `@src/main/java/com/gold/safefam/domain/chat/client/AiChatClient.java`:
- Around line 24-43: Update the primary AiChatClient constructor to use the
Spring HTTP client implementation that supports configuring both connectTimeout
and readTimeout, rather than constructing a RestTemplate with
SimpleClientHttpRequestFactory. Preserve the injected timeout properties and the
existing chatUrl normalization, and keep the package-private constructor’s
injected client behavior consistent with the selected client type.

In `@src/main/java/com/gold/safefam/domain/chat/controller/ChatController.java`:
- Around line 34-43: Apply the existing rate-limiting mechanism used by the
analysis submission flow to the ChatController.chat endpoint, using the
established ANALYSIS_RATE_LIMIT_EXCEEDED response or equivalent configured limit
for authenticated users. Ensure requests exceeding the per-user limit are
rejected before invoking chatService.chat, while preserving the current
successful response behavior.

In `@src/test/java/com/gold/safefam/domain/chat/client/AiChatClientTest.java`:
- Around line 1-112: Add a test method to AiChatClientTest that uses a
RestTemplate configured with a request factory throwing a
ResourceAccessException whose cause is SocketTimeoutException, then invokes
AiChatClient.chat(request()) and asserts the resulting BusinessException has
ErrorCode.CHAT_SERVICE_TIMEOUT. Keep the existing request fixture and test
coverage unchanged.
🪄 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 Plus

Run ID: f277b373-9420-41dd-a530-ec0fa3ec6fb4

📥 Commits

Reviewing files that changed from the base of the PR and between c796df0 and e8405ec.

📒 Files selected for processing (18)
  • .env.example
  • .env.prod.example
  • README.md
  • docker-compose.yml
  • docs/safefam-backend.md
  • src/main/java/com/gold/safefam/domain/analysis/repository/AnalysisRepository.java
  • src/main/java/com/gold/safefam/domain/chat/client/AiChatClient.java
  • src/main/java/com/gold/safefam/domain/chat/controller/ChatController.java
  • src/main/java/com/gold/safefam/domain/chat/dto/ChatMessage.java
  • src/main/java/com/gold/safefam/domain/chat/dto/ChatRequest.java
  • src/main/java/com/gold/safefam/domain/chat/dto/ChatResponse.java
  • src/main/java/com/gold/safefam/domain/chat/dto/ChatRole.java
  • src/main/java/com/gold/safefam/domain/chat/service/ChatService.java
  • src/main/java/com/gold/safefam/global/exception/ErrorCode.java
  • src/main/resources/application.yml
  • src/test/java/com/gold/safefam/SafefamApplicationTests.java
  • src/test/java/com/gold/safefam/domain/chat/client/AiChatClientTest.java
  • src/test/java/com/gold/safefam/domain/chat/service/ChatServiceTest.java

Comment thread src/main/java/com/gold/safefam/domain/chat/client/AiChatClient.java
@LATE-BL00MER LATE-BL00MER self-assigned this Aug 2, 2026
@LATE-BL00MER LATE-BL00MER added feat Implementing new features and removed feat Implementing new features labels Aug 2, 2026

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

🧹 Nitpick comments (1)
src/test/java/com/gold/safefam/domain/chat/client/AiChatClientTest.java (1)

31-53: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Add a multi-turn payload assertion.

The success case sends only one user message. It does not verify that an assistant message and a later user message preserve role values and order. Add a multi-turn fixture and assert every message in the JSON request body.

Also applies to: 119-129

🤖 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/gold/safefam/domain/chat/client/AiChatClientTest.java`
around lines 31 - 53, Add a multi-turn message fixture to
callsFastApiChatContractAndReadsMessage, including user, assistant, and later
user entries, then update the content.json assertion to verify every message’s
role, content, and order in the POST request payload.
🤖 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.

Nitpick comments:
In `@src/test/java/com/gold/safefam/domain/chat/client/AiChatClientTest.java`:
- Around line 31-53: Add a multi-turn message fixture to
callsFastApiChatContractAndReadsMessage, including user, assistant, and later
user entries, then update the content.json assertion to verify every message’s
role, content, and order in the POST request payload.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: bf233e61-70e5-4fed-b0b7-7afe82260e04

📥 Commits

Reviewing files that changed from the base of the PR and between e8405ec and c33eb50.

📒 Files selected for processing (11)
  • src/main/java/com/gold/safefam/domain/analysis/controller/AnalysisController.java
  • src/main/java/com/gold/safefam/domain/auth/controller/AuthController.java
  • src/main/java/com/gold/safefam/domain/chat/client/AiChatClient.java
  • src/main/java/com/gold/safefam/domain/family/controller/FamilyController.java
  • src/main/java/com/gold/safefam/domain/family/safety/controller/FamilySafetyCaseController.java
  • src/main/java/com/gold/safefam/domain/notification/controller/DeviceController.java
  • src/main/java/com/gold/safefam/domain/report/controller/ReportController.java
  • src/main/java/com/gold/safefam/domain/statistics/controller/StatisticsController.java
  • src/main/java/com/gold/safefam/domain/user/controller/UserController.java
  • src/main/java/com/gold/safefam/domain/whitelist/controller/WhitelistController.java
  • src/test/java/com/gold/safefam/domain/chat/client/AiChatClientTest.java

@LATE-BL00MER
LATE-BL00MER merged commit 04919ce into develop Aug 2, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feat Implementing new features

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] 챗봇 API 연동: Spring /chat 프록시 및 Flutter 실동작 연결

1 participant