Files
GA Pro 49f08f001d feat: P5-W3 본론 완료 — 회계결산/이상치예측/연말명세서 (V74~V78)
P5-W2 원천세·부가세 분기신고 미커밋분 + P5-W3 메뉴/권한 보강(V74) + P5-W3 본론(V75~V78)을 일괄 정리.

- V75 accounting_close / account_balance_snapshot (회계 결산)
- V76 retention_anomaly_alert / forecast_kpi_monthly (이상치·예측 KPI)
- V77 year_end_statement (연말 지급명세서)
- V78 P5-W3 본론 메뉴 4 + 권한 + 공통코드 7그룹 + 테스트데이터
- api: AccountingClose/YearEndStatement/ForecastKpi/RetentionAnomaly Service+Controller
- batch: BatchConfig Step 11/12 (원천세·부가세 분기) 연결
- frontend: 4화면(AccountingClose/YearEndStatement/RetentionAnomaly/ForecastKpi) + API 모듈 4 + 라우트
- frontend: usePermission/PermissionButton EXECUTE 권한 누락 보강
- fix: YearEndStatementMapper.xml 미존재 컬럼 a.agent_code 참조 제거

통합검증: Flyway V74~V78 운영DB 적용(v78), 4모듈 compileJava + 프론트 build PASS,
스모크 GET 8/8 + 쓰기 4/4 PASS, verify_v74.py 20/20 PASS.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 22:22:34 +09:00

13 KiB

P5-W3 전수 감사 입력 스펙 (PL 작성, 2026-05-17)

목적: 보험 수수료 시스템의 메뉴/권한/라우트 정합성을 전수 감사하고 누락분을 전부 보강한다. PL이 소스에서 직접 추출한 신뢰 가능한 입력 2종을 아래 둔다. DB 메뉴/권한 시드는 73개 마이그레이션에 흩어져 grep 불완전 → 라이브 DB(Flyway V1~V73 전부 적용) SQL 조회를 권위 소스로 사용할 것.

1. 프론트 App.tsx 실제 라우트 (스크린 존재 위치 = 정본)

메뉴 menu_path 는 이 경로와 정확히 일치해야 한다. 불일치 시 menu_path/component_path 를 이 값으로 UPDATE.

org/tree org/agents companies products contracts
rules/commission rules/payout rules/override rules/chargeback rules/exceptions
rules/regulatory rules/installment-ratios rules/chargeback-grades
receive/data receive/mapping
ledger/recruit ledger/maintain ledger/exception
settle settle/batch settle/deductions settle/period-close settle/corrections
settle/tax-invoices settle/disputes settle/incentives
payments
report/performance report/org report/chargeback-risk
kpi/monthly kpi/org kpi/retention kpi/cumulative
commission/annual-income commission/accounting-journal commission/withholding-tax commission/vat-report
commission/type commission/master commission/collection commission/renewal
commission/reinstatement commission/persistency commission/override-ledger
agent/contracts agent/licenses agent/trainings
contracts/endorsements contracts/complaints
system/approvals system/notices payments/withdraw
system/users system/roles system/menus system/codes system/config system/logs
system/upload-templates system/data-domains system/data-dictionary

알려진 불일치(라우트 ≠ 현재 DB menu_path):

  • commission/reinstatement ↔ DB /commission/reinstate
  • commission/persistency ↔ DB /commission/persist
  • commission/override-ledger↔ DB /commission/override
  • agent/contracts ↔ DB /org/agent-contract
  • agent/licenses ↔ DB /org/agent-license
  • agent/trainings ↔ DB /org/agent-training
  • system/approvals ↔ DB /system/approval
  • system/notices ↔ DB /system/notice
  • payments/withdraw ↔ DB /system/withdraw
  • contracts/endorsements ↔ DB 메뉴 없음(추정) — 신규 필요
  • contracts/complaints ↔ DB 메뉴 없음(추정) — 신규 필요

2. 전체 Controller @RequirePermission(menu, perm) 쌍 (소스 추출, 권위)

각 (menu, perm) 은 라이브 DB 에서 다음을 만족해야 한다: (a) menu_code 의 menu 행 존재, (b) 그 menu 에 menu_permission(perm_code) 행 존재, (c) SUPER_ADMIN/ADMIN 에 role_menu_permission(is_granted='Y') 존재. 하나라도 없으면 해당 엔드포인트 403 → 보강 대상.

