검증 결과: - 정적 검증: Mapper-XML 매칭 OK (24개 메뉴코드 ↔ DB 매칭) - TypeScript: 0 errors (vite-env.d.ts 추가) - vite build: 성공 (dist/ 생성, 1.3MB → gzip 411KB) - gradle :ga-api:bootJar: 성공 (74MB) - gradle :ga-batch:bootJar: 성공 (76MB) 수정 사항: - ga-common/core/admin: bootJar.enabled=false 제거 (spring-boot 플러그인 미적용 모듈에서 task 참조 에러) - ga-frontend/vite.config.ts: '@/*' alias 추가 (Rollup이 path resolution 못함) - ga-frontend/src/vite-env.d.ts: import.meta.env 타입 정의 - ga-frontend/components/ExcelExportButton: params 타입 완화 (Record<string,unknown> | object) - gradle wrapper 8.6 추가 (./gradlew 사용 가능) - .gitignore: .claude/ 추가 (Agent Teams 개인 설정)
GA 수수료 정산 솔루션
법인보험대리점(GA) 수수료 정산 시스템 — Multi-module Spring Boot + React.
기술 스택
| 영역 | 기술 |
|---|---|
| Backend | Java 17, Spring Boot 3.2, Spring Security, Spring Batch |
| ORM | MyBatis 3 + PageHelper |
| DB | PostgreSQL 16 |
| Cache | Redis 7 |
| Build | Gradle 멀티모듈 |
| Frontend | React 18 + Vite + TypeScript + Ant Design 5 + AG Grid + React Query + Zustand |
| Infra | Docker Compose, Nginx |
모듈 구조
ga-commission-system/
├── ga-common/ # 공통 프레임워크 (인증/권한/로그/엑셀/공통코드/메뉴)
├── ga-core/ # 도메인 코어 (VO, Mapper, SQL)
├── ga-api/ # REST API (포트 8080)
├── ga-batch/ # Spring Batch (포트 8081)
├── ga-admin/ # 관리자 라이브러리
└── ga-frontend/ # React SPA (포트 3000)
🚀 실행 가이드
환경 요구사항
- Java 17+ (
java -version확인) - Node.js 18+ + npm
- PostgreSQL 14+ (운영:
192.168.0.60:55432/trading_ai/gaschema) - Redis 7+ (선택 — 공통코드/세션 캐시)
- Gradle (또는 IDE: IntelliJ IDEA 권장 — 자동으로 Gradle wrapper 생성)
시나리오 A — 운영 DB(trading_ai/ga) 에 연결해서 실행 ⭐ 권장
이미 V1~V17 마이그레이션 + 테스트 데이터(보험사 5 / 상품 20 / 설계사 50 / 계약 200)가
192.168.0.60:55432/trading_ai/ga 스키마에 적용되어 있습니다.
1) Backend (ga-api) 실행
# 1-1. Gradle wrapper 가 없다면 한 번 생성 (Gradle 설치 필요)
gradle wrapper --gradle-version 8.6
# 1-2. 빌드
./gradlew :ga-api:bootJar
# 1-3. 실행 (trading_ai 프로파일 — 운영 DB 연결)
./gradlew :ga-api:bootRun --args='--spring.profiles.active=trading_ai'
# 또는 환경변수로 비밀번호/Redis 호스트 오버라이드
export DB_PASSWORD=your-password
export REDIS_HOST=localhost
java -jar ga-api/build/libs/ga-api.jar --spring.profiles.active=trading_ai
확인:
- API: http://localhost:8080
- Swagger: http://localhost:8080/swagger-ui.html
2) Backend (ga-batch) 실행 — 정산 배치 트리거 처리
./gradlew :ga-batch:bootRun --args='--spring.profiles.active=trading_ai'
# 또는
java -jar ga-batch/build/libs/ga-batch.jar --spring.profiles.active=trading_ai
기본 포트 8081. ga-api 가 /api/batch/settlement/run 호출 시 batch_job_log 에
REQUESTED 상태로 기록되며, ga-batch 가 이를 폴링/직접 호출로 실행합니다.
3) Frontend 실행
cd ga-frontend
npm install
npm run dev # http://localhost:3000 (Vite dev server)
기본적으로 /api/* 요청은 Vite 프록시로 http://localhost:8080 으로 전달됩니다.
4) 로그인 & 동작 확인
URL : http://localhost:3000
ID : admin
PW : admin1234!
로그인 후 사이드바 메뉴 — 좌측에 동적으로 메뉴가 그려져야 합니다. 주요 화면:
| 메뉴 | 경로 | 설명 |
|---|---|---|
| 대시보드 | / |
정산 요약 카드 |
| 설계사 관리 | /org/agents |
50명 더미 + 검색/등록/수정/엑셀 |
| 계약 관리 | /contracts |
200건 더미 + 상태/보험사 필터 |
| 모집수수료 원장 | /ledger/recruit |
AG Grid 호환 테이블 + 엑셀 다운로드 |
| 예외금액 원장 | /ledger/exception |
승인/반려 |
| 정산 결과 | /settle |
월 요약 + 확정/보류 |
| 정산 배치 | /settle/batch |
배치 실행 + 진행률 폴링 |
| 지급 관리 | /payments |
지급 상태 추적 |
| 사용자 관리 | /system/users |
비번 초기화/잠금 해제 |
| 역할/권한 | /system/roles |
권한 매트릭스 (메뉴 × 6권한) |
| 공통코드 | /system/codes |
그룹별 코드 조회 |
시나리오 B — 로컬 PostgreSQL 로 처음부터 (개발용)
# 1) PostgreSQL + Redis 기동 (Docker)
docker compose up -d postgres redis
# 2) ga-api 실행 (Flyway 가 자동으로 V1~V17 마이그레이션)
./gradlew :ga-api:bootRun
# 기본 프로파일은 application.yml — localhost:5432/ga 에 연결
# 3) ga-batch 실행
./gradlew :ga-batch:bootRun
# 4) 프론트
cd ga-frontend && npm install && npm run dev
application.yml 의 기본 DB:
url: jdbc:postgresql://localhost:5432/ga
username: ga
password: ga
시나리오 C — Docker Compose 로 전체 기동
docker compose up -d --build
# postgres + redis + api + batch + frontend 모두 컨테이너로 기동
# - 프론트: http://localhost:3000
# - API: http://localhost:8080/swagger-ui.html
# - Batch: http://localhost:8081 (내부 통신용)
docker-compose.yml 환경변수:
JWT_SECRET— JWT 서명 키 (256bit 이상)ENCRYPT_KEY— AES-256 키 (32바이트)
DB 마이그레이션 직접 실행 (스크립트)
저장소 루트의 migrate.py (이 파일은 ga-commission-system 외부에 있음) — Python + pg8000 으로
V1~V17 SQL을 임의 DB에 일괄 적용:
pip install pg8000
python migrate.py
# host/port/db/user/schema 는 파일 상단 상수로 수정
ga 스키마가 이미 있으면 idempotent guard 로 멈춥니다.
완전 재설치는 DROP SCHEMA ga CASCADE; CREATE SCHEMA ga; 후 재실행.
🧪 데이터 확인 (운영 DB 기준)
| 테이블 | 건수 |
|---|---|
| insurance_company | 5 (삼성/한화/교보/디비/KB) |
| product | 20 (보험사 × 4상품) |
| organization | 7 (본부 1 / 지점 3 / 팀 3) |
| agent | 50 (GM 3 / DM 3 / SMGR 6 / SFC 12 / FC 26) |
| contract | 200 (ACTIVE 190 / LAPSE 10) |
| commission_rate | 100 |
| payout_rule | 120 |
| override_rule | 10 |
| chargeback_rule | 4 |
| common_code (그룹/상세) | 18 / 42 |
| menu / menu_permission | 33 / 150 |
| role / role_menu_permission | 4 / 323 |
🔧 트러블슈팅
Q. ./gradlew 가 없다고 함
gradle wrapper --gradle-version 8.6 로 한번 생성하거나, IntelliJ 로 프로젝트 열면 자동 생성.
Q. ga-api 부팅 시 Failed to determine a suitable driver class
JDBC URL 또는 자격증명 누락. --spring.profiles.active=trading_ai 가 적용됐는지 확인.
Q. NoSuchKey: ga (Flyway)
운영 DB 의 ga 스키마를 인식하려면 currentSchema=ga 가 URL 에 있어야 함.
application-trading_ai.yml 에서 이미 설정되어 있음.
Q. 프론트에서 401 / "토큰이 만료되었습니다"
localStorage 에 accessToken 이 만료됨. /login 으로 다시 로그인.
Q. AG Grid 가 빈 화면으로 보임
@ag-grid-community/styles/ag-theme-quartz.css import 가 잘 됐는지 확인.
Q. 비밀번호 변경
-- BCrypt 해시 생성 후 직접 UPDATE
UPDATE ga.users SET password = '$2b$10$...' WHERE login_id = 'admin';
또는 사용자 관리 화면 → "비번초기화" 액션.
📋 주요 기능
백엔드
- 인증/권한: JWT (HS256), 메뉴×권한 RBAC, BCrypt 비밀번호
- 공통코드: Redis 캐시, 시스템코드 잠금, REST CRUD
- 메뉴: 트리 구조, 사용자별 동적 메뉴 + 권한 매트릭스
- 엑셀: SXSSF+Cursor 다운로드(100만건), SAX+배치 업로드(70만건)
- 로그: 로그인/API/데이터변경 자동 기록 (비동기)
- 암호화: AES-256 CBC (
resident_no,account_no자동)
도메인
- 조직: 트리 구조, CTE 재귀, 인사 이력
- 계약: 보험사/상품/계약 관리
- 수수료 규정: 보험사율, 지급율, 오버라이드, 환수, 예외코드
- 원장: 모집/유지/예외 (PageHelper + AG Grid)
- 정산: 8 Step 배치 (수신→변환→대사→모집→유지→환수/예외→오버라이드→집계)
- 지급: 이체파일 생성, 상태 추적
정산 배치 8 Step
- receiveData — 보험사별 DataReceiver → raw_commission_data 적재
- transformData — MappingEngine 으로 raw → 표준 원장 (TRIM/UPPER/DATE/DIVIDE/CODE_MAP)
- reconcile — 보험사 통보액 vs 시스템 계산액 대사
- calcRecruit — 모집수수료 (계약시점 commission_rate/payout_rule 적용)
- calcMaintain — 유지수수료 (납입주기 매칭, 1~5년차)
- chargebackException — 실효 계약 환수 자동생성
- calcOverride — 조직 트리 상향 탐색 → 상위 직급에 분배
- aggregate — 설계사별 통합 집계 → settle_master UPSERT (3.3% 세금)
🛠 신입 개발자 표준 패턴 (5분 컷)
// 1) VO (XxxVO + XxxResp + XxxSaveReq + XxxSearchParam)
@Data
public class FooSearchParam extends SearchParam { }
// 2) Mapper Interface + XML
@Mapper
public interface FooMapper {
List<FooResp> selectList(FooSearchParam p);
}
// 3) Service
@Service @RequiredArgsConstructor
public class FooService {
private final FooMapper mapper;
public PageResponse<FooResp> list(FooSearchParam p) {
p.startPage();
return PageResponse.of(mapper.selectList(p));
}
}
// 4) Controller
@RestController @RequestMapping("/api/foos") @RequiredArgsConstructor
public class FooController {
private final FooService service;
@GetMapping
@RequirePermission(menu = "FOO", perm = "READ")
public ApiResponse<PageResponse<FooResp>> list(FooSearchParam p) {
return ApiResponse.ok(service.list(p));
}
}
🔒 보안
- JWT (HS256) — 액세스 2시간, 리프레시 7일
- AES-256 CBC 암호화 (
EncryptTypeHandler자동 적용) - RBAC —
role_menu_permission매트릭스 @DataChangeLog— 데이터 변경 이력 AOP 자동- API 접근 로그 — 비동기 저장 (
api_access_log)
🗄 DB 마이그레이션
| 버전 | 내용 |
|---|---|
| V1~V8 | 도메인 스키마 + 초기 데이터 (직급, 예외코드) |
| V9~V12 | 공통코드/메뉴/시스템관리 + 초기 데이터 |
| V13 | 인덱스 최적화 |
| V14 | 파티셔닝 helper 함수 |
| V15 | 통계/리포트 뷰 (v_agent_monthly_summary 등) |
| V16 | 관리자 계정 + 메뉴 상세 + 권한 매트릭스 |
| V17 | 테스트 데이터 (보험사 5 / 상품 20 / 설계사 50 / 계약 200 + 수수료 규정) |
✅ 진행 상황
- 1단계 — 프로젝트 뼈대 + DB (V1~V17)
- ga-common — 공통 프레임워크 일체
- ga-core — 22개 테이블 VO/Mapper/XML
- ga-api — Auth + 14개 도메인 컨트롤러
- ga-batch — MonthlySettlementJob 8 Step (실제 동작 로직 포함)
- Docker — docker-compose + multi-stage Dockerfile + nginx
- ga-frontend — 13개 페이지 (대시보드/설계사/계약/원장/정산/지급/배치/시스템관리)
- 운영 DB 적용 — 192.168.0.60:55432/trading_ai/ga (V1~V17 + 테스트 데이터)
- 단위/통합 테스트 — 미작성
- MappingEngine 정밀화 — 일부 변환 규칙은 단순화된 형태
🔮 향후 확장
- 프론트 페이지 추가:
menu테이블 등록 → React 페이지 구현 → 동적 라우팅 적용 - 신규 보험사:
company_profile+company_field_mapping등록 + 필요 시DataReceiver구현 - 신규 정산 규정:
commission_rate/payout_rule/override_rule/chargeback_rule에effective_from만 다른 버전으로 추가 (versioning) - 이체파일 포맷: 은행별 EBCDIC/CSV 출력 어댑터 추가
📡 외부 시스템 연결 정보 (요약)
| 항목 | 값 |
|---|---|
| 운영 DB 호스트 | 192.168.0.60 |
| 운영 DB 포트 | 55432 |
| 운영 DB 데이터베이스 | trading_ai |
| 운영 DB 스키마 | ga |
| 운영 DB 사용자 | kyu |
| Git 원격 | https://gl.kyleyang.co.kr/kyu/ga-commission-system |
| 초기 관리자 | admin / admin1234! |