Skip to content

[feat] 백오피스 대시보드: 사용량·LLM 품질 모니터링 - #52

Merged
theminjunchoi merged 6 commits into
devfrom
feat/51-dashboard
Jul 27, 2026
Merged

[feat] 백오피스 대시보드: 사용량·LLM 품질 모니터링#52
theminjunchoi merged 6 commits into
devfrom
feat/51-dashboard

Conversation

@theminjunchoi

@theminjunchoi theminjunchoi commented Jul 26, 2026

Copy link
Copy Markdown
Collaborator

🔗 연관 이슈

📌 개요

백오피스 대시보드('준비중'이던 자리)를 구현한다. 서비스 사용량LLM 생성 품질/안정성을 한 화면에서 모니터링한다. (보안 지표는 별도 이슈)

🔧 주요 변경사항

관측 로그 (generation_log)

  • V9 마이그레이션 + GenerationLog 엔티티, 생성 시 GenerationLogRecorder로 한 줄씩 best-effort 기록(기록 실패가 생성 흐름을 깨지 않음)
  • comment_status 상태머신으로 못 보던 실제 호출 수·재시도·지연·토큰·에러까지 정확히 확보

집계 (SRP: 사용량/품질 서비스 분리)

  • UsageStatsService — 오늘 대화·유저 발화, 유저당 평균 메시지, 카드·가입, DAU/WAU, 감정 분포, 일별 활동 추이
  • QualityStatsService — 생성 성공률·호출 수·재시도율·avg/p95 지연·토큰·막힌 PENDING, 일별 성공/실패 추이
  • KST 날짜 경계 계산은 KstDashboardDates로 중앙화
  • GET /api/admin/dashboard/usage · /quality

백오피스 UI (admin-web)

  • /dashboard 페이지 — 사용량·품질 2섹션, recharts(감정 파이·활동 추이 이중축·성공/실패 스택바), 위험 신호 강조(막힌 PENDING·성공률 저하)
  • 네비 '준비중' 해제, 로그인 후 대시보드 착지, 차트 지연 로드

🌐 API · DB 영향

  • API 변경: 추가GET /api/admin/dashboard/usage, GET /api/admin/dashboard/quality
  • DB 마이그레이션: V9generation_log 테이블 신설
  • 하위 호환: 호환 (신규 엔드포인트·테이블만 추가)

모습

스크린샷 2026-07-26 오후 10 21 39

💬 리뷰 포인트

  • 생성 기록이 요청 경로를 지연시키지 않도록 best-effort(예외 삼킴)로 구현 — 기록 실패가 생성/응답을 막지 않음
  • 집계는 사용량/품질 서비스로 책임 분리(SRP), KST 날짜 로직 중앙화
  • 통합테스트로 조인·group by·프로젝션·p95 백분위 실검증(Testcontainers MySQL)
  • V9 번호 주의: 미머지 검색 PR([feat] 대화방 검색 (제목·채팅 내용) #43)도 V9를 씀 — 둘 중 하나 머지되면 나머지 renumber 필요

예상 후속

  • 품질 지표는 조회형 대시보드 — 추후 모니터링 스택(Prometheus/Grafana) 생기면 generation_log를 넘겨 알림까지 확장

Summary by CodeRabbit

Summary by CodeRabbit

  • 새 기능
    • 관리자 대시보드에서 사용량·도입과 LLM 품질·안정성 지표를 KPI 카드와 차트(감정 분포, 일별 활동, 생성 성공·실패)로 확인할 수 있습니다.
    • 대시보드 지표 API(usage/quality)와 기간(days) 기반 집계 엔드포인트가 추가되었습니다.
  • 개선
    • 대시보드 메뉴 상태 및 기본 진입 경로를 /dashboard로 정리했습니다.
    • 로딩/오류 시 스켈레톤과 재시도 UI를 제공하고, 성공률·지연·토큰·막힌 요청 등 핵심 지표를 표시합니다.
  • 인프라/테스트
    • 생성 로그 기반 집계와 관련 DB 인덱스/통합 테스트를 추가했습니다.

- 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)
- '오늘 메시지'를 '유저당 평균 메시지'(오늘 유저 발화 / DAU)로 교체
- UsageStatsResponse: avgMessagesPerUser 추가, todayCharacterMessages 제거
@theminjunchoi theminjunchoi self-assigned this Jul 26, 2026
@github-actions

