Files
GA Pro bfc724669b feat: incar 갭 반영 수수료/운영 14개 도메인 풀스택 + 배치통합 + 신입교육자료
incar CMS(116메뉴) 벤치마킹 갭분석으로 ga-pro에 없던 14개 도메인을 풀스택 추가.

P7 수수료 계산 7종 (V88~V96):
- 수입수수료+수지차, 소개·이관수수료, 정착지원금, 인정실적+환산율,
  시상, 생보운영지원수수료, 지점장수당
- 각 rule/ledger + 공식(보험료×요율, 수입−지급 등) Service 내장

P8 운영/정산 7종 (V97~V105):
- 단계마감, 본사정산, 등급평가, 공동계약, 보증보험, 적립금, 수수료시뮬레이터
- close/reopen/apply/simulate/upsert 등 액션 + 손익·잔액·등급 산정 로직

배치 통합 (V106):
- settle_master.other_commission_total 컬럼 추가(DEFAULT 0, 백필)
- 설계사 지급성 9종 원장 aggregateByAgent → AggregateStep gross 합산
- 빈 원장 0 → 기존 정산결과·무결성 불변(비파괴적)

테스트: P7/P8 Service 공식 단위테스트 21건(ga-api:test 57건 전체 통과)
프론트: 화면 14개 + React.lazy 코드 스플리팅(단일 4MB → 130+ 청크)
문서: DOMAIN_GAP_P7/P8.md, 신입교육_보험과수수료_완전기초.md, DOMAIN_KNOWLEDGE/HANDOFF 갱신

검증: 전체 ./gradlew build(test 포함) SUCCESSFUL, Flyway V88~V106 success,
GET+액션POST smoke 5xx 0건, 9개 집계쿼리 SQL 유효성 확인, 공식 런타임 실측.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 15:45:10 +09:00

12 KiB
Raw Permalink Blame History

P7 — incar 갭 반영: 수수료 계산 7개 도메인

작성: PL (자율 모드), 2026-05-31 근거: incar CMS 116메뉴 vs ga-pro 96메뉴 갭 분석. 사용자 지시 "필요한 메뉴 적용 + 수수료 공식 다 적용". 범위: 🅰 수수료 계산 7개 도메인 풀스택 (DB→Core→API→Frontend→Infra).

기존 패턴 100% 준수 (template = 수금수수료 V41 / CollectionCommission*). 모든 금액 NUMERIC(15,2), 율 NUMERIC(7,4)(소수, 0~1), 반올림 HALF_UP.

Flyway: V87이 최신 → V88부터. 각 도메인은 rule(+) ledger 2테이블 패턴. 메뉴는 GRP_COMMISSION 하위.


도메인별 설계

D1. 수입수수료 + 수지차 (INCOME_COMM) — V88

보험사가 GA에 지급한 수입 측. 기존 원장(LEDGER_*)은 설계사 지급 측. 수지차 = 수입 지급.

income_commission_ledger (수입수수료 원장)

컬럼 타입 설명
income_id BIGSERIAL PK
contract_id BIGINT NN FK contract
carrier_id BIGINT NN FK insurance_company 보험사
settle_month CHAR(6) NN
premium_amount NUMERIC(15,2) NN 보험료
company_rate NUMERIC(7,4) NN 보험사요율
income_amount NUMERIC(15,2) NN = premium_amount × company_rate
commission_type VARCHAR(20) NN RECRUIT/MAINTAIN 등
status VARCHAR(20) NN DEFAULT 'CALCULATED' CALCULATED/CONFIRMED/CANCELLED
created_at/updated_at
idx: (carrier_id, settle_month), (contract_id), (status, settle_month)

margin_summary (수지차 집계 — recalc 액션으로 채움)