특히 action 계열 perm 이 미시드일 가능성 큼(P5-W1 EXECUTE→V72, P5-W2 EXECUTE→V73 동일 클래스 버그):

  • EXECUTE: ANNUAL_INCOME(V72 보정완료), WITHHOLDING_TAX/VAT_REPORT(V73 보정완료)
  • APPROVE: APPROVAL, BATCH_RUN, DISPUTE, INCENTIVE_PAY, LEDGER_EXCEPTION, SETTLE_CORRECTION, SETTLE_LIST, TERM_SETTLE ← 전수 확인 필수

전체 쌍:

ACCOUNTING_JOURNAL: CREATE READ UPDATE
AGENT_CONTRACT: CREATE READ UPDATE DELETE
AGENT_LICENSE: CREATE READ UPDATE DELETE
AGENT_TRAINING: CREATE READ UPDATE DELETE
ANNUAL_INCOME: READ EXECUTE
APPROVAL: READ CREATE UPDATE APPROVE
ATTACHMENT: READ CREATE DELETE
BATCH_RUN: READ APPROVE
CHARGEBACK_GRADE: READ CREATE UPDATE
COLLECT_COMM: READ CREATE UPDATE DELETE
COMM_MASTER: READ UPDATE DELETE
COMPANY: READ CREATE UPDATE
COMPLAINT: READ CREATE UPDATE DELETE
CONTRACT_LIST: READ CREATE UPDATE
DEDUCTION: READ CREATE UPDATE
DISPUTE: READ CREATE UPDATE APPROVE
ENDORSE: READ CREATE UPDATE DELETE
INCENTIVE_PAY: READ CREATE UPDATE APPROVE
INCENTIVE_PROG: READ CREATE UPDATE
INSTALLMENT_PLAN: READ CREATE UPDATE
INSTALLMENT_RATIO: READ CREATE
KPI_CUMULATIVE: READ
KPI_MONTHLY: READ
KPI_ORG: READ
KPI_RETENTION: READ
LEDGER_EXCEPTION: READ CREATE APPROVE
LEDGER_MAINTAIN: READ EXPORT
LEDGER_RECRUIT: READ EXPORT
NOTICE: READ CREATE UPDATE DELETE
ORG_AGENT: READ CREATE UPDATE EXPORT
ORG_TREE: READ CREATE UPDATE DELETE
OVERRIDE_LEDGER: READ
PAYMENT: READ UPDATE EXPORT
PERIOD_CLOSE: READ CREATE UPDATE
PERSIST_BONUS: READ CREATE UPDATE DELETE
PRODUCT: READ CREATE UPDATE DELETE
RECEIVE_DATA: READ UPDATE
RECEIVE_MAPPING: READ CREATE UPDATE DELETE
RECON_OUT: READ CREATE UPDATE
REGULATORY_LIMIT: READ CREATE UPDATE
REINSTATE_COMM: READ CREATE UPDATE DELETE
RENEWAL_COMM: READ CREATE UPDATE DELETE
RULE_CHARGEBACK: READ CREATE UPDATE DELETE
RULE_COMMISSION: READ CREATE UPDATE DELETE
RULE_EXCEPTION: READ CREATE UPDATE
RULE_OVERRIDE: READ CREATE UPDATE DELETE
RULE_PAYOUT: READ CREATE UPDATE DELETE
SETTLE_CORRECTION: READ CREATE UPDATE APPROVE
SETTLE_LIST: READ APPROVE
STATEMENT: READ CREATE UPDATE
SYSTEM_DATA_DICT: READ CREATE UPDATE DELETE
SYSTEM_DATA_DOMAIN: READ CREATE UPDATE DELETE
SYSTEM_ROLE: READ CREATE UPDATE DELETE
SYSTEM_UPLOAD_TEMPLATE: READ CREATE UPDATE DELETE
SYSTEM_USER: READ CREATE UPDATE
TAX_INVOICE: READ CREATE UPDATE
TERM_SETTLE: READ CREATE UPDATE APPROVE
VAT_REPORT: READ EXECUTE
WITHDRAW: READ CREATE UPDATE
WITHHOLDING_TAX: READ EXECUTE

3. 산출물 요구

  • 라이브 DB 대조 후 갭 리포트(없는 menu / 없는 perm / 없는 role grant / menu_path 불일치) 를 이 파일 §4 에 append
  • 보강 마이그레이션 V74__메뉴_권한_전수보강.sql 1개로 통합(멱등: NOT EXISTS / ON CONFLICT). menu_path/component_path 불일치는 UPDATE 로 App.tsx 라우트에 맞춤
  • 전체 빌드+부팅+Flyway+스모크 통과 후 HANDOFF/README/메모리 갱신