github-actions Bot commented Jul 26, 2026

Copy link
Copy Markdown

Test Results

279 tests  +3   279 ✅ +3   1m 20s ⏱️ -1s
 45 suites +1     0 💤 ±0 
 45 files   +1     0 ❌ ±0 

Results for commit e164a9d. ± Comparison against base commit e8b9f67.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Jul 26, 2026

Copy link
Copy Markdown

Test Coverage

Overall Project 74.34% -1.2% 🍏
Files changed 89.71% 🍏

File Coverage
GenerationType.kt 100% 🍏
KstDashboardDates.kt 100% 🍏
QualityStatsService.kt 100% 🍏
UsageStatsService.kt 100% 🍏
QualityStatsResponse.kt 95.65% -4.35% 🍏
UsageStatsResponse.kt 94.74% -5.26% 🍏
EmotionCountResponse.kt 90.91% -9.09% 🍏
DailyActivityResponse.kt 88.89% -11.11% 🍏
CommentGenerationService.kt 86.98% -5.07% 🍏
GenerationLog.kt 84.62% -15.38% 🍏
GenerationLogRecorder.kt 71.93% -28.07% 🍏
MessageRepository.kt 66.67% 🍏
ConversationRepository.kt 57.14% 🍏
DailyGenerationResponse.kt 57.14% -42.86% 🍏
CardRepository.kt 57.14% 🍏
AdminDashboardController.kt 39.13% -60.87% 🍏

좁은 카드에서 6종 범례가 5+1로 어색하게 접히던 것을 3+3 균등 2줄로 변경
@coderabbitai

coderabbitai Bot commented Jul 26, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 5272c279-cfa0-4efc-858d-bf1830f94966

📥 Commits

Reviewing files that changed from the base of the PR and between 9b21019 and e164a9d.

📒 Files selected for processing (1)
  • src/main/resources/db/migration/V10__messages_comment_status_index.sql

Walkthrough

관리자 대시보드에 사용량·LLM 품질 통계 API와 웹 UI를 추가했습니다. 생성 로그를 저장해 성공률, 재시도, 지연, 토큰 및 일별 추이를 집계하고 /dashboard 라우트와 사용량·품질 차트를 제공합니다.

Changes

대시보드 모니터링 기능

