24 KiB
24 KiB
에이전트 정산 기능 QA 계획
QA 목표
- 최근 구현된 agent authorization 및 settlement 기능에서 남아 있는 실제 결함을 백엔드 관점으로 점검한다.
- 범위는
src/main/kotlin/kr/co/vividnext/sodalive/admin/partner/agent/**,src/main/kotlin/kr/co/vividnext/sodalive/partner/agent/**로 한정한다. - 이미 수용된 두 가지 저우선순위 이슈(빈 finalized 기간 미생성, 중복 finalize 동시성 rough edge)는 제외한다.
작업 체크리스트
- 관련 모듈/테스트/기존 작업 문서를 확인해 QA 범위를 정리한다.
- 백엔드 QA 시나리오를 20개 이상 도출하고 P0/P1/P2로 분류한다.
- P0/P1 시나리오를 중심으로 기존 테스트와 실행형 검증 명령을 수행한다.
- 실패 시 재현 경로와 실제 증거를 확보해 결함 여부를 확정한다.
- 최종 PASS/FAIL 판정을 정리하고 검증 기록을 남긴다.
구현 체크리스트
- assignment/finalize 가드 미체크 항목 회귀 테스트를 추가한다.
- calculate empty-result/snapshot pagination/finalized immutability 회귀 테스트를 추가한다.
- ratio 목록 응답을 member 단위 current/history 구조로 확장한다.
- generic 4종 calculate total 경로를 전용 total 계산 경로로 분리한다.
- finalize snapshot 생성 경로의 중복 groupBy/row 변환을 줄인다.
- 관련 테스트, 진단, 수동 검증 결과를 문서에 반영한다.
검증 대상 축
- assignment create/remove 시간 경계 동작
- ratio create/update 검증과 history 동작
- calculate 5개 카테고리 조회
- snapshot finalize 및 finalized 조회
- provenance/source detail 무결성
- 신규 validation과 기존 동작의 상호작용
시나리오 목록
P0
- assignment 생성: 유효한 agent/creator/assignedAt이면 신규 이력 row가 생성된다.
- assignment 생성: agentId와 creatorId가 같으면 거부된다.
- assignment 생성: agent가 AGENT 역할이 아니면 거부된다.
- assignment 생성: creator가 CREATOR 역할이 아니면 거부된다.
- assignment 생성: 활성 소속과 시간이 겹치면 거부된다.
- assignment 생성: 이전 소속의
unassignedAt과 동일한assignedAt은 허용된다. - assignment 해제: 활성 소속이면
unassignedAt이 기록된다. - assignment 해제:
unassignedAt <= assignedAt이면 거부된다. - assigned creator 목록 조회: 다른 agent 소속 creator는 제외된다.
- assigned creator 목록 조회: 미래
assignedAt만 가진 예약 소속은 현재 목록에 노출되지 않아야 한다. - assigned creator 목록 조회: 미래
unassignedAt이 있는 현재 소속은 종료 전까지 유지되어야 한다. - ratio 생성: 유효한
effectiveFrom이면 활성 row 종료 후 신규 이력 row가 추가된다. - ratio 생성/수정:
settlementRatio가 0..100 범위를 벗어나면 거부된다. - ratio 생성/수정: 과거 closed history 구간과 겹치는
effectiveFrom이면 거부된다. - calculate 조회: 5개 카테고리 모두 거래 시점 assignment를 기준으로 agent가 갈린다.
- calculate 조회: 5개 카테고리 모두 거래 시점 ratio를 기준으로 agentSettlementAmount가 계산된다.
- calculate 조회: content는 콘텐츠 개별 ratio와 creator 기본 ratio fallback을 모두 반영한다.
- calculate 조회: 일반 정산/채널후원 모두 agent ratio 이력이 없으면 10% fallback이 적용된다.
- snapshot finalize: LIVE finalize는 immutable snapshot과 source detail을 함께 저장한다.
- snapshot finalize: 기간 내 source row가 여러 개면 summary FK는 비우고 provenance detail만 남긴다.
- finalized read: 5개 카테고리 모두 동일 기간 finalized snapshot을 live 계산보다 우선 사용한다.
- snapshot finalize: 동일 기간/타입/agent 재요청은 중복 저장 없이 alreadyFinalized=true를 반환한다.
P1
- admin finalize: 대상 member가 없으면 실패한다.
- admin finalize: 대상 member가 AGENT 역할이 아니면 실패한다.
- agent controller: 익명 사용자는 creator/list 조회에 실패한다.
- admin finalize controller: 익명 사용자는 finalize 호출에 실패한다.
- channel donation 조회: 분할 정산 레코드가 있어도 후원 건수는 distinct useCan 기준이다.
- calculate 조회: 기간 내 결과가 없으면 total=0, items=[]로 일관되게 반환된다.
- assigned creator 목록 조회: 정렬/페이지네이션이 creatorId desc 기준으로 유지된다.
P2
- snapshot read: snapshot pagination이
creatorId desc기준으로 안정적이다. - ratio 목록 조회: current/history가 페이지 응답에서 누락 없이 노출된다.
- provenance detail 합계는 snapshot summary 합계와 일치한다.
- finalized 이후 ratio/assignment 변경이 생겨도 동일 finalized 기간 응답은 변하지 않는다.
미체크 항목 재확인 및 후속 방안
assignment 생성: agentId와 creatorId가 같으면 거부된다.- 현재 상태:
AdminAgentCreatorService.assignCreator()가 동일 ID를partner.agent.assignment.invalid_relation으로 즉시 거부한다 (src/main/kotlin/kr/co/vividnext/sodalive/admin/partner/agent/assignment/AdminAgentCreatorService.kt:22-25). - 후속 방안:
AdminAgentCreatorServiceTest에agentId == creatorId요청을 추가해 동일 예외 키를 직접 검증한다.
- 현재 상태:
admin finalize: 대상 member가 없으면 실패한다.- 현재 상태:
AdminAgentSettlementSnapshotService.getAgent()가 member 미존재 시partner.agent.ratio.agent_not_found를 던진다 (src/main/kotlin/kr/co/vividnext/sodalive/admin/partner/agent/settlement/AdminAgentSettlementSnapshotService.kt:122-128). - 후속 방안:
AdminAgentSettlementSnapshotServiceTest에memberRepository.findById()가 비어 있는 케이스를 추가해 finalize 진입 전 실패를 검증한다.
- 현재 상태:
admin finalize: 대상 member가 AGENT 역할이 아니면 실패한다.- 현재 상태: 같은
getAgent()에서 role이AGENT가 아니면partner.agent.ratio.invalid_agent를 던진다 (src/main/kotlin/kr/co/vividnext/sodalive/admin/partner/agent/settlement/AdminAgentSettlementSnapshotService.kt:122-128). - 후속 방안:
AdminAgentSettlementSnapshotServiceTest에USER또는CREATORrole member를 주입해 예외 키를 직접 검증한다.
- 현재 상태: 같은
calculate 조회: 기간 내 결과가 없으면 total=0, items=[]로 일관되게 반환된다.- 현재 상태: 조회 repository는 total count를
?: 0으로 반환하고, 페이지 대상 creator가 없으면 빈 목록을 반환한다. 서비스도 이 값을 그대로 응답으로 조립한다 (src/test/kotlin/kr/co/vividnext/sodalive/partner/agent/calculate/AgentCalculateQueryRepositoryTest.kt:272-326,src/main/kotlin/kr/co/vividnext/sodalive/partner/agent/calculate/AgentCalculateService.kt:200-211). - 후속 방안: in-range 데이터가 전혀 없는 fixture로
AgentCalculateService또는 query integration test를 추가해total.count/total.totalCan/...가 모두 0이고items=[]인 응답 계약을 직접 고정한다.
- 현재 상태: 조회 repository는 total count를
snapshot read: snapshot pagination이 creatorId desc 기준으로 안정적이다.- 현재 상태: snapshot 조회는
findAllByPeriodStartAndPeriodEndAndSettlementTypeAndAgentIdOrderByCreatorIdDesc(...)를 사용해 정렬 기준 자체는 명시되어 있다 (src/main/kotlin/kr/co/vividnext/sodalive/partner/agent/settlement/snapshot/AgentSettlementSnapshotRepository.kt:14-19). 다만 다건 snapshot에서 offset/limit slicing 순서를 직접 검증하는 테스트는 없다. - 후속 방안:
AgentCalculateServiceTest에 creatorId가 다른 snapshot 3건 이상을 주입하고,offset/limit별 응답 순서와 크기를 검증하는 회귀 테스트를 추가한다.
- 현재 상태: snapshot 조회는
ratio 목록 조회: current/history가 페이지 응답에서 누락 없이 노출된다.- 현재 상태: 현재 응답 DTO는
items: List<GetAgentSettlementRatioItem>단일 flat 구조이고 (src/main/kotlin/kr/co/vividnext/sodalive/partner/agent/ratio/GetAgentSettlementRatioResponse.kt:6-17), query도 ratio row를 flat list로만 조회한다 (src/main/kotlin/kr/co/vividnext/sodalive/partner/agent/ratio/AgentSettlementRatioRepository.kt:23-49). 기존 서비스 테스트도 flat 목록 1건만 검증한다 (src/test/kotlin/kr/co/vividnext/sodalive/admin/partner/agent/ratio/AgentSettlementRatioServiceTest.kt:344-367). - 구현 방안:
current/history를 분리한 응답 DTO를 새로 정의하고, query/service 계층에서 member별 ratio row를 current 1건 + history n건으로 재구성하도록 응답 모델을 확장한다. 페이지 기준은 member 단위로 재정의하고, current/history 누락 회귀 테스트를 함께 추가한다.
- 현재 상태: 현재 응답 DTO는
finalized 이후 ratio/assignment 변경이 생겨도 동일 finalized 기간 응답은 변하지 않는다.- 현재 상태: finalize는 snapshot/source detail에 당시 값을 저장하고 (
src/test/kotlin/kr/co/vividnext/sodalive/admin/partner/agent/settlement/AdminAgentSettlementSnapshotServiceTest.kt:44-202), 읽기 경로는 finalized snapshot을 live 계산보다 우선 사용한다 (src/test/kotlin/kr/co/vividnext/sodalive/partner/agent/calculate/AgentCalculateServiceTest.kt:458-598). 다만 finalize 이후 assignment/ratio를 실제로 바꾼 뒤 같은 기간 재조회가 불변인지 직접 검증하는 테스트는 없다. - 후속 방안: finalize 이후 assignment/ratio fixture를 변경한 뒤 동일 기간 read 응답이 snapshot 값 그대로 유지되는지를 검증하는 통합 회귀 테스트를 추가한다.
- 현재 상태: finalize는 snapshot/source detail에 당시 값을 저장하고 (
추가 구조/성능 메모
우선 반영 1순위: AgentCalculateService.buildSettlementByCreatorResponse()의totalRowsLoader기반 total 계산을 DB total query로 분리한다.- 현재 경로: generic 4종(LIVE/CONTENT/COMMUNITY/CONTENT_DONATION) total은
totalRowsLoader(startDate, endDate).toMergedResponseItems().toResponseTotal()로 계산된다 (src/main/kotlin/kr/co/vividnext/sodalive/partner/agent/calculate/AgentCalculateService.kt:200-203). - 현재 비용: 기간 전체
GetAgentCreatorSettlementSummaryQueryData를 메모리에 적재한 뒤, 각 row마다toResponseItem()에서BigDecimal기반 금액 계산을 수행하고 (src/main/kotlin/kr/co/vividnext/sodalive/partner/agent/calculate/GetAgentCreatorSettlementSummaryQueryData.kt:17-40), 다시groupBy { creatorId }로 creator별 병합 후 (.../GetAgentCreatorSettlementSummaryQueryData.kt:60-77), 마지막에sumOf로 grand total을 한 번 더 순회한다 (src/main/kotlin/kr/co/vividnext/sodalive/partner/agent/calculate/GetAgentSettlementByCreatorResponse.kt:33-43). - 왜 1순위인가: pagedRowsLoader는 페이지 범위만 읽지만 totalRowsLoader는 기간 전체 row를 읽는다. 따라서 메모리 사용량과 GC 비용, total 계산 지연을 동시에 줄이려면 total 경로를 먼저 제거하는 편이 효과가 가장 크다.
- row granularity 주의점: total을 단순
sum(totalCan)으로 바꾸면 안 된다. 현재 row는 creator 1건이 아니라 assignment/agent ratio/settlement ratio 기준으로 분할되어 있고 (src/main/kotlin/kr/co/vividnext/sodalive/partner/agent/calculate/AgentCalculateQueryRepository.kt:392-596), 같은 creator도 콘텐츠 개별 ratio 차이로 여러 row가 생긴다 (src/test/kotlin/kr/co/vividnext/sodalive/partner/agent/calculate/AgentCalculateQueryRepositoryTest.kt:145-176). 또한 거래 시점 assignment/agent ratio 이력 때문에 row가 갈라진다 (.../AgentCalculateQueryRepositoryTest.kt:328-381,421-470). - 핵심 관찰: total 계산에서 creator별 병합 자체는 필수가 아니다. 현재 로직은 row → creator 병합 → grand total 순서지만, 최종 total 값은 row별 계산 결과를 그대로 모두 더한 값과 동일하다. 즉 total 전용 경로는 creator 응답 shape를 만들 필요 없이 “현재 row granularity의 정산 결과 총합”만 DB에서 반환하면 된다.
- 권장 구현 방안:
AgentCalculateQueryRepository에 generic 4종용getCalculate*Total()전용 query를 추가하고,GetAgentSettlementByCreatorTotal에 대응하는 total projection을fetchOne()으로 바로 반환한다. 이때 현재 반올림/비율 적용 semantics를 유지하려면, 기존 grouped row granularity를 유지한 뒤 그 row 단위 정산 금액을 다시 합산하는 형태가 필요하다. Spring Boot 2.7 + Querydsl JPA 제약을 고려하면, 1차 권장은 파생 테이블(native SQL 또는 Querydsl SQL/JPASQLQuery fallback) 기반 total query이고, 로컬 선례는 total을 목록 쿼리와 분리한AdminChannelDonationCalculateQueryRepository.getChannelDonationSettlementTotal()/CreatorAdminChannelDonationCalculateQueryRepository.getChannelDonationSettlementTotal()이다 (src/main/kotlin/kr/co/vividnext/sodalive/admin/calculate/channelDonation/AdminChannelDonationCalculateQueryRepository.kt:33-54,src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/calculate/channelDonation/CreatorAdminChannelDonationCalculateQueryRepository.kt:18-38). - 차선책: DB query 분리가 바로 어렵다면, 최소한 total 계산에서
.toMergedResponseItems()를 제거하고 row를 단일fold로 누적해 creator별groupBy/중간 리스트 생성을 없앨 수 있다. 다만 이 방법은 기간 전체 row 적재 자체는 남기므로 임시 완화책으로만 본다. - 구현 결과: 이번 단계에서는
List<GetAgentCreatorSettlementSummaryQueryData>.toResponseTotal()전용 경로를 추가해 generic 4종 total 계산에서 creator별groupBy와 중간GetAgentSettlementByCreatorItem리스트 병합을 제거했다. DB total query 분리는 Spring Boot 2.7 + Querydsl JPA 제약을 고려한 후속 최적화 후보로 남긴다.
- 현재 경로: generic 4종(LIVE/CONTENT/COMMUNITY/CONTENT_DONATION) total은
AdminAgentSettlementSnapshotService.finalizeSnapshots()는 DB가 assignment/ratio 단위로 이미 집계한 row를 creator별 snapshot 1건으로 다시 합산하는데, 이 합산 자체는 필요하지만rows.groupBy { creatorId }뒤에toMergedResponseItems()가 다시 같은 key로 groupBy를 수행해 불필요한 재-groupBy가 한 번 더 발생한다. 반면 source detail은 query row 1건을 detail 1건으로 보존하므로 추가 집계는 없고, 동일 row의toResponseItem()변환만 summary/detail에서 각각 반복된다 (src/main/kotlin/kr/co/vividnext/sodalive/admin/partner/agent/settlement/AdminAgentSettlementSnapshotService.kt:131-179,182-253).- 구현 방안: finalize 내부에서는 creator별 재-groupBy 없는 전용 merge 로직을 두고, row 변환 결과를 summary/detail 양쪽에서 재사용하도록 draft 구조를 조정한다.
- 구현 결과:
SnapshotAggregateDraft단일 패스 누적 구조로 summary/source detail 수치를 함께 합산하도록 바꿔 creator별 재-groupBy와 중복toResponseItem()변환을 제거했다.
검증 기록
1차 QA
- 무엇을:
- assignment/ratio/calculate/snapshot/controller 축의 기존 테스트를 집중 실행했다.
assigned creator list의 시간창(window) 처리 누락 여부를 임시 DataJpa 재현 테스트로 검증했다.
- 왜:
- 기존 테스트가 보장하는 범위와, 목록 조회처럼 테스트 공백이 있는 시간 경계 시나리오를 분리해서 확인해야 실제 latent bug를 잡을 수 있기 때문이다.
- 어떻게:
- 성공:
./gradlew test --tests kr.co.vividnext.sodalive.admin.partner.agent.assignment.AdminAgentCreatorServiceTest --tests kr.co.vividnext.sodalive.admin.partner.agent.ratio.AgentSettlementRatioServiceTest --tests kr.co.vividnext.sodalive.partner.agent.calculate.AgentCalculateServiceTest --tests kr.co.vividnext.sodalive.partner.agent.calculate.AgentCalculateQueryRepositoryTest --tests kr.co.vividnext.sodalive.admin.partner.agent.settlement.AdminAgentSettlementSnapshotServiceTest --tests kr.co.vividnext.sodalive.admin.partner.agent.settlement.AdminAgentSettlementSnapshotControllerTest --tests kr.co.vividnext.sodalive.partner.agent.calculate.AgentCalculateControllerTest→ BUILD SUCCESSFUL - 성공:
./gradlew test --tests kr.co.vividnext.sodalive.admin.partner.agent.assignment.AdminAgentCreatorControllerTest --tests kr.co.vividnext.sodalive.admin.partner.agent.ratio.AdminAgentSettlementRatioControllerTest→ BUILD SUCCESSFUL - 실패 재현 1: 임시 QA 테스트에서 미래
assignedAt예약 소속 목록 노출 검증 →TEST-kr.co.vividnext.sodalive.partner.agent.calculate.AgentAssignedCreatorFutureWindowQaTest.xml기준expected <0> but was <1> - 실패 재현 2: 임시 QA 테스트에서 미래
unassignedAt이전 현재 소속 유지 검증 →TEST-kr.co.vividnext.sodalive.partner.agent.calculate.AgentAssignedCreatorFutureWindowQaTest.xml기준expected <1> but was <0>
- 성공:
2차 QA 문서 정리
- 무엇을:
- 이후 수정/테스트로 증거가 확보된 QA 항목만 문서 상태를 최신화했다.
- 왜:
- 현재 QA 문서는 일부 항목이 이미 수정/검증되었는데도 실패 메모나 미체크 상태로 남아 있어, 실제 상태와 문서가 어긋나 있었기 때문이다.
- 어떻게:
src/test/kotlin/kr/co/vividnext/sodalive/partner/agent/calculate/AgentCalculateQueryRepositoryTest.kt:91-110확인 → 현재 시각 활성 구간 creator list 회귀 테스트가 미래assignedAt미노출 / 미래unassignedAt이전 유지 두 조건을 함께 검증함을 확인했다.docs/20260408_에이전트권한및정산기능추가.md:644-658확인 → 위 creator list window 버그가 17차 수정에서 실제 수정되고 테스트/빌드 검증까지 완료되었음을 확인했다.src/test/kotlin/kr/co/vividnext/sodalive/admin/partner/agent/settlement/AdminAgentSettlementSnapshotServiceTest.kt:191-201확인 → provenance detail 각 수치 합계가 snapshot summary와 일치하는 검증이 이미 존재함을 확인했다.- 위 세 근거에 따라 creator list 2개 항목의 실패 메모를 제거하고,
provenance detail 합계항목을 완료 처리했다.
3차 미체크 항목/구조 점검
- 무엇을:
- QA 문서에 남아 있던 미체크 항목을 구현/테스트 기준으로 다시 분류했다.
AgentCalculateService의 creator 합산 경로와AdminAgentSettlementSnapshotServicefinalize 경로의 중복 집계 여부를 코드 기준으로 재점검했다.
- 왜:
- 현재 문서에는 “구현은 이미 있으나 테스트가 빠진 항목”, “응답 모델 자체가 요구를 충족하지 못하는 항목”, “기능 결함은 아니지만 구조적으로 비효율적인 항목”이 섞여 있어 후속 작업 우선순위가 드러나지 않았기 때문이다.
- 어떻게:
- 명령 실행 없음: 이번 단계는 문서/코드 정합성 점검 목적이라 읽기 전용 파일 검토만 수행했다.
src/main/kotlin/kr/co/vividnext/sodalive/admin/partner/agent/assignment/AdminAgentCreatorService.kt:22-25확인 → 동일 agentId/creatorId 거부 로직은 구현돼 있으나 직접 테스트가 없음을 확인했다.src/test/kotlin/kr/co/vividnext/sodalive/partner/agent/calculate/AgentCalculateQueryRepositoryTest.kt:69-89및src/test/kotlin/kr/co/vividnext/sodalive/partner/agent/calculate/AgentCalculateControllerTest.kt:37-62확인 → assigned creator 정렬/페이지네이션은 이미 검증돼 있어 완료 처리했다.src/main/kotlin/kr/co/vividnext/sodalive/partner/agent/ratio/GetAgentSettlementRatioResponse.kt:6-17및src/main/kotlin/kr/co/vividnext/sodalive/partner/agent/ratio/AgentSettlementRatioRepository.kt:23-49확인 → ratio 목록은 flat 응답만 제공하므로current/history요구를 충족하려면 응답 모델과 조회 로직 확장이 필요함을 확인했다.src/main/kotlin/kr/co/vividnext/sodalive/partner/agent/calculate/AgentCalculateService.kt:141-168,172-211확인 → finalized snapshot 경로가 전체 snapshot row를 메모리에서 page/total 처리함을 확인했다.src/main/kotlin/kr/co/vividnext/sodalive/admin/partner/agent/settlement/AdminAgentSettlementSnapshotService.kt:131-179,182-253확인 → finalize summary 생성 시 creator별 재-groupBy가 한 번 더 수행되고, source detail은 집계 대신 row 변환만 반복함을 확인했다.
4차 totalRowsLoader 개선 방향 구체화
- 무엇을:
buildSettlementByCreatorResponse()의totalRowsLoader경로만 따로 떼어 메모리/성능 병목과 개선 우선순위를 구체화했다.
- 왜:
- 기존 성능 메모는 “live 계산 경로 전반을 DB 쿼리로 옮기자” 수준이라 범위가 넓었고, 실제로 어떤 부분을 먼저 고쳐야 효과가 큰지 드러나지 않았기 때문이다.
- 어떻게:
- 명령 실행 없음: 이번 단계도 읽기 전용 코드/문서 검토만 수행했다.
src/main/kotlin/kr/co/vividnext/sodalive/partner/agent/calculate/AgentCalculateService.kt:200-203확인 → total이totalRowsLoader(...).toMergedResponseItems().toResponseTotal()로 계산됨을 다시 확인했다.src/main/kotlin/kr/co/vividnext/sodalive/partner/agent/calculate/GetAgentCreatorSettlementSummaryQueryData.kt:17-40,60-77및src/main/kotlin/kr/co/vividnext/sodalive/partner/agent/calculate/GetAgentSettlementByCreatorResponse.kt:33-43확인 → row별 금액 계산, creator별 groupBy 병합, grand total 재합산이 모두 애플리케이션 메모리에서 수행됨을 확인했다.src/main/kotlin/kr/co/vividnext/sodalive/partner/agent/calculate/AgentCalculateQueryRepository.kt:392-596확인 → generic 4종 쿼리가 assignment/agent ratio/settlement ratio 기준의 grouped row를 반환함을 확인했다.src/test/kotlin/kr/co/vividnext/sodalive/partner/agent/calculate/AgentCalculateQueryRepositoryTest.kt:145-176,328-381,421-470확인 → 같은 creator도 settlement ratio/assignment/agent ratio 이력 때문에 여러 row로 분할될 수 있어 total 계산이 단순sum(totalCan)으로 대체되면 안 됨을 확인했다.src/main/kotlin/kr/co/vividnext/sodalive/admin/calculate/channelDonation/AdminChannelDonationCalculateQueryRepository.kt:33-54및src/main/kotlin/kr/co/vividnext/sodalive/creator/admin/calculate/channelDonation/CreatorAdminChannelDonationCalculateQueryRepository.kt:18-38확인 → 이 저장소 안에 total 전용fetchOne()aggregate query 선례가 이미 있음을 확인했다.
5차 미체크 항목 구현 및 성능 완화
- 무엇을:
- assignment/finalize 가드, calculate empty-result, snapshot pagination, finalized immutability 회귀 테스트를 추가했다.
- ratio 목록 응답을 member 단위
current/history구조로 확장하고, generic total/finalize 내부 계산 경로를 가볍게 정리했다.
- 왜:
- 문서에 남아 있던 미체크 항목을 실제 테스트와 응답 계약으로 고정해야 후속 회귀를 막을 수 있고, total/finalize 경로의 불필요한 groupBy/중간 객체 생성을 줄여야 현재 범위 안에서 안전하게 성능을 완화할 수 있기 때문이다.
- 어떻게:
- 성공:
./gradlew test --tests kr.co.vividnext.sodalive.admin.partner.agent.assignment.AdminAgentCreatorServiceTest --tests kr.co.vividnext.sodalive.admin.partner.agent.settlement.AdminAgentSettlementSnapshotServiceTest --tests kr.co.vividnext.sodalive.partner.agent.calculate.AgentCalculateServiceTest→ BUILD SUCCESSFUL - 성공:
./gradlew test --tests kr.co.vividnext.sodalive.admin.partner.agent.ratio.AgentSettlementRatioServiceTest --tests kr.co.vividnext.sodalive.admin.partner.agent.ratio.AdminAgentSettlementRatioControllerTest→ BUILD SUCCESSFUL - 성공:
./gradlew test --tests kr.co.vividnext.sodalive.admin.partner.agent.assignment.AdminAgentCreatorServiceTest --tests kr.co.vividnext.sodalive.admin.partner.agent.settlement.AdminAgentSettlementSnapshotServiceTest --tests kr.co.vividnext.sodalive.partner.agent.calculate.AgentCalculateServiceTest --tests kr.co.vividnext.sodalive.partner.agent.calculate.AgentCalculateQueryRepositoryTest --tests kr.co.vividnext.sodalive.admin.partner.agent.ratio.AgentSettlementRatioServiceTest --tests kr.co.vividnext.sodalive.admin.partner.agent.ratio.AdminAgentSettlementRatioControllerTest→ BUILD SUCCESSFUL - 참고:
lsp_diagnostics는 현재 환경에 Kotlin LSP가 없어 사용할 수 없었고, 대신 위 Gradle 실행에서compileKotlin/compileTestKotlin까지 함께 통과한 것으로 컴파일 진단을 대체했다.
- 성공: