Files
GA Pro e4697dd5ee docs: 실행 가이드 + 운영 DB 연결 정보 README 보강
- 시나리오 A: 운영 DB(trading_ai/ga, 포트 55432) 연결 실행
- 시나리오 B: 로컬 PostgreSQL 처음부터 (Flyway 자동 마이그레이션)
- 시나리오 C: Docker Compose 전체 기동
- 트러블슈팅 6항목 (Gradle 미설치, JDBC 드라이버, Flyway 스키마, JWT, AG Grid, 비밀번호)
- 13개 페이지 메뉴-경로 표
- 데이터 현황 테이블 (보험사 5 / 상품 20 / 설계사 50 / 계약 200 등)
- 외부 시스템 연결 정보 (호스트/포트/스키마/관리자 계정)
2026-05-09 22:50:19 +09:00

346 lines
12 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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/ga` schema)
- **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) 실행
```bash
# 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) 실행 — 정산 배치 트리거 처리
```bash
./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 실행
```bash
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 로 처음부터 (개발용)
```bash
# 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:
```yaml
url: jdbc:postgresql://localhost:5432/ga
username: ga
password: ga
```
---
### 시나리오 C — Docker Compose 로 전체 기동
```bash
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에 일괄 적용:
```bash
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. 비밀번호 변경
```sql
-- 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
1. **receiveData** — 보험사별 DataReceiver → raw_commission_data 적재
2. **transformData** — MappingEngine 으로 raw → 표준 원장 (TRIM/UPPER/DATE/DIVIDE/CODE_MAP)
3. **reconcile** — 보험사 통보액 vs 시스템 계산액 대사
4. **calcRecruit** — 모집수수료 (계약시점 commission_rate/payout_rule 적용)
5. **calcMaintain** — 유지수수료 (납입주기 매칭, 1~5년차)
6. **chargebackException** — 실효 계약 환수 자동생성
7. **calcOverride** — 조직 트리 상향 탐색 → 상위 직급에 분배
8. **aggregate** — 설계사별 통합 집계 → settle_master UPSERT (3.3% 세금)
---
## 🛠 신입 개발자 표준 패턴 (5분 컷)
```java
// 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 + 수수료 규정) |
---
## ✅ 진행 상황
- [x] 1단계 — 프로젝트 뼈대 + DB (V1~V17)
- [x] **ga-common** — 공통 프레임워크 일체
- [x] **ga-core** — 22개 테이블 VO/Mapper/XML
- [x] **ga-api** — Auth + 14개 도메인 컨트롤러
- [x] **ga-batch** — MonthlySettlementJob 8 Step (실제 동작 로직 포함)
- [x] **Docker** — docker-compose + multi-stage Dockerfile + nginx
- [x] **ga-frontend** — 13개 페이지 (대시보드/설계사/계약/원장/정산/지급/배치/시스템관리)
- [x] **운영 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!` |