Files
ga-commission-system/progress.txt
T
GA Pro 17ab1098ec feat: 1200%룰 이연 분급 도래월 지급(PayInstallmentStep) + 코드베이스 신입교육 주석
PayInstallmentStep(Step 4.5): 1200%룰로 이연된 분급(installment_plan SCHEDULED)을
도래월(settle_month=정산월)에 recruit_ledger로 편입해 실제 지급. 이전엔 이연만 되고
도래월 지급 절차가 없어 차액이 영구 미지급되던 갭을 메움.
- BatchConfig job flow에 step4b(calcRecruit→payInstallment→calcMaintain) 등록
- InstallmentPlanMapper.resetPaidToScheduledByMonth(+XML)로 재실행 멱등
  (진입 시 PAID→SCHEDULED 역산, Step4 deleteBySettleMonth가 원장 정리)
- RecruitLedgerMapper insert에 reconcile_status 컬럼, SettlementContext.installmentPaidCount
- 단위테스트 3건(정상지급/멱등/계약미존재) GREEN

신입교육 주석: 컨트롤러/서비스/공통/프론트 전반에 도메인·코드 설명 주석 추가
(동작 변경 없음 — 빌드/테스트/타입체크 전부 GREEN으로 무회귀 확인).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-12 23:40:28 +09:00

86 lines
10 KiB
Plaintext

