# P8 — incar 갭 반영: 운영/정산 프로세스 7개 도메인 (🅱)

작성: PL (자율 모드), 2026-05-31. 사용자 지시 "다 적용". P7(🅰 수수료계산 7)에 이어 🅱 운영 7개로 incar 갭 14개 완성.
범위: 풀스택(DB→Core→API→Frontend→Infra). 패턴 100% 준수(template = 수금수수료 V41 / CollectionCommission*, P7과 동일).
Flyway: **V96이 최신 → V97부터.** 메뉴는 적절한 상위그룹 하위. 금액 NUMERIC(15,2), 율 NUMERIC(7,4), HALF_UP.

**확정 FK**: agent(agent_id), contract(contract_id), organization(org_id), insurance_company(company_id), grade(grade_id), settle_master.

---

## 도메인별 설계

### D8. 단계마감 (STEP_CLOSE) — V97
월 정산을 단계별로 마감(수신→계산→검증→지급). 기존 PERIOD_CLOSE(단일 잠금) 보강.

**settlement_step_close**
| 컬럼 | 타입 | 설명 |
|---|---|---|
| step_close_id | BIGSERIAL PK | |
| settle_month | CHAR(6) NN | |
| step_code | VARCHAR(20) NN | RECEIVE/CALC/VERIFY/PAY |
| step_seq | INT NN | 단계 순서 1~4 |
| status | VARCHAR(20) NN DEFAULT 'OPEN' | OPEN/CLOSED |
| closed_at TIMESTAMP / closed_by BIGINT / created_at | | |
UNIQUE(settle_month, step_code); CHECK step_code IN(...); CHECK status IN('OPEN','CLOSED')
공식 없음(워크플로우). 액션: close(단계마감), reopen.

### D9. 본사정산 (HQ_SETTLE) — V98
GA 본사 자체의 수입/비용 정산 항목(설계사 지급과 별개의 GA 손익).

**hq_settle_item**
| 컬럼 | 타입 | 설명 |
|---|---|---|
| item_id | BIGSERIAL PK | |
| settle_month | CHAR(6) NN | |
| item_type | VARCHAR(20) NN | INCOME(수입)/EXPENSE(비용) |
| item_name | VARCHAR(100) NN | 항목명 |
| amount | NUMERIC(15,2) NN | 금액 |
| memo | VARCHAR(300) | |
| status | VARCHAR(20) NN DEFAULT 'REGISTERED' | REGISTERED/CONFIRMED |
| created_at/created_by/updated_at | | |
idx: (settle_month, item_type). CHECK item_type IN('INCOME','EXPENSE')
공식: 본사손익 = Σ(INCOME amount) − Σ(EXPENSE amount). 조회 집계 엔드포인트 제공.

### D10. 등급평가 (GRADE_EVAL) — V99
설계사 실적 점수로 등급 산정. rule(점수구간→등급) + 평가원장.

**grade_eval_rule**
| 컬럼 | 타입 | 설명 |
|---|---|---|
| rule_id BIGSERIAL PK | | |
| grade_id | BIGINT NN FK grade | 부여 등급 |
| min_score | NUMERIC(7,2) NN | 이 점수 이상이면 해당 등급 |
| effective_from DATE NN / effective_to DATE | | |

**agent_grade_evaluation**
| 컬럼 | 타입 | 설명 |
|---|---|---|
| eval_id BIGSERIAL PK | | |
| agent_id BIGINT NN FK agent | | |
| eval_period CHAR(6) NN | 평가기준월 | |
| performance_score NUMERIC(7,2) NN | 실적점수 | |
| prev_grade_id BIGINT FK grade | 기존 등급 | |
| evaluated_grade_id BIGINT FK grade | 산정 등급 | |
| status VARCHAR(20) NN DEFAULT 'EVALUATED' | EVALUATED/APPLIED | |
idx: (agent_id, eval_period). UNIQUE(agent_id, eval_period)
공식: evaluated_grade = score 이상인 최대 min_score 룰의 grade. Service가 grade_eval_rule 조회해 결정.

### D11. 공동계약 (JOINT_CONTRACT) — V100
한 계약을 여러 설계사가 공동 모집 → 지분율(share_rate)로 수수료 배분.

**joint_contract**
| 컬럼 | 타입 | 설명 |
|---|---|---|
| joint_id BIGSERIAL PK | | |
| contract_id BIGINT NN FK contract | | |
| agent_id BIGINT NN FK agent | | |
| role VARCHAR(10) NN | LEAD/SUB | |
| share_rate NUMERIC(7,4) NN | 지분율(합=1) | |
| created_at/created_by | | |
UNIQUE(contract_id, agent_id); CHECK role IN('LEAD','SUB'); CHECK share_rate>=0 AND share_rate<=1
공식: 설계사몫 = 계약수수료 × share_rate. (검증: 계약별 share_rate 합=1 — Service 가드)

### D12. 보증보험 (GUARANTEE_INS) — V101
설계사가 가입하는 신원보증보험 가입현황 추적(공식 없음, 관리).

**agent_guarantee_insurance**
| 컬럼 | 타입 | 설명 |
|---|---|---|
| guarantee_id BIGSERIAL PK | | |
| agent_id BIGINT NN FK agent | | |
| policy_no VARCHAR(50) NN | 증권번호 | |
| carrier_id BIGINT FK insurance_company(company_id) | 보증보험사 | |
| guarantee_amount NUMERIC(15,2) NN | 보증금액 | |
| start_date DATE NN / end_date DATE NN | 보증기간 | |
| status VARCHAR(20) NN DEFAULT 'ACTIVE' | ACTIVE/EXPIRED/CANCELLED | |
idx: (agent_id, status),(end_date)