컬럼 타입 설명
margin_id BIGSERIAL PK
settle_month CHAR(6) NN
agent_id BIGINT FK agent (NULL이면 전체)
income_total NUMERIC(15,2) NN DEFAULT 0 수입 합
payout_total NUMERIC(15,2) NN DEFAULT 0 지급 합(settle_master 기준)
margin_amount NUMERIC(15,2) NN DEFAULT 0 = income_total payout_total
margin_rate NUMERIC(7,4) = margin/income (income>0)
created_at
UNIQUE(settle_month, agent_id)

공식: income_amount = premium × company_rate. margin = Σincome Σpayout.

D2. 소개·이관수수료 (REFERRAL_COMM) — V89

계약을 소개(REFERRAL)하거나 이관(TRANSFER)한 설계사에게 주는 수수료.

referral_commission_rule

컬럼 타입 설명
rule_id BIGSERIAL PK
referral_type VARCHAR(20) NN REFERRAL/TRANSFER
calc_type VARCHAR(10) NN RATE/FIXED
commission_rate NUMERIC(7,4) calc_type=RATE 일 때
fixed_amount NUMERIC(15,2) calc_type=FIXED 일 때
effective_from DATE NN / effective_to DATE
CHECK referral_type IN ('REFERRAL','TRANSFER'); CHECK calc_type IN ('RATE','FIXED')

referral_commission_ledger

컬럼 타입 설명
ledger_id BIGSERIAL PK
contract_id BIGINT NN FK
referrer_agent_id BIGINT NN FK agent 소개/이관한 설계사
settle_month CHAR(6) NN
referral_type VARCHAR(20) NN
base_amount NUMERIC(15,2) NN 기준금액(수수료/보험료)
commission_rate NUMERIC(7,4)
commission_amount NUMERIC(15,2) NN = base×rate (RATE) 또는 fixed_amount (FIXED)
status VARCHAR(20) NN DEFAULT 'CALCULATED'
idx: (referrer_agent_id, settle_month),(contract_id)

D3. 정착지원금 (SETTLING_SUPPORT) — V90

신입/경력 설계사 정착 지원금. 등급별 정액 지급 + 조기 해촉 시 환수.

settling_support_rule

컬럼 타입 설명
rule_id BIGSERIAL PK
agent_grade VARCHAR(20) NN 설계사 등급
support_amount NUMERIC(15,2) NN 월 정액 지원금
duration_months INT NN 약정 지원 개월수
clawback_months INT NN 이 개월 내 해촉 시 환수 대상
effective_from DATE NN / effective_to DATE

settling_support_ledger

컬럼 타입 설명
ledger_id BIGSERIAL PK
agent_id BIGINT NN FK agent
settle_month CHAR(6) NN
support_amount NUMERIC(15,2) NN 지급액
clawback_amount NUMERIC(15,2) NN DEFAULT 0 환수액
net_amount NUMERIC(15,2) NN = support_amount clawback_amount
status VARCHAR(20) NN DEFAULT 'CALCULATED' PAID/CLAWED_BACK 포함
idx: (agent_id, settle_month)

공식: 지급 = 등급별 support_amount. 환수 = 조기해촉시 support_amount × (잔여약정개월/약정개월) (clawback service 계산).

D4. 인정실적 + 환산보험료 (RECOGNIZED_PERF) — V91

환산보험료 = 보험료 × 상품별환산율. 인정실적 = 환산보험료 × 인정율. 시상/등급의 기초.

product_conversion_rate (상품별 환산율)

컬럼 타입 설명
rate_id BIGSERIAL PK
product_id BIGINT NN FK product
conversion_rate NUMERIC(7,4) NN 환산율 (예: 0.5=50%)
effective_from DATE NN / effective_to DATE
UNIQUE(product_id, effective_from)

recognized_performance_ledger