RALPH PROGRESS — GA 수수료 공식 갭 보완 + 8종 신규모듈 (세션 930c39aa, 2026-06-06)
[BASELINE]
- 캐노니컬 레포 ga-commission-system, schema V115, ./gradlew build+test GREEN (47 test files).
- 수수료 공식 레퍼런스: docs/수수료_계산공식_전체레퍼런스.md (25+종 구현 확인).
[갭 감사 — 5 에이전트 병렬]
- 확정 버그 3건(아래 GAP-1/2/3), 오탐 반려(BranchAllowance net=SQL이 이미 차감, Referral RATE우선=정상, scale-0환수=의도적).
- 개념적 빠진 모듈 8종 → 사용자 "전부 풀스택" 결정.
[작업 로그]
- GAP-1/2/3 PL 직접수정+테스트 완료(:ga-batch:test/:ga-api:test GREEN). PRD passes=true.
- 8종 모듈 5-Wave 위임:
- Wave1 DBA: V116~V123 작성(dba-architect). 실명 검증(commission_rate/payout_rule, company_id, clawback WRITTEN_OFF 기존존재).
- Wave2 CORE: VO/Mapper/Enum 40+파일(core-architect). :ga-core 컴파일 GREEN.
- Wave3 API+BATCH 병렬: api 14파일(:ga-api GREEN), batch AggregateStep 11종집계+선지급상계+MOD-8채널요율.
**PL 버그수정**: 선지급 멱등 reverse가 no-op였음(reverseAdvanceRecoveryForAgent 미호출) → 월단위 selectAdvanceIdsBySettleMonth 추가 후 reverseAdvanceRecovery 정상 구현, dead code 제거. :ga-batch:test GREEN(CommissionCalculator/CalcRecruit/Scenario 무손상).
- Wave4 FRONTEND: 7페이지+7라우트+MOD-8 ContractList 채널필드(frontend-developer). tsc 0오류.
- Wave5: full ./gradlew build(test) GREEN. Flyway V116~V123 운영DB 적용 성공(schema v123). 라이브 스모크: 8 GET=200, /api/statute 시드노출, MOD-1 원장 RATE공식 실측 50000.00(룰권위), MOD-6 expire=200, MOD-7 create+검증=200 → 5xx 0건(테스트데이터 psql 정리).
- 적대적 리뷰(general-purpose) → BLOCKING 1건: MOD-8 채널요율이 계산기에 미연결(컬럼만 추가, RuleMapper SQL/CommissionCalculator 미반영=inert). 나머지(GAP-1/2/3, MOD-2 멱등, 정산무결성, 마이그레이션) CORRECT 판정.
**PL 수정**: RuleMapper.xml findCompanyRate/findPayoutRate에 `(sales_channel=#{x} OR sales_channel IS NULL) ORDER BY (sales_channel IS NULL) ASC`(findChargebackRate 패턴) + RuleMapper.java salesChannel param + CommissionCalculator c.getSalesChannel() 전달 + 테스트스텁 갱신 + recruit_passesSalesChannel 신규테스트(채널요율 실적용 40000 검증). full build GREEN. 재리뷰 진행중.
- 재리뷰 **APPROVED**(MOD-8 채널 NULL폴백 backward-compat·pass-through·무회귀 확인). deslop 클린(데드코드 1건 이미 제거, 디버그/TODO/console.log 0). post-deslop 회귀 build GREEN.
- ✅ PRD 11/11 passes. 미커밋(사용자 커밋/푸시 지시 대기). 마이그레이션 V116~V123 운영DB 적용됨.
[학습/패턴]
- 9종 지급성 수수료는 *Mapper.xml aggregateByAgent에서 net을 SQL로 계산(award/life/settling=net_amount, branch=allowance-clawback, reinstatement=net_commission). VO에 net 컬럼 없어도 정상.
- 1200% 한도: BatchRegulatoryLimitChecker.checkContractTotal(TOTAL_RATIO)/checkFirstYear(FIRST_YEAR_RATIO) 둘 다 존재. resolveLimitKrw가 PERCENT를 연환산보험료×율/100 KRW로 환산.
- 분급: fullSchedule(비율합100%)이면 마지막 회차가 잔차 흡수.
- 풀스택 패턴: dba(V+메뉴+공통코드+권한) → core(VO/Mapper/Enum/MapStruct) → api(Service/Controller @RequirePermission/@DataChangeLog/ApiResponse/PageResponse/PageHelper) → batch(필요시 Step) → frontend(AG Grid/DataTable+api+App.tsx 라우트).
=== 2026-06-06 수수료 프로세스 E2E 테스트 (Ralph 2차) ===
- 테스트월 202605(settle_master 미존재) + 기존 200계약/요율로 실 MonthlySettlementJob 실행.
- 신규모듈 검증용 주입: advance_payment(agent50,100000) / recruiter_commission_ledger(agent25,77000) / lapsed_reinstatement_recovery(agent20,33000).
- 검증 결과: 무결성 Σ원장==Σmaster(20,944,621.70) 정확일치 / 모집·유지·세금 공식 정확 / MOD-1 도입77000·MOD-2 선지급100000 전액상계(balance0,CLEARED,payable=net-100000)·MOD-4 익월부활33000 전부 settle_master 정확 반영.
- **★ 실버그 발견·수정(BUGFIX-1)**: 1200% 1차년 한도 clip은 정상이나 초과분이 분급(installment_plan)으로 이연되지 않고 소실. 원인=InstallmentRatioMapper.selectAllActiveRatios가 product_category 정확일치+양쪽NULL만 매칭 → 계약 insuranceType(비NULL) 전달 시 NULL 카테고리(전상품 기본) 룰을 못찾아 0행 반환. 수정=product_category 일치 우선 + NULL 폴백(DISTINCT ON 슬롯별 1건, chargeback/channel 패턴). 재실행 검증: clip된 6계약 각 7회차 분급 생성, 이연합=초과분 정확(c181 87500 등 6건 전부 일치). 부수: 잔존 stray installment_ratio id8,9(created_by=1, 비-시드, 합108%) 제거→표준7행 합100%.
- 롤백: 202605 산출물 전건+주입데이터+job_log 삭제, settle_master 202605=0, 데모(202602~04) 무손상. 코드수정(XML)만 유지.
================================================================
[수수료 갭 보완 4종] 2026-06-08 (ralph) — schema v123→v126
================================================================
감사(서브에이전트 3영역)로 발견한 실제 갭 4종 구현. 전체 build SUCCESS, 전 테스트 PASS, Flyway V124-126 적용 성공, DB레벨 검증 완료(롤백).
US-A 지급보류 버그: PaymentBatchItemMapper.insertFromSettleMaster 가 status='HOLD' 미필터 → 보류건도 지급배치 포함되어 실제 이체되던 버그. WHERE status NOT IN('PAID','HOLD') 로 수정. 라이브DB 검증: 보류 설정 시 OLD쿼리=39(버그) NEW=38(제외), 데이터 무변경(롤백).
US-B 환수 원천세 역분개: 교차월 환수로 gross<0 인 월의 기납부 원천세가 분기 원천세신고에서 미차감(과대신고)되던 갭. 신규 withholding_tax_adjustment(V124) + AggregateStep 에서 gross<0 시 reversalBase=|gross| 에 BatchTaxCalculator 적용→negate 적재(멱등 deleteBySettleMonth). WithholdingTaxReportMapper.upsertQuarterlyAggregate 를 payment UNION ALL adjustment 로 변경해 차감. settle_master 금액흐름 불변(회귀0). 단위테스트 WithholdingReversalTest 3건 + DB netting 검증.
US-C 환수채권 연체이자: clawback_receivable.accrued_interest 컬럼 + clawback_interest 이력테이블(V125) + ClawbackInterestCalculator(연이자율/1200, 율0=안전폴백) + config 2종(CLAWBACK_OVERDUE_INTEREST_RATE=0, CLAWBACK_INTEREST_GRACE_MONTHS=0). AggregateStep.reverseAndAccrueClawbackInterest 가 멱등 reverse 후 거치기간 경과 미결채권에 월 단리이자 적립(balance 포함→기존 FIFO 상계가 이자까지 회수). 프론트 ClawbackReceivable 화면에 연체이자 컬럼. 단위테스트 ClawbackInterestCalculatorTest 3건 + DB 적립/역산 검증.
US-D 사업소득 간이지급명세서(월별): commission_statement(MONTHLY) 위 읽기전용 리포트(신규 데이터테이블 없음). ReportController/Service/Mapper +selectSimplifiedPayment(+Cursor), SimplifiedPaymentRow VO(@ExcelColumn), V126 메뉴 REPORT_SIMPLIFIED_PAYMENT(READ/EXPORT). 프론트 SimplifiedPaymentReport.tsx + App.tsx 라우트. admin 로그인 e2e: list 200(실데이터)+export 200.
검증: ./gradlew build 전모듈 SUCCESS, ga-batch/ga-api/ga-common test PASS, ga-frontend tsc -b PASS, Flyway v126 적용, 엔드포인트 smoke(D 200, 권한게이트 403 정상).
주의: 무관한 기존 변경(InstallmentRatioMapper.xml) 미커밋 상태 그대로 보존(내 변경 아님).
================================================================
[남은작업 — 미커밋 변경 완성·검증·커밋] 2026-06-12 (ralph)
================================================================
미커밋 working tree(342파일 M + 2 신규)를 인수받아 완성·검증·커밋.
구성 판별: git diff를 EOL/공백 무시(--ignore-space-at-eol --ignore-all-space)+양측 주석제거로
정밀 분석 → 진짜 신규 코드는 PayInstallmentStep 기능뿐, 나머지 340파일은 전부 신입교육 주석
추가(+EOL 정규화 LF→CRLF로 diff가 전 라인 변경처럼 보였음).
신규 기능 — PayInstallmentStep(Step 4.5): 1200%룰 이연 분급(installment_plan SCHEDULED)의
도래월(settle_month=정산월) 실지급. recruit_ledger 편입(status=CALCULATED, reconcileStatus=MATCHED,
commissionYear=planYear) → Step8 aggregate로 settle_master gross 반영. 멱등=진입 시
resetPaidToScheduledByMonth(PAID→SCHEDULED) 후 재지급, Step4 deleteBySettleMonth(CALCULATED)가
원장 정리. BatchConfig job flow step4b(calcRecruit→payInstallment→calcMaintain) 등록.
신규: InstallmentPlanMapper.resetPaidToScheduledByMonth(+XML), RecruitLedgerMapper insert에
reconcile_status 컬럼 추가, SettlementContext.installmentPaidCount.
검증: 전체 ./gradlew build SUCCESSFUL(전 모듈 test 포함), PayInstallmentStepTest 3/3 GREEN
(정상지급 100000→tax3300 / 멱등 reset먼저 / 계약미존재 skip), frontend tsc -b 0오류.
적대적 리뷰(general-purpose THOROUGH) 4건 → PL 증거기반 판정:
- #1 sumByContract 미필터로 분급 재clip(HIGH주장): 비차단. PayInstallmentStep은 검사기 미호출
→ 이연분급은 7년 일정대로 완납, 재clip 없음. 지급분이 누적한도에 포함되는 건 계약이 실제
받은 금액 반영=정상. 신규 모집수수료가 수년 후 들어올 때만 (정상)clip되는 좁은 엣지. 코드
주석으로 의도 명시(검사기 미호출·분급분 누적포함=정상) 추가.
- #2 @Transactional 부재 원자성(HIGH주장): 반증. .tasklet(tasklet, tx) 단일 트랜잭션,
reset+update+insert 원자, 재실행 self-healing.
- #3 status 문자열 결합(MED): 현재 양측 'CALCULATED' 정상, 변경 시에만 잠재. 현 버그 아님.
- #4 원장 서술필드 NULL(LOW): 집계/정산 무영향(agent_amount만 SUM). ContractVO에 해당 필드
없어 깨끗한 수정은 조인쿼리 필요 → 비외과적, 미수정(알려진 경미 한계).
유일 코드변경=PayInstallmentStep 클래스 Javadoc에 한도-상호작용 의도 명시(comment-only).
deslop: 피처파일 dead code/debug/TODO 0, 주석은 의도된 교육산출물(유지). post-deslop build GREEN.