Layer / File(s) Summary
LLM 생성 로그 기록
src/main/kotlin/com/nexters/gamss/monitoring/..., src/main/kotlin/com/nexters/gamss/conversation/service/CommentGenerationService.kt, src/test/kotlin/com/nexters/gamss/conversation/service/CommentGenerationServiceTest.kt
생성 로그 스키마·엔티티·저장소를 추가하고 댓글·답글 생성의 성공·실패·재시도 정보를 best-effort로 기록합니다.
대시보드 데이터 계약과 집계 기반
src/main/kotlin/com/nexters/gamss/admin/controller/dto/*, src/main/kotlin/com/nexters/gamss/admin/service/KstDashboardDates.kt, src/main/kotlin/com/nexters/gamss/*/repository/*
사용량·품질 응답 DTO, KST 날짜 계산, 도메인별 집계 쿼리를 추가합니다.
통계 서비스와 관리자 API
src/main/kotlin/com/nexters/gamss/admin/service/*StatsService.kt, src/main/kotlin/com/nexters/gamss/admin/controller/AdminDashboardController.kt, src/test/kotlin/com/nexters/gamss/admin/service/DashboardStatsIntegrationTest.kt
사용량·품질 통계를 계산하고 기간 제한이 있는 두 API로 반환하며 통합 테스트로 주요 집계값과 null 비율을 검증합니다.
대시보드 라우팅과 페이지 구성
admin-web/src/App.tsx, admin-web/src/components/layout/AdminLayout.tsx, admin-web/src/components/metric-card.tsx, admin-web/src/pages/dashboard/index.tsx
/dashboard 라우트와 기본 리다이렉트를 추가하고 대시보드 내비게이션을 활성화했으며 페이지 셸과 KPI 카드를 구성합니다.
사용량·품질 시각화
admin-web/src/pages/dashboard/*
API 응답을 KPI 카드와 recharts 기반 차트로 표시하고 로딩·오류·빈 데이터 상태를 처리합니다.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant AdminWeb
  participant AdminDashboardController
  participant UsageStatsService
  participant QualityStatsService
  participant Repositories
  AdminWeb->>AdminDashboardController: 사용량 또는 품질 통계 요청
  AdminDashboardController->>UsageStatsService: days 전달
  AdminDashboardController->>QualityStatsService: days 전달
  UsageStatsService->>Repositories: 사용량 집계 쿼리 실행
  QualityStatsService->>Repositories: 생성 로그 품질 집계 조회
  Repositories-->>UsageStatsService: 사용량 원시 결과
  Repositories-->>QualityStatsService: 품질 원시 결과
  UsageStatsService-->>AdminDashboardController: UsageStatsResponse
  QualityStatsService-->>AdminDashboardController: QualityStatsResponse
  AdminDashboardController-->>AdminWeb: ApiResponse 응답
Loading

Possibly related PRs

  • Nexters/GAMSS-Server#13: GenerationLogRecorderCommentGenerationService에 주입해 생성 시도 메타데이터를 기록하는 변경과 직접 연결됩니다.
  • Nexters/GAMSS-Server#34: 같은 댓글·답글 재시도 흐름의 상태 전이와 생성 로깅 변경이 코드 수준에서 맞닿아 있습니다.
  • Nexters/GAMSS-Server#48: 댓글·답글 생성 API 흐름과 GenerationLogRecorder 주입 지점이 직접 연결됩니다.

Suggested reviewers: kite707

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning 사용량 지표에서 오늘 메시지 수(유저/캐릭터) 요구가 유저 발화/평균 메시지로만 보이며, 총 메시지 KPI가 빠져 있습니다. 오늘 메시지 총량(유저+캐릭터) KPI를 추가하고, 필요하면 유저/캐릭터를 분리한 카드나 합산 지표로 명시하세요.
Docstring Coverage ⚠️ Warning Docstring coverage is 62.22% 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
Title check ✅ Passed 제목이 백오피스 대시보드의 사용량·LLM 품질 모니터링이라는 핵심 변경을 정확히 요약합니다.
Description check ✅ Passed 필수 섹션(연관 이슈, 개요, 주요 변경사항, API·DB 영향, 리뷰 포인트)이 모두 채워져 템플릿을 충족합니다.
Out of Scope Changes check ✅ Passed 대부분의 변경이 대시보드 API, 집계, UI, 마이그레이션에 직접 연관되어 별도 범위 변경은 보이지 않습니다.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/51-dashboard

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: 10

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/test/kotlin/com/nexters/gamss/conversation/service/CommentGenerationServiceTest.kt (1)

40-51: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

생성 로그 계약을 검증하는 테스트를 추가하세요.

현재 relaxed mock은 주입만 검증하므로 타입·성공 여부·재시도 횟수·토큰·최종 실패 기록이 깨져도 테스트가 통과합니다. 빠른 단위 테스트에서 record() 인자를 검증하는 방안은 변경 비용이 낮고 계약을 명확히 보장합니다. 저장소 통합 테스트는 DB 매핑까지 확인할 수 있지만 실행 비용이 더 큽니다.

검증 예시
verify(exactly = 1) {
    generationLogRecorder.record(
        type = GenerationType.COMMENT,
        success = true,
        attemptCount = 1,
        latencyMs = any(),
        usedTokens = 123,
    )
}

verify(exactly = 1) {
    generationLogRecorder.record(
        type = GenerationType.COMMENT,
        success = false,
        attemptCount = 2,
        latencyMs = any(),
        usedTokens = null,
        failureReason = any(),
    )
}
🤖 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/kotlin/com/nexters/gamss/conversation/service/CommentGenerationServiceTest.kt`
around lines 40 - 51, generationLogRecorder is relaxed without verifying the
generation-log contract. Add unit-test assertions around
CommentGenerationService scenarios that verify GenerationLogRecorder.record()
receives the expected COMMENT type, success status, attempt count, token usage,
latency, and failureReason for both successful and final-failure outcomes.
🤖 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 `@admin-web/src/pages/dashboard/quality-section.tsx`:
- Line 72: Update the quality stats request in the component using useCustom to
consume its error state and render an explicit failure state when the API
request fails, instead of allowing undefined stats to return null. Preserve the
existing loading and successful-data rendering behavior, and apply the same
handling to the usage section’s corresponding useCustom flow.
- Around line 45-69: Remove the duplicated short() and GenerationTooltip
implementations from the quality section, and reuse the existing shared
equivalents from usage-section.tsx, including ActivityTooltip where applicable.
Update the quality section’s references and imports so its current chart
behavior remains unchanged.

In `@admin-web/src/pages/dashboard/usage-section.tsx`:
- Around line 59-96: Remove the duplicated short() and ActivityTooltip
implementations from usage-section.tsx and reuse the corresponding shared
symbols already defined in quality-section.tsx, preserving the existing tooltip
behavior and formatting.
- Line 99: Update the useCustom destructuring and rendering in the usage section
to handle error and isError, matching the pattern in quality-section.tsx.
Display an API failure state separately from the existing no-data state,
including the applicable handling around the logic at lines 118-120.
- Around line 154-178: Update the emotion legend rendering alongside the
hasEmotion check in the dashboard usage section so it is shown only when
hasEmotion is true; when no emotion data exists, display only the existing “데이터
없음” state and omit the emotionData entries. Keep the chart and legend rendering
unchanged for populated data.

In `@src/main/kotlin/com/nexters/gamss/admin/service/KstDashboardDates.kt`:
- Around line 14-26: Update the KstDashboardDates calculation flow so one
LocalDate is captured at the service entry point and reused for sinceDaysAgo(),
startOfToday(), startOfTomorrow(), and dateAxis() instead of each method calling
today(). Prefer injecting a Clock for obtaining the captured KST date, and pass
that reference date through the related service calculations to keep KPI ranges
and date axes consistent.

In `@src/main/kotlin/com/nexters/gamss/admin/service/QualityStatsService.kt`:
- Around line 27-50: Update QualityStatsService.getQualityStats so aggregate
success, retry, latency, token, and percentile statistics are computed by the
database rather than loading every GenerationLog through findAllSince(since).
Add or reuse a repository-level aggregation query/projection, while preserving
the existing response values and dailyGeneration behavior.

In `@src/main/kotlin/com/nexters/gamss/admin/service/UsageStatsService.kt`:
- Around line 64-85: Update UsageStatsService.buildDailyActivity and the
corresponding QualityStatsService aggregation to use database-side date GROUP BY
queries instead of loading all timestamps through findCreatedAtsSince and
grouping with bucketByDate. Preserve the existing KST date buckets and
DailyActivityResponse results, and reuse shared query logic where appropriate.

In
`@src/main/kotlin/com/nexters/gamss/conversation/service/CommentGenerationService.kt`:
- Around line 161-164: 재시도 루프가 예상 밖 예외도 품질 로그에 남기도록 수정하세요.
src/main/kotlin/com/nexters/gamss/conversation/service/CommentGenerationService.kt의
161-164 및 207-210에서 각 루프에 별도 catch (e: Exception)를 추가해 현재 시도 횟수와 지연 시간을 기록한 뒤 즉시
재던지며, 기존 CommentGenerationFailedException 재시도 정책은 유지하세요. 같은 파일 176-182의
failureReasonOf는 Throwable?을 받아 예상 밖 예외의 메시지 또는 안전한 요약을 반환하도록 변경하세요.

In
`@src/test/kotlin/com/nexters/gamss/admin/service/DashboardStatsIntegrationTest.kt`:
- Around line 40-121: 보정 지표의 0건 분모 null 반환 경로를 통합 테스트로 검증하세요. 기존 `사용량 지표를 집계한다`
및 `LLM 품질 지표를 집계한다` 테스트와 별도로 데이터가 없는 기간을 조회해 `avgMessagesPerUser`,
`successRate`, `retryRate`가 각각 null인지 assert하고, 기존 비어 있지 않은 케이스 검증은 유지하세요.

---

Outside diff comments:
In
`@src/test/kotlin/com/nexters/gamss/conversation/service/CommentGenerationServiceTest.kt`:
- Around line 40-51: generationLogRecorder is relaxed without verifying the
generation-log contract. Add unit-test assertions around
CommentGenerationService scenarios that verify GenerationLogRecorder.record()
receives the expected COMMENT type, success status, attempt count, token usage,
latency, and failureReason for both successful and final-failure outcomes.
🪄 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: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 1a643299-2f69-4bd2-963e-d07142dbe8e9

📥 Commits

Reviewing files that changed from the base of the PR and between 4ef6970 and 2940101.

📒 Files selected for processing (28)
  • admin-web/src/App.tsx
  • admin-web/src/components/layout/AdminLayout.tsx
  • admin-web/src/components/metric-card.tsx
  • admin-web/src/pages/dashboard/index.tsx
  • admin-web/src/pages/dashboard/quality-section.tsx
  • admin-web/src/pages/dashboard/usage-section.tsx
  • src/main/kotlin/com/nexters/gamss/admin/controller/AdminDashboardController.kt
  • src/main/kotlin/com/nexters/gamss/admin/controller/dto/DailyActivityResponse.kt
  • src/main/kotlin/com/nexters/gamss/admin/controller/dto/DailyGenerationResponse.kt
  • src/main/kotlin/com/nexters/gamss/admin/controller/dto/EmotionCountResponse.kt
  • src/main/kotlin/com/nexters/gamss/admin/controller/dto/QualityStatsResponse.kt
  • src/main/kotlin/com/nexters/gamss/admin/controller/dto/UsageStatsResponse.kt
  • src/main/kotlin/com/nexters/gamss/admin/service/KstDashboardDates.kt
  • src/main/kotlin/com/nexters/gamss/admin/service/QualityStatsService.kt
  • src/main/kotlin/com/nexters/gamss/admin/service/UsageStatsService.kt
  • src/main/kotlin/com/nexters/gamss/card/repository/CardRepository.kt
  • src/main/kotlin/com/nexters/gamss/card/repository/EmotionCountProjection.kt
  • src/main/kotlin/com/nexters/gamss/conversation/repository/ConversationRepository.kt
  • src/main/kotlin/com/nexters/gamss/conversation/repository/MessageRepository.kt
  • src/main/kotlin/com/nexters/gamss/conversation/service/CommentGenerationService.kt
  • src/main/kotlin/com/nexters/gamss/member/repository/MemberRepository.kt
  • src/main/kotlin/com/nexters/gamss/monitoring/domain/GenerationLog.kt
  • src/main/kotlin/com/nexters/gamss/monitoring/domain/GenerationType.kt
  • src/main/kotlin/com/nexters/gamss/monitoring/repository/GenerationLogRepository.kt
  • src/main/kotlin/com/nexters/gamss/monitoring/service/GenerationLogRecorder.kt
  • src/main/resources/db/migration/V9__generation_log.sql
  • src/test/kotlin/com/nexters/gamss/admin/service/DashboardStatsIntegrationTest.kt
  • src/test/kotlin/com/nexters/gamss/conversation/service/CommentGenerationServiceTest.kt

Comment thread admin-web/src/pages/dashboard/quality-section.tsx Outdated
Comment thread admin-web/src/pages/dashboard/quality-section.tsx Outdated
Comment thread admin-web/src/pages/dashboard/usage-section.tsx Outdated
Comment thread admin-web/src/pages/dashboard/usage-section.tsx Outdated
Comment thread admin-web/src/pages/dashboard/usage-section.tsx
Comment thread src/main/kotlin/com/nexters/gamss/admin/service/KstDashboardDates.kt Outdated
- 생성 재시도 루프에서 예상 밖 예외도 generation_log에 기록 후 재던짐
  (기존엔 CommentGenerationFailedException만 기록돼 성공률이 과대 집계)
- KstDashboardDates: 요청당 기준 날짜(today)를 한 번만 캡처해 전달
  (자정 경계에서 KPI 범위와 일별 축 기준일 어긋남 방지)
- 프론트: API 실패 시 에러 상태(재시도) 표시, 감정 범례 hasEmotion 가드
- 프론트: shortDate·SeriesTooltip·SectionError 공통 모듈로 중복 제거
- 데이터 0건일 때 평균·비율 null 반환 테스트 추가
# Conflicts:
#	src/main/kotlin/com/nexters/gamss/conversation/service/CommentGenerationService.kt

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
admin-web/src/pages/dashboard/quality-section.tsx (1)

15-24: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

빈 기간의 지연 시간을 nullms로 표시하지 않도록 nullable 계약을 반영하세요.

Line 22-23이 number로 고정되어 있어 API가 빈 기간에 null을 반환하면 Line 36에서 nullms가 렌더링됩니다. avgLatencyMs/p95LatencyMsnumber | null로 선언하고 latency(null)를 반환하세요.

수정 예시
-interface QualityStats {
-  avgLatencyMs: number
-  p95LatencyMs: number
+interface QualityStats {
+  avgLatencyMs: number | null
+  p95LatencyMs: number | null
 }

-function latency(ms: number): string {
+function latency(ms: number | null): string {
+  if (ms === null) return '—'
   if (ms >= 1000) {

Also applies to: 32-37

🤖 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 `@admin-web/src/pages/dashboard/quality-section.tsx` around lines 15 - 24,
Update the QualityStats interface so avgLatencyMs and p95LatencyMs accept number
| null, and adjust the latency rendering logic to return an em dash for null
values instead of producing “nullms”; preserve the existing millisecond
formatting for numeric values.
src/test/kotlin/com/nexters/gamss/conversation/service/CommentGenerationServiceTest.kt (1)

40-51: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

생성 로그 기록 계약도 검증하세요.

GenerationLogRecorder가 relaxed mock이라 기록 호출이 빠지거나 attemptCount가 틀려도 테스트가 통과합니다. 성공, 재시도 소진, 비재시도 예외 각각에 대해 type, success, attemptCountverify해 대시보드 집계의 핵심 입력을 보호하세요.

🤖 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/kotlin/com/nexters/gamss/conversation/service/CommentGenerationServiceTest.kt`
around lines 40 - 51, CommentGenerationServiceTest에서 relaxed mock인
generationLogRecorder에 대한 계약 검증이 빠져 있다. 성공, 재시도 소진, 비재시도 예외를 다루는 각 테스트에
GenerationLogRecorder 호출 검증을 추가하고, 기록된 type·success·attemptCount가 각 시나리오의 기대값과
일치하는지 확인하라.
🤖 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.

Outside diff comments:
In `@admin-web/src/pages/dashboard/quality-section.tsx`:
- Around line 15-24: Update the QualityStats interface so avgLatencyMs and
p95LatencyMs accept number | null, and adjust the latency rendering logic to
return an em dash for null values instead of producing “nullms”; preserve the
existing millisecond formatting for numeric values.

In
`@src/test/kotlin/com/nexters/gamss/conversation/service/CommentGenerationServiceTest.kt`:
- Around line 40-51: CommentGenerationServiceTest에서 relaxed mock인
generationLogRecorder에 대한 계약 검증이 빠져 있다. 성공, 재시도 소진, 비재시도 예외를 다루는 각 테스트에
GenerationLogRecorder 호출 검증을 추가하고, 기록된 type·success·attemptCount가 각 시나리오의 기대값과
일치하는지 확인하라.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: d1d0b8f0-0635-415e-a77c-50c31389a5f2

📥 Commits

Reviewing files that changed from the base of the PR and between 2940101 and 9b21019.

📒 Files selected for processing (9)
  • admin-web/src/pages/dashboard/chart-shared.tsx
  • admin-web/src/pages/dashboard/quality-section.tsx
  • admin-web/src/pages/dashboard/usage-section.tsx
  • src/main/kotlin/com/nexters/gamss/admin/service/KstDashboardDates.kt
  • src/main/kotlin/com/nexters/gamss/admin/service/QualityStatsService.kt
  • src/main/kotlin/com/nexters/gamss/admin/service/UsageStatsService.kt
  • src/main/kotlin/com/nexters/gamss/conversation/service/CommentGenerationService.kt
  • src/test/kotlin/com/nexters/gamss/admin/service/DashboardStatsIntegrationTest.kt
  • src/test/kotlin/com/nexters/gamss/conversation/service/CommentGenerationServiceTest.kt

@kite707 kite707 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

질문에 잘 답변해주셔서 감사합니다! 늦은 시간까지 고생하셨어요!

청소 스케줄러·대시보드 막힌 PENDING 지표가 comment_status + comment_status_updated_at
조건으로 조회하는데 인덱스가 없어 messages 전체를 스캔(스케줄러는 1분마다)한다.
가장 빠르게 커지는 테이블이라 스캔 비용 누적을 막기 위해 복합 인덱스를 둔다.
@theminjunchoi
theminjunchoi merged commit 7518b4b into dev Jul 27, 2026
5 checks passed
@theminjunchoi
theminjunchoi deleted the feat/51-dashboard branch July 27, 2026 14:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[feat] 백오피스 대시보드: 사용량·LLM 품질 모니터링

2 participants