컬럼 타입 설명
ledger_id BIGSERIAL PK
agent_id BIGINT NN FK agent
contract_id BIGINT NN FK contract
settle_month CHAR(6) NN
premium_amount NUMERIC(15,2) NN 보험료
conversion_rate NUMERIC(7,4) NN 적용 환산율
converted_premium NUMERIC(15,2) NN = premium × conversion_rate
recognition_rate NUMERIC(7,4) NN 인정율
recognized_amount NUMERIC(15,2) NN = converted_premium × recognition_rate
status VARCHAR(20) NN DEFAULT 'CALCULATED'
idx: (agent_id, settle_month),(contract_id)

D5. 시상 (AWARD) — V92

신인도입/법인/유지율 등 시상. 조건 충족 시 정액 또는 정률.

award_rule

컬럼 타입 설명
rule_id BIGSERIAL PK
award_type VARCHAR(20) NN NEW_RECRUIT/CORPORATE/RETENTION/PERFORMANCE
calc_type VARCHAR(10) NN RATE/FIXED
threshold_amount NUMERIC(15,2) 충족 기준 실적(이상)
award_rate NUMERIC(7,4) RATE
award_fixed NUMERIC(15,2) FIXED
effective_from DATE NN / effective_to DATE
CHECK award_type IN (...); CHECK calc_type IN ('RATE','FIXED')

award_ledger

컬럼 타입 설명
ledger_id BIGSERIAL PK
agent_id BIGINT NN FK agent
settle_month CHAR(6) NN
award_type VARCHAR(20) NN
base_amount NUMERIC(15,2) NN 기준 실적
award_amount NUMERIC(15,2) NN = base×award_rate (RATE) 또는 award_fixed (FIXED)
status VARCHAR(20) NN DEFAULT 'CALCULATED'
idx: (agent_id, settle_month),(award_type, settle_month)

D6. 생보운영지원수수료 (LIFE_OP_SUPPORT) — V93

생보 계약 운영지원 수수료. 실적 기준 지급률 + 환수.

life_support_rule

컬럼 타입 설명
rule_id BIGSERIAL PK
agent_grade VARCHAR(20) NN
support_rate NUMERIC(7,4) NN 지급률
effective_from DATE NN / effective_to DATE

life_support_ledger

컬럼 타입 설명
ledger_id BIGSERIAL PK
agent_id BIGINT NN FK agent
settle_month CHAR(6) NN
base_amount NUMERIC(15,2) NN 생보 실적
support_rate NUMERIC(7,4) NN
support_amount NUMERIC(15,2) NN = base × support_rate
clawback_amount NUMERIC(15,2) NN DEFAULT 0 환수
net_amount NUMERIC(15,2) NN = support clawback
status VARCHAR(20) NN DEFAULT 'CALCULATED'
idx: (agent_id, settle_month)

D7. 지점장수당 (BRANCH_MGR_ALLOWANCE) — V94

지점장이 소속 조직 실적에 대해 받는 수당. cap 제한 + 환수.

branch_mgr_allowance_rule

컬럼 타입 설명
rule_id BIGSERIAL PK
position_code VARCHAR(20) NN 직책(지점장 등)
allowance_rate NUMERIC(7,4) NN 수당율
cap_amount NUMERIC(15,2) 상한(NULL=무제한)
effective_from DATE NN / effective_to DATE

branch_mgr_allowance_ledger

컬럼 타입 설명
ledger_id BIGSERIAL PK
manager_agent_id BIGINT NN FK agent 지점장
org_id BIGINT NN FK organization 대상 조직
settle_month CHAR(6) NN
base_amount NUMERIC(15,2) NN 조직 실적
allowance_rate NUMERIC(7,4) NN
allowance_amount NUMERIC(15,2) NN = LEAST(base×rate, cap)
clawback_amount NUMERIC(15,2) NN DEFAULT 0
status VARCHAR(20) NN DEFAULT 'CALCULATED'
idx: (manager_agent_id, settle_month),(org_id, settle_month)