### D13. 적립금 (RESERVE_FUND) — V102
환수 대비 수수료 일부 적립 + 잔액 관리.

**agent_reserve_fund**
| 컬럼 | 타입 | 설명 |
|---|---|---|
| reserve_id BIGSERIAL PK | | |
| agent_id BIGINT NN FK agent | | |
| settle_month CHAR(6) NN | | |
| reserve_in NUMERIC(15,2) NN DEFAULT 0 | 적립액 | |
| reserve_out NUMERIC(15,2) NN DEFAULT 0 | 인출/사용액 | |
| balance NUMERIC(15,2) NN | **= 전월잔액 + reserve_in − reserve_out** | |
| created_at | | |
UNIQUE(agent_id, settle_month). idx (agent_id, settle_month)
공식: balance = (직전월 balance) + reserve_in − reserve_out. Service가 직전월 조회해 누적.

### D14. 수수료 시뮬레이터 (COMM_SIMULATOR) — V103
보험료/요율/지급률 입력 → 수수료·세금·실지급·분급·환수예상 산출. 시나리오 저장.

**commission_simulation**
| 컬럼 | 타입 | 설명 |
|---|---|---|
| sim_id BIGSERIAL PK | | |
| sim_name VARCHAR(100) NN | 시나리오명 | |
| premium_amount NUMERIC(15,2) NN | 입력 보험료 | |
| company_rate NUMERIC(7,4) NN | 보험사요율 | |
| payout_rate NUMERIC(7,4) NN | 지급률 | |
| commission_year INT NN | 회차 | |
| company_payment NUMERIC(15,2) NN | = 보험료×요율 | |
| agent_commission NUMERIC(15,2) NN | = 보험사지급액×지급률 | |
| withholding_tax NUMERIC(15,2) NN | = 설계사수수료×3.3% | |
| net_amount NUMERIC(15,2) NN | = 수수료−원천세 | |
| expected_chargeback NUMERIC(15,2) | 예상 환수(13개월 가정 50% 등) | |
| created_at/created_by | | |
공식(DOMAIN_KNOWLEDGE 7장과 동일): company_payment=premium×company_rate, agent_commission=company_payment×payout_rate, withholding_tax=agent_commission×0.033, net=agent_commission−withholding_tax. Service의 simulate 액션이 입력만 받아 계산 후 저장/반환.

---

## 메뉴 (V104)
| menu_code | menu_name | 상위그룹 | menu_path | component_path |
|---|---|---|---|---|
| STEP_CLOSE | 단계마감 | GRP_SETTLE | /settle/step-close | settle/StepClose |
| HQ_SETTLE | 본사정산 | GRP_SETTLE | /settle/hq-settle | settle/HqSettle |
| GRADE_EVAL | 등급평가 | GRP_ORG | /org/grade-eval | org/GradeEvaluation |
| JOINT_CONTRACT | 공동계약 | GRP_PRD | /contracts/joint | contracts/JointContract |
| GUARANTEE_INS | 보증보험 | GRP_ORG | /org/guarantee | org/GuaranteeInsurance |
| RESERVE_FUND | 적립금 | GRP_COMMISSION | /commission/reserve | commission/ReserveFund |
| COMM_SIMULATOR | 수수료 시뮬레이터 | GRP_COMMISSION | /commission/simulator | commission/CommissionSimulator |

권한 READ/CREATE/UPDATE/DELETE/EXPORT(STEP_CLOSE는 READ/UPDATE/APPROVE). 역할부여 V54/V95 패턴.

## 공통코드 (V105)
| group_code | 코드 |
|---|---|
| STEP_CODE | RECEIVE=수신마감/CALC=계산마감/VERIFY=검증마감/PAY=지급마감 |
| STEP_STATUS | OPEN=열림/CLOSED=마감 |
| HQ_ITEM_TYPE | INCOME=수입/EXPENSE=비용 |
| JOINT_ROLE | LEAD=주설계사/SUB=공동설계사 |
| GUARANTEE_STATUS | ACTIVE=유효/EXPIRED=만료/CANCELLED=해지 |
| GRADE_EVAL_STATUS | EVALUATED=평가완료/APPLIED=반영완료 |

---

## Wave 실행 (P7과 동일 팀/패턴)
1 dba: V97~V105  ·  2 core: VO/Mapper/Enum  ·  3 api: Service/Controller(공식·집계 내장)  ·  4 front: 7페이지+commission/settle/org api+App.tsx  ·  5 infra: build+smoke
**PL 검증**: GET뿐 아니라 액션 POST(close/reopen/simulate/recalc balance/등급산정)까지 실호출로 5xx 0 확인 — P7에서 GET-only smoke가 버그를 놓친 교훈 반영.

---

## 완료 상태 (2026-05-31)
schema **v105** 적용(Flyway V97~V105 success), 전체 `./gradlew build` SUCCESSFUL, 프론트 빌드 OK, ga-api 8082 라이브. 8테이블·7메뉴 등록. GET 9 + 액션 POST 5(simulate/hq-settles/step-closes/close/reserve upsert) **전부 200, 5xx 0건**. 시뮬레이터 공식 실측: 보험료 1,000,000×0.6=600,000 → ×0.75=450,000 → 원천세 14,850 → net 435,150 → 예상환수 225,000 ✓. 테스트데이터 정리 완료. (P8은 P7과 달리 액션까지 PL이 직접 호출 검증 → 숨은 버그 0.)
