[HSC-396] 실시간 이탈 위험도 커서 조회 추가#249
Conversation
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! 이 PR은 관리자 대시보드에서 실시간 이탈 위험도를 효율적으로 모니터링할 수 있도록 새로운 API 엔드포인트를 도입합니다. 커서 기반의 데이터 조회 방식을 통해 초기 데이터 로딩과 이후 변경분 폴링을 최적화하고, 이탈 스냅샷 데이터에 변경 이력을 추적할 수 있는 필드를 추가하여 시스템의 실시간성을 강화했습니다. 이를 통해 관리자는 최신 이탈 위험 정보를 신속하게 파악하고 대응할 수 있습니다. Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. Footnotes
|
🧪 Test Coverage Report (JaCoCo)
Package line spark (sample): 📦 Package coverage (worst 10)
🧨 Lowest coverage classes (worst 10)
🧩 Changed files coverage breakdown (8 files)
🔎 HTML 리포트: Actions → Artifacts → |
📝작업 내용
latestAPI와 3초 폴링용changesAPI를 커서 기반 구현churn_score_snapshot에 변경 커서용revision_id와updated_at을 추가하고, churn snapshot 저장 시점마다 함께 갱신되도록 변경risk_reasons.summary를reason으로 내려주고, 회원 이름은 복호화 후 마스킹해서 반환 구현👀변경 사항
변경 요약
GET /api/v1/admin/churn/latestGET /api/v1/admin/churn/changeschurn_score_snapshot.revision_id추가afterId로 사용churn_score_snapshot.updated_at추가timeStamp로 사용revision_id,updated_at갱신risk_reasons[0].summary->reasonHIGH,MEDIUM지원MID미사용API 스펙
/api/v1/admin/churn/latestlimit,level/api/v1/admin/churn/changesafterId,limit,level응답 아이템 매핑
churnIdchurn_score_snapshot.revision_idmemberIdmember.member_idreasonrisk_reasons첫 번째summarychurnLevelchurn_score_snapshot.risk_levelmemberNametimeStampchurn_score_snapshot.updated_at주요 변경 파일
src/main/java/site/holliverse/admin/web/controller/ChurnRealTimeController.javalatest/changesAPI 진입점src/main/java/site/holliverse/admin/web/dto/churn/ChurnRealTimeRequestDto.javasrc/main/java/site/holliverse/admin/web/dto/churn/ChurnRealTimeResponseDto.javasrc/main/java/site/holliverse/admin/application/usecase/RetrieveChurnRealtimeUseCase.javasrc/main/java/site/holliverse/admin/query/dao/ChurnRealtimeDao.javasrc/main/java/site/holliverse/admin/query/dao/ChurnRealtimeRawData.javasrc/main/java/site/holliverse/admin/web/assembler/ChurnRealtimeAssembler.javasrc/main/java/site/holliverse/admin/application/usecase/ChurnSnapshotStoreService.javasrc/main/resources/db/migration/V34__add_churn_revision_cursor.sqlrevision_id,updated_at추가 migration변경 로직
flowchart LR A["상담 / 로그 / 배치 feature 갱신"] --> B["ChurnSnapshotStoreService"] B --> C["churn_score_snapshot upsert"] C --> D["revision_id 재발급"] C --> E["updated_at 갱신"] F["GET /churn/latest"] --> G["revision_id desc 조회"] H["GET /churn/changes?afterId=N"] --> I["revision_id > N 조회"] G --> J["ChurnRealtimeAssembler"] I --> J J --> K["items / afterId / hasMore 응답"]저장 구조 변경
flowchart TD A["기존 feature score 계산"] --> B["총 churn score 계산"] B --> C["churn_score_snapshot 저장"] C --> D["revision_id 증가"] C --> E["updated_at = now()"] D --> F["폴링 커서 사용"] E --> G["목록 시각 표시"]사이드 이펙트
revision_id는 변경 히스토리 테이블이 아니라 현재 snapshot row의 최신 변경 커서입니다.revision_id,updated_at이 채워지고 이후 갱신부터 실시간 커서 의미가 명확해집니다.base_date = today조건을 유지합니다.검증
./gradlew compileJava -x flywayMigrate -x generateJooq./gradlew test --tests "*ArchitectureRulesTest" -x flywayMigrate -x generateJooqafterId = 10001000확인🎫 Jira Ticket
#️⃣관련 이슈