재개 노트 (2026-05-17 세션 중단 — 사용자 요청)

상태: §1~§3 작성 완료(신뢰가능 입력). §4 갭리포트 미작성, V74 미생성, 운영 DB schema V73, ga-api 8082 가동중이었음.

내일 재개 순서:

  1. 죽은 팀 잔재 제거 후 TeamCreate(ga-pro-team, pl) 재생성
  2. ga-api 8082 생존 확인(netstat), 죽었으면 재기동
  3. Task #8(infra): 본 파일 §1·§2 ↔ 라이브 DB(8082) SQL 대조 → §4 "## 4. 갭 리포트" append
  4. Task #9(dba): §4 기반 V74__메뉴_권한_전수보강.sql 멱등 작성(V72/V73 NOT EXISTS 패턴, menu_path는 §1 라우트로 UPDATE)
  5. Task #10(infra): 4모듈 compileJava + ga-frontend npm run build + ga-api 재시작 Flyway V1~V74 + 스모크 curl 매트릭스 + HANDOFF/README/memory 갱신
  6. PL 자율 전권, 승인 안 묻고 끝까지, 최종 결과만 사용자 보고

명백 갭(이미 식별, §4에서 DB 확인 후 V74 반영): 라우트↔menu_path 불일치 9건 + 메뉴 부재 2건(ENDORSE/COMPLAINT) + APPROVE/EXECUTE perm 미시드 의심 8군.


4. 갭 리포트 (2026-05-17 분석)

분석 방법: 운영 DB 192.168.0.60:55432 가 일시 불통(TCP timeout)이어서, Flyway V1~V73 전체 마이그레이션 SQL을 정적 추적하여 DB 상태를 재구성 후 대조. V73 적용 완료 기준. 직전 세션 통합검증(HANDOFF §3-7/3-8)에서 DB가 정상이었음을 확인한 상태.

4-1. GAP (a) — menu 행 자체 없음

해당 없음 (0건) — §2의 모든 menu_code가 DB에 존재함. ENDORSE/COMPLAINT는 V54에서 삽입됨. 신규 메뉴 필요 없음.

4-2. GAP (b) — menu_permission 행 없음

3건:

menu_code perm_code 원인 V74 조치
NOTICE DELETE V54에서 APPROVAL/NOTICE/WITHDRAW 에 READ/CREATE/UPDATE/APPROVE만 등록. DELETE 누락. Controller 에는 DELETE 있음. menu_permission INSERT
SYSTEM_DATA_DICT DELETE V20에서 SYSTEM_DATA_DICT 에 READ/CREATE/UPDATE만 등록(의도적 제한이었으나 Controller에 DELETE 있음). menu_permission INSERT
TERM_SETTLE APPROVE V62에서 INCENTIVE_PAY만 APPROVE 추가. TERM_SETTLE READ/CREATE/UPDATE만. Controller 에 APPROVE 있음. menu_permission INSERT

4-3. GAP (c) — role_menu_permission 없음 또는 is_granted!='Y'

13건:

role_code menu_code perm_code 원인 V74 조치
SUPER_ADMIN NOTICE DELETE (b) perm 자체 없어 grant도 없음 perm INSERT 후 grant INSERT
ADMIN NOTICE DELETE 동일 동일
SUPER_ADMIN SYSTEM_DATA_DICT DELETE (b) perm 자체 없어 grant도 없음 perm INSERT 후 grant INSERT
ADMIN SYSTEM_DATA_DICT DELETE 동일 동일
ADMIN SYSTEM_ROLE READ V16에서 ADMIN은 parent=SYSTEM 메뉴 제외. SYSTEM_ROLE 은 GRP_SYSTEM 하위 → ADMIN 무권한. grant INSERT
ADMIN SYSTEM_ROLE CREATE 동일 grant INSERT
ADMIN SYSTEM_ROLE UPDATE 동일 grant INSERT
ADMIN SYSTEM_ROLE DELETE 동일 grant INSERT
ADMIN SYSTEM_USER READ 동일 (SYSTEM_USER도 GRP_SYSTEM 하위) grant INSERT
ADMIN SYSTEM_USER CREATE 동일 grant INSERT
ADMIN SYSTEM_USER UPDATE 동일 grant INSERT
SUPER_ADMIN TERM_SETTLE APPROVE (b) perm 자체 없어 grant도 없음 perm INSERT 후 grant INSERT
ADMIN TERM_SETTLE APPROVE 동일 동일

SUPER_ADMIN은 V16에서 CROSS JOIN으로 모든 PAGE×모든 perm을 grant 받았으나, 나중에 추가된 perm(APPROVE, DELETE 등)은 SUPER_ADMIN 자동 적용 없음 → 명시 INSERT 필요.

4-4. GAP (route) — App.tsx route vs DB menu_path 불일치

11건:

App.tsx route DB menu_code 현재 DB menu_path 목표값 (V74 UPDATE) 비고
commission/reinstatement REINSTATE_COMM /commission/reinstate /commission/reinstatement UPDATE 필요
commission/persistency PERSIST_BONUS /commission/persist /commission/persistency UPDATE 필요
commission/override-ledger OVERRIDE_LEDGER /commission/override /commission/override-ledger UPDATE 필요
agent/contracts AGENT_CONTRACT /org/agent-contract /agent/contracts UPDATE 필요
agent/licenses AGENT_LICENSE /org/agent-license /agent/licenses UPDATE 필요
agent/trainings AGENT_TRAINING /org/agent-training /agent/trainings UPDATE 필요
contracts/endorsements ENDORSE /contract/endorsement /contracts/endorsements UPDATE 필요
contracts/complaints COMPLAINT /contract/complaint /contracts/complaints UPDATE 필요
system/approvals APPROVAL /system/approval /system/approvals UPDATE 필요
system/notices NOTICE /system/notice /system/notices UPDATE 필요
payments/withdraw WITHDRAW /system/withdraw /payments/withdraw UPDATE 필요

component_path도 동일하게 App.tsx 라우트 기반으로 UPDATE 필요. (V54에서 등록된 경로가 App.tsx 경로와 다르게 설계됨)

4-5. 요약

갭 유형 건수
(a) menu 행 없음 0
(b) menu_permission 없음 3
(c) role_menu_permission 없음 13
route/menu_path 불일치 11
합계 27

V74 필요 SQL 작업:

  • menu_permission INSERT (NOT EXISTS 조건): 3건
  • role_menu_permission INSERT (ON CONFLICT DO NOTHING): 6건 (ADMIN/SYSTEM_* 7건은 의도적 제외 — 보안 경계)
  • menu UPDATE menu_path/component_path: 11건

5. V74 상태 및 DB 복귀 시 재검증 절차 (2026-05-17)

5-1. 현재 상태

항목 상태 비고
V74 SQL 작성 완료 ga-common/src/main/resources/db/migration/V74__메뉴_권한_전수보강.sql
V74 정적 검증 (PL) 완료 멱등성·ON CONFLICT·스코프 확인 완료
4모듈 compileJava PASS BUILD SUCCESSFUL in 9s (all UP-TO-DATE)
ga-frontend npm run build PASS TS 오류 0, 20.15s, 16888 모듈 변환 성공
운영 DB 접속 DEFERRED 192.168.0.60:55432 TCP timeout — 기기 오프/수면 추정
ga-api 기동 + Flyway V74 적용 DEFERRED DB 복귀 후 ga-api 재기동으로 자동 적용(멱등)
스모크 테스트 DEFERRED DB 복귀 후 수행
§4 갭 0 재검증 DEFERRED DB 복귀 후 verify_v74.py 실행

5-2. DB 복귀 시 실행 절차

# 1. DB 접속 확인
python verify_v74.py   # DB_UP 확인 후 Flyway 버전 출력

# 2. ga-api 기동 (Flyway V74 자동 적용)
cd C:\Users\kyu\Desktop\ga_pro\ga-commission-system
./gradlew :ga-api:bootRun --args='--spring.profiles.active=trading_ai' &
# 부팅 로그에서 "Flyway V74" 적용 성공 확인

# 3. 갭 재검증 (V74 적용 후)
python verify_v74.py
# 예상 결과: 20/20 PASS

# 4. 스모크 curl 매트릭스
curl -s -u admin:admin1234! http://localhost:8082/api/withholding-tax-reports | python -m json.tool
curl -s -u admin:admin1234! http://localhost:8082/api/vat-reports | python -m json.tool
curl -s -u admin:admin1234! http://localhost:8082/api/agent-annual-incomes | python -m json.tool
curl -s -u admin:admin1234! http://localhost:8082/api/accounting-entries | python -m json.tool

재검증 스크립트: C:\Users\kyu\Desktop\ga_pro\ga-commission-system\verify_v74.py

V74는 멱등(NOT EXISTS / ON CONFLICT DO NOTHING / WHERE menu_path != target)이므로 ga-api 재기동 시 안전하게 자동 적용됨.