feat: 테스트 데이터(V17) + 실 DB 프로파일 + 프론트 화면 확장

V17 (192.168.0.60:55432/trading_ai/ga 적용 완료):
- 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 (5상품 × 5년차 × 5보험사 = 일부)
  실제 INSERT는 상품 20개 × 1년차 + 20 × 4년차 = 100건
- payout_rule 120 (직급 6 × 보험종류 4 × 연차 5)
- override_rule 10 (FC/SFC/MGR/SMGR/DM 직급 간 오버라이드)
- chargeback_rule 4 (실효월수 구간별 환수율)

운영 DB 프로파일:
- application-trading_ai.yml (ga-api, ga-batch)
- 192.168.0.60:55432 / trading_ai / currentSchema=ga
- Flyway baseline-version=17 (수동 적용 분 인정)

DB 포트 변경 반영: 5432 → 55432 (운영 변경)

프론트 추가 화면:
- DataGrid (AG Grid Community 래퍼; 합계행/셀편집/로딩 오버레이)
- 예외원장 (ExceptionLedger): 승인/반려 액션
- 지급관리 (PaymentList)
- 정산 배치 (BatchRun): 실행 + 진행률 폴링
- 시스템관리:
  * UserList: 비밀번호 초기화 + 잠금 해제
  * RoleList: 좌측 역할 + 우측 권한 매트릭스 (메뉴 × 6권한)
  * CodeList: 좌측 그룹 + 우측 상세 코드, 시스템그룹 경고

설계사 상세/등록 폼:
- AgentDetail: 통계 카드 + 기본정보 + 수정 버튼
- AgentForm: 등록/수정 통합 (id='new' 또는 :id/edit)

라우터:
- /org/agents/{new|:id|:id/edit}
- /ledger/exception, /payments, /settle/batch
- /system/{users|roles|codes}
This commit is contained in:
GA Pro
2026-05-09 22:47:55 +09:00
parent 98eb231950
commit 92079d2385
16 changed files with 1197 additions and 4 deletions
+95
View File
@@ -0,0 +1,95 @@
import api, { PageResponse, unwrap } from './request';
export interface UserResp {
userId: number;
loginId: string;
userName: string;
email?: string;
phone?: string;
agentId?: number;
agentName?: string;
orgName?: string;
status: string;
failCount?: number;
lastLoginAt?: string;
createdAt?: string;
roleCodes?: string[];
}
export interface UserSaveReq {
loginId: string;
userName: string;
email?: string;
phone?: string;
agentId?: number;
status?: string;
password?: string;
roleIds?: number[];
}
export const userApi = {
list: (p: { searchKeyword?: string; status?: string; pageNum?: number; pageSize?: number }) =>
unwrap<PageResponse<UserResp>>(api.get('/api/system/users', { params: p })),
detail: (id: number) => unwrap<UserResp>(api.get(`/api/system/users/${id}`)),
create: (req: UserSaveReq) => unwrap<number>(api.post('/api/system/users', req)),
update: (id: number, req: UserSaveReq) => unwrap<void>(api.put(`/api/system/users/${id}`, req)),
resetPassword: (id: number) => unwrap<void>(api.put(`/api/system/users/${id}/reset-password`)),
unlock: (id: number) => unwrap<void>(api.put(`/api/system/users/${id}/unlock`)),
};
export interface RoleVO {
roleId: number;
roleCode: string;
roleName: string;
roleDesc?: string;
roleLevel: number;
isSystem: string;
isActive: string;
}
export const roleApi = {
list: () => unwrap<RoleVO[]>(api.get('/api/system/roles')),
detail: (id: number) => unwrap<RoleVO>(api.get(`/api/system/roles/${id}`)),
permissions: (id: number) =>
unwrap<Array<{ menuId: number; permCode: string; isGranted: string }>>(api.get(`/api/system/roles/${id}/permissions`)),
create: (vo: Partial<RoleVO>) => unwrap<number>(api.post('/api/system/roles', vo)),
update: (id: number, vo: Partial<RoleVO>) => unwrap<void>(api.put(`/api/system/roles/${id}`, vo)),
savePermissions: (id: number, perms: Array<{ menuId: number; permCode: string; isGranted: string }>) =>
unwrap<void>(api.put(`/api/system/roles/${id}/permissions`, perms)),
};
export interface CommonCodeGroup {
groupCode: string;
groupName: string;
description?: string;
isSystem: string;
isActive: string;
sortOrder: number;
}
export interface CommonCode {
codeId: number;
groupCode: string;
code: string;
codeName: string;
codeDesc?: string;
sortOrder: number;
isActive: string;
}
export const commonCodeApi = {
groups: (keyword?: string) =>
unwrap<CommonCodeGroup[]>(api.get('/api/common/codes/groups', { params: { keyword } })),
codes: (groupCode: string) =>
unwrap<CommonCode[]>(api.get(`/api/common/codes/groups/${groupCode}/codes`)),
createGroup: (vo: Partial<CommonCodeGroup>) =>
unwrap<void>(api.post('/api/common/codes/groups', vo)),
updateGroup: (groupCode: string, vo: Partial<CommonCodeGroup>) =>
unwrap<void>(api.put(`/api/common/codes/groups/${groupCode}`, vo)),
createCode: (groupCode: string, vo: Partial<CommonCode>) =>
unwrap<void>(api.post(`/api/common/codes/groups/${groupCode}/codes`, vo)),
updateCode: (codeId: number, vo: Partial<CommonCode>) =>
unwrap<void>(api.put(`/api/common/codes/codes/${codeId}`, vo)),
deleteCode: (codeId: number) =>
unwrap<void>(api.delete(`/api/common/codes/codes/${codeId}`)),
};