확정 FK (DB 실검증): contract(contract_id) · agent(agent_id) · product(product_id) · organization(org_id) · insurance_company(company_id) · settle_master. 보험사 FK는 carrier_id BIGINT REFERENCES insurance_company(company_id). 수지차 payout은 settle_master 집계로 산출(dba가 컬럼 확인).


메뉴 (V95) — GRP_COMMISSION 하위 7개 PAGE

menu_code menu_name menu_path component_path sort
INCOME_COMM 수입수수료/수지차 /commission/income commission/IncomeCommission 80
REFERRAL_COMM 소개·이관수수료 /commission/referral commission/ReferralCommission 90
SETTLING_SUPPORT 정착지원금 /commission/settling-support commission/SettlingSupport 100
RECOGNIZED_PERF 인정실적 /commission/recognized commission/RecognizedPerformance 110
AWARD 시상 /commission/award commission/Award 120
LIFE_OP_SUPPORT 생보운영지원수수료 /commission/life-support commission/LifeSupport 130
BRANCH_MGR_ALLOWANCE 지점장수당 /commission/branch-allowance commission/BranchAllowance 140

권한: READ/CREATE/UPDATE/DELETE/EXPORT. 역할부여: SUPER_ADMIN/ADMIN 전체, MANAGER READ/CREATE/UPDATE/EXPORT, AGENT READ(INCOME_COMM 제외 — 본인 관련만). V54 패턴 그대로.

공통코드 (V96)

group_code 코드
INCOME_STATUS CALCULATED/CONFIRMED/CANCELLED
REFERRAL_TYPE REFERRAL=소개/TRANSFER=이관
CALC_TYPE RATE=정률/FIXED=정액
SUPPORT_STATUS CALCULATED/PAID/CLAWED_BACK
AWARD_TYPE NEW_RECRUIT=신인도입/CORPORATE=법인/RETENTION=유지율/PERFORMANCE=실적

CommissionType enum 확장: INCOME/REFERRAL/TRANSFER/SETTLING/RECOGNIZED/AWARD/LIFE_SUPPORT/BRANCH_ALLOWANCE 추가 + V40 COMMISSION_TYPE 공통코드 동기화.


Wave 실행

Wave 담당 산출물
1 dba-architect V88~V96 (도메인 7 + 메뉴 + 공통코드). FK 테이블명 실검증.
2 core-architect 14테이블 VO/Resp/SaveReq/SearchParam + Mapper IF+XML + CommissionType enum 확장
3 api-developer 7 Service + 7 Controller (@RequirePermission/@DataChangeLog, 공식 계산 Service 내장)
4 frontend-developer 7 페이지 + api/commission.ts 확장 + App.tsx 라우트
5 infra-reviewer ./gradlew build + 프론트 빌드 + smoke. README/HANDOFF/DOMAIN_KNOWLEDGE 갱신

완료 상태 (2026-05-31)

schema v96 적용(Flyway V88~V96 success), 전체 ./gradlew build SUCCESSFUL, 프론트 빌드 OK, ga-api 8082 라이브. P7 14개 GET + 수지차 recalc POST 전수 호출 5xx 0건. 수입수수료(보험료×요율=6,000,000)·수지차(수입−지급) 공식 런타임 실측 검증 후 테스트데이터 정리.

PL 통합검증에서 잡은 버그 3건(팀원 GET-only smoke가 놓침) — 수정 완료:

  1. 프론트 인정실적 경로 /rules → 백엔드 /rates 불일치 → api/commission.ts 수정.
  2. 프론트 수지차 경로 /margin → 백엔드 /margins 불일치 → 수정.
  3. 수지차 recalc 3중 결함: 컨트롤러 @RequestBody(프론트는 쿼리파라미터)→@RequestParam, 서비스 payoutTotal=0 하드코딩 → settle_master.net_amount 실집계(sumPayoutByMonth)+sumIncomeByMonth 신규, selectByMonthAndAgent#{agentId} IS NULL Postgres typed-null 오류 → <choose>로 교체.