[chore] prod 배포 v0.0.4 - #55
Conversation
- Dockerfile: 의존성 다운로드를 소스와 분리된 레이어로 분리해 gha 캐시 재사용 (resolveDependencies 태스크 추가, configuration cache 호환·lenient 해석) - image.yml: 태그 계산(meta) 잡 분리 후 백엔드·admin 이미지 병렬 빌드 - 백엔드·admin 캐시 scope 분리(type=gha,scope=…)로 상호 덮어쓰기 방지
* chore: 빌드-테스트 병렬화 및 액션 Node24 버전 업그레이드 - build-backend·build-admin이 ci를 기다리지 않고 meta 직후 시작(테스트와 병렬) - deploy가 ci를 needs에 포함해 테스트 게이트 유지(테스트 실패 시 배포 차단) - Node 20 deprecation 해소: checkout v5, setup-java v5, setup-gradle v6, docker setup-buildx v4·login v4·build-push v7, scp v1.0.0, ssh v1.2.5 * docs: meta job 주석 정정 (리뷰 반영) meta는 ci와 병렬로 시작하고 빌드 job이 meta를 기다리는 관계인데, 'ci·빌드와 병렬로 돈다'고 잘못 적혀 있던 주석을 정확히 수정 * revert: 빌드-테스트 병렬화 되돌림 (리뷰 반영, Node 업그레이드는 유지) 테스트 안 된 이미지가 GHCR에 올라가 수동 롤백 시 오배포될 위험이 ~1분 단축 이득보다 크다는 리뷰를 수용해, build-backend·build-admin을 다시 ci 통과 후 실행하도록 순차 복원. 액션 Node24 업그레이드는 유지
* fix: 캐릭터 메시지가 아닌 대상에 답장 저장을 허용하던 문제 수정 답장 대상이 같은 채팅방에 속하는지만 검증하고 캐릭터 메시지인지는 확인하지 않았다. 저장과 생성이 분리되어 있을 때는 이어지는 생성 호출에서 INVALID_COMMENT_TARGET으로 걸러졌지만, 저장 직후 같은 요청에서 생성까지 이어지는 흐름에서는 저장은 이미 커밋된 채 응답만 400을 반환해 "실패로 보이는데 실제로는 저장된" 상태가 될 수 있었다. 저장 시점 (validateReplyTarget)에 미리 막아 이 상태 자체가 생기지 않게 한다. * feat: Gemini 호출에 명시적 타임아웃 추가 LLM 호출(재시도 최대 2회)을 저장과 한 요청으로 묶으면 nginx proxy_read_timeout(120s)이 하드 리밋이 되는데, 기존엔 호출별 타임아웃이 없었다. GeminiProperties.requestTimeout(PT30S)을 GenerateContentConfig의 HttpOptions에 적용해 최악의 경우에도 재시도 포함 ~60초 안에 들어오게 한다. * feat: 감정 기록 저장 + 캐릭터 댓글·답글 생성 동기 1콜 API 통합 (#39) - POST /messages가 저장 직후 같은 요청 안에서 CommentGenerationService의 댓글(일기)·재응답(답글) 생성까지 동기로 처리해 함께 반환한다(폴링 제거) - 새로 저장된 메시지 행은 이번 요청에서 최초로 CAS 선점을 시도하므로 GENERATING은 나오지 않고 DONE/FAILED만 나온다 - LLM 생성이 재시도까지 실패해도 저장은 유지되고 commentStatus=FAILED로 구분해서 응답한다 - 기존 폴링 엔드포인트(/messages/comments류)는 삭제하지 않고 FAILED 이후 수동 재시도용으로 문서만 좁혔다 - 크래시 복구는 기존 PendingCommentCleanupScheduler가 그대로 커버해 별도 작업이 필요 없었다 * refactor: 댓글·답글 생성 폴링 엔드포인트 제거 POST /messages가 저장과 함께 댓글·답글 생성을 동기로 처리하게 되면서 /messages/comments, /messages/comments/{messageId}는 실사용 경로가 아니게 됐다. 실패 후 수동 재시도용으로 문서만 좁혀 남겨뒀었는데, 쓰이지 않는 API 표면을 유지할 이유가 없어 엔드포인트와 전용 DTO (GenerateCommentsRequest, CommentGenerationResponse, ReplyGenerationResponse)를 완전히 제거한다. 삭제된 채팅방에서 생성이 막히는지 검증하던 관련 통합 테스트 2건도 함께 정리한다(같은 보호 로직은 CommentGenerationServiceTest에서 단위 테스트로 계속 커버). * Revert "refactor: 댓글·답글 생성 폴링 엔드포인트 제거" This reverts commit 596c3e9. * fix: 저장+생성 응답에서 GENERATING 유출을 코드로 방어 (CodeRabbit 리뷰 반영) * test: 답글 생성 FAILED 경로 부분 성공 테스트 추가 (CodeRabbit 리뷰 반영) * fix: gemini.request-timeout이 Int 밀리초 범위를 벗어나면 기동 시점에 검증 (CodeRabbit 리뷰 반영) * refactor: 댓글·답글 생성 결과 타입 통합 및 분기를 서비스 계층으로 이동 (리뷰 반영) * fix: 답장 생성 시 다른 채팅방 메시지 참조 차단 (CodeRabbit 리뷰 반영) * fix: 1ms 미만 Gemini 타임아웃 설정 차단 (CodeRabbit 리뷰 반영) * fix: LLM 재시도 전체 타임아웃 제한 (CodeRabbit 리뷰 반영)
* feat: 백오피스 대시보드(사용량·LLM 품질 모니터링) 추가 - generation_log 테이블(V9) + 생성 시 best-effort 기록(GenerationLogRecorder) → 호출 수·재시도율·지연·토큰·에러를 comment_status로 못 보던 부분까지 집계 - 사용량/품질 집계 서비스 분리(UsageStatsService·QualityStatsService, SRP) · 사용량: 오늘 대화·메시지·카드·가입, DAU/WAU, 감정 분포, 일별 활동 추이 · 품질: 생성 성공률·호출·재시도율·avg/p95 지연·토큰·막힌 PENDING - GET /api/admin/dashboard/usage·/quality - admin-web 대시보드 페이지(사용량·품질 2섹션, recharts) + 라우트·네비 활성화 - KST 날짜 경계 계산 중앙화(KstDashboardDates) * feat: 대시보드 사용량 지표에 유저당 평균 메시지 추가 - '오늘 메시지'를 '유저당 평균 메시지'(오늘 유저 발화 / DAU)로 교체 - UsageStatsResponse: avgMessagesPerUser 추가, todayCharacterMessages 제거 * fix: 대시보드 감정 분포 범례를 3열 그리드로 정돈 좁은 카드에서 6종 범례가 5+1로 어색하게 접히던 것을 3+3 균등 2줄로 변경 * fix: CodeRabbit 리뷰 반영 (대시보드 정확성·에러상태·중복 제거) - 생성 재시도 루프에서 예상 밖 예외도 generation_log에 기록 후 재던짐 (기존엔 CommentGenerationFailedException만 기록돼 성공률이 과대 집계) - KstDashboardDates: 요청당 기준 날짜(today)를 한 번만 캡처해 전달 (자정 경계에서 KPI 범위와 일별 축 기준일 어긋남 방지) - 프론트: API 실패 시 에러 상태(재시도) 표시, 감정 범례 hasEmotion 가드 - 프론트: shortDate·SeriesTooltip·SectionError 공통 모듈로 중복 제거 - 데이터 0건일 때 평균·비율 null 반환 테스트 추가 * perf: messages.comment_status 복합 인덱스 추가 청소 스케줄러·대시보드 막힌 PENDING 지표가 comment_status + comment_status_updated_at 조건으로 조회하는데 인덱스가 없어 messages 전체를 스캔(스케줄러는 1분마다)한다. 가장 빠르게 커지는 테이블이라 스캔 비용 누적을 막기 위해 복합 인덱스를 둔다.
* feat: 대화방 제목 지정/수정 API 추가
- Conversation에 nullable title(ConversationTitle 값 객체, 공백트림·최대100자)
- PATCH /api/conversations/{id}/title — 본인 대화방, 여러 번 수정 가능, 삭제된 방 차단
- 새 대화방은 title=null, ConversationResponse에 title 포함
- V9 마이그레이션(conversations.title)
* fix: 제목 수정 동시성·검증 정합성 개선 (CodeRabbit 리뷰 반영)
- updateTitle이 getOwnedConversationForUpdate(행 잠금) 사용 — 잠금 없이 stale
상태로 읽으면 동시 삭제가 flush로 되살아나는(모든 컬럼 UPDATE) 문제 방지
- UpdateConversationTitleRequest의 @notblank 제거 — 공백 검증을 ConversationTitle
값 객체로 일원화(공백→INVALID_CONVERSATION_TITLE, 누락→INVALID_INPUT, 문서와 일치)
- 공백 제목 HTTP 케이스 테스트 추가
* chore: 대화방 제목 마이그레이션 V9 → V11 리네임
dev에 generation_log(V9)·인덱스(V10)가 머지되어 V9가 겹치므로 다음 번호(V11)로 조정
|
Warning Review limit reached
Next review available in: 44 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the 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 configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (59)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
📌 개요
dev → prod 정기 배포. v0.0.3 → v0.0.4 (patch). 지난 릴리스 이후 머지된 기능·개선을 prod로 승격합니다.
🔧 포함 변경 (머지된 PR)
PATCH /api/conversations/{id}/title)🌐 API · DB 영향
V9__generation_log·V10__messages_comment_status_index·V11__conversation_titlegeneration_log/ 신규 컬럼:conversations.title/ 신규 인덱스:messages(comment_status, comment_status_updated_at)POST /messages응답 스키마 변경([feat] 대화 저장 + LLM 댓글 생성 API 통합 #48, 저장+생성 통합), 백오피스 대시보드 API 추가POST /api/conversations/messages응답이{ message, commentStatus, comments, usedTokens }로 바뀜 — 클라 배포 타이밍 확인 필요💬 리뷰 포인트