feat: ga-core + ga-api + ga-batch + V13-V15 + Docker + frontend skeleton
ga-core (22 tables): - user/role: VO + Mapper + XML (login + RBAC) - org: Grade, Organization (CTE recursive tree), Agent + history - product: InsuranceCompany, Product, Contract - rule: CommissionRate, PayoutRule, OverrideRule, ChargebackRule, ExceptionTypeCode - receive: CompanyProfile, FieldMapping, CodeMapping, RawCommissionData, ParseError - ledger: Recruit, Maintain, Exception (batch insert + cursor) - settle: SettleMaster (UPSERT), Override, Chargeback, Payment, Reconciliation, BatchJobLog - All XMLs use EncryptTypeHandler for PII fields ga-api: - AuthController: login (lock on N fails), refresh, me, password, logout - Domain controllers: Agent, Organization, Contract, Company, Product, Rule, Receive, Ledger (recruit/maintain/exception + approve), Settle (confirm/hold/release), Payment, User, Role (matrix), BatchTrigger - All use @RequirePermission + @DataChangeLog ga-batch: - MonthlySettlementJob: 8 Steps (receiveData, transformData, reconcile, calcRecruit, calcMaintain, chargebackException, calcOverride, aggregate) - DataReceiver strategy + ManualReceiver, MappingEngine stub - CommissionCalculator (pct/tax via MoneyUtil), JobLauncherController DB V13~V15: - V13: 14 indexes (settle_master, ledgers, contract, chargeback, payment, raw, logs) - V14: create_monthly_partition() helper function - V15: v_agent_monthly_summary, v_org_settle_summary, v_chargeback_risk views Infra: - docker-compose: postgres + redis + api + batch + frontend - Multi-stage Dockerfile (gradle build → JRE) ga-frontend (skeleton): - Vite + React 18 + TypeScript + AntD 5 + AG Grid + React Query + Zustand - API request layer (axios + JWT), LoginPage, MainLayout (dynamic menu), Dashboard - nginx.conf for /api proxying
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
-- V13: 추가 인덱스 (성능 최적화)
|
||||
|
||||
-- settle_master: 정산월 기준 빈번한 조회
|
||||
CREATE INDEX IF NOT EXISTS idx_sm_month_status ON settle_master(settle_month, status);
|
||||
CREATE INDEX IF NOT EXISTS idx_sm_agent_month ON settle_master(agent_id, settle_month);
|
||||
|
||||
-- recruit_ledger / maintain_ledger: 정산월 + 설계사
|
||||
CREATE INDEX IF NOT EXISTS idx_rl_month_agent ON recruit_ledger(settle_month, agent_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_ml_month_agent ON maintain_ledger(settle_month, agent_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_rl_company ON recruit_ledger(company_code, settle_month);
|
||||
CREATE INDEX IF NOT EXISTS idx_ml_company ON maintain_ledger(company_code, settle_month);
|
||||
|
||||
-- exception_ledger: 정산월 + 승인상태
|
||||
CREATE INDEX IF NOT EXISTS idx_el_month_approve ON exception_ledger(settle_month, approve_status);
|
||||
|
||||
-- contract: 만기/실효 처리용
|
||||
CREATE INDEX IF NOT EXISTS idx_contract_lapse ON contract(lapse_date) WHERE lapse_date IS NOT NULL;
|
||||
CREATE INDEX IF NOT EXISTS idx_contract_status_agent ON contract(status, agent_id);
|
||||
|
||||
-- chargeback / payment 인덱스 보강
|
||||
CREATE INDEX IF NOT EXISTS idx_cb_month ON chargeback(settle_month, status);
|
||||
CREATE INDEX IF NOT EXISTS idx_pay_month ON payment(pay_date, pay_status);
|
||||
|
||||
-- raw / 에러 / 매핑
|
||||
CREATE INDEX IF NOT EXISTS idx_raw_status ON raw_commission_data(parse_status, settle_month);
|
||||
CREATE INDEX IF NOT EXISTS idx_pe_company ON parse_error_log(company_code, resolve_status);
|
||||
CREATE INDEX IF NOT EXISTS idx_codemap_lookup ON code_mapping(company_code, code_type, source_code) WHERE is_active = 'Y';
|
||||
|
||||
-- 로그 테이블 부분 인덱스 (날짜 검색)
|
||||
CREATE INDEX IF NOT EXISTS idx_dcl_table_recent ON data_change_log(table_name, created_at DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_aal_url_recent ON api_access_log(url, created_at DESC);
|
||||
@@ -0,0 +1,30 @@
|
||||
-- V14: 파티셔닝 (대용량 로그 테이블)
|
||||
--
|
||||
-- 주의: 운영에서 기존 테이블을 파티셔닝하려면 데이터 마이그레이션이 필요.
|
||||
-- 본 마이그레이션은 신규 테이블만 파티셔닝 적용.
|
||||
-- 기존 api_access_log / data_change_log 는 별도 마이그레이션으로 전환 권장.
|
||||
-- 본 V14 는 파티션 자동 생성을 위한 함수 + cron 형태의 helper.
|
||||
|
||||
-- 월별 파티션 테이블을 자동 생성하는 함수 (운영 시 cron 또는 pg_cron 으로 매월 호출)
|
||||
CREATE OR REPLACE FUNCTION create_monthly_partition(
|
||||
base_table TEXT,
|
||||
target_month DATE
|
||||
) RETURNS void AS $$
|
||||
DECLARE
|
||||
partition_name TEXT;
|
||||
start_date DATE;
|
||||
end_date DATE;
|
||||
BEGIN
|
||||
start_date := date_trunc('month', target_month);
|
||||
end_date := start_date + interval '1 month';
|
||||
partition_name := base_table || '_' || to_char(start_date, 'YYYYMM');
|
||||
|
||||
EXECUTE format(
|
||||
'CREATE TABLE IF NOT EXISTS %I PARTITION OF %I FOR VALUES FROM (%L) TO (%L)',
|
||||
partition_name, base_table, start_date, end_date
|
||||
);
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
COMMENT ON FUNCTION create_monthly_partition IS
|
||||
'파티션 테이블에 월별 파티션을 자동 생성. 예: SELECT create_monthly_partition(''api_access_log'', NOW())';
|
||||
@@ -0,0 +1,63 @@
|
||||
-- V15: 통계/리포트용 뷰
|
||||
|
||||
-- 설계사별 월 실적 요약
|
||||
CREATE OR REPLACE VIEW v_agent_monthly_summary AS
|
||||
SELECT
|
||||
sm.agent_id,
|
||||
a.agent_name,
|
||||
o.org_id,
|
||||
o.org_name,
|
||||
g.grade_name,
|
||||
sm.settle_month,
|
||||
sm.recruit_total,
|
||||
sm.maintain_total,
|
||||
sm.exception_plus,
|
||||
sm.exception_minus,
|
||||
sm.override_total,
|
||||
sm.chargeback_total,
|
||||
sm.gross_amount,
|
||||
sm.tax_amount,
|
||||
sm.net_amount,
|
||||
sm.status
|
||||
FROM settle_master sm
|
||||
JOIN agent a ON a.agent_id = sm.agent_id
|
||||
LEFT JOIN organization o ON o.org_id = a.org_id
|
||||
LEFT JOIN grade g ON g.grade_id = a.grade_id;
|
||||
|
||||
-- 조직별 월 정산 합계
|
||||
CREATE OR REPLACE VIEW v_org_settle_summary AS
|
||||
SELECT
|
||||
a.org_id,
|
||||
o.org_name,
|
||||
o.org_type,
|
||||
sm.settle_month,
|
||||
COUNT(sm.settle_id) AS agent_count,
|
||||
COALESCE(SUM(sm.recruit_total), 0) AS recruit_total,
|
||||
COALESCE(SUM(sm.maintain_total), 0) AS maintain_total,
|
||||
COALESCE(SUM(sm.gross_amount), 0) AS gross_amount,
|
||||
COALESCE(SUM(sm.tax_amount), 0) AS tax_amount,
|
||||
COALESCE(SUM(sm.net_amount), 0) AS net_amount
|
||||
FROM settle_master sm
|
||||
JOIN agent a ON a.agent_id = sm.agent_id
|
||||
JOIN organization o ON o.org_id = a.org_id
|
||||
GROUP BY a.org_id, o.org_name, o.org_type, sm.settle_month;
|
||||
|
||||
-- 환수 위험 계약 (실효 + 환수 발생)
|
||||
CREATE OR REPLACE VIEW v_chargeback_risk AS
|
||||
SELECT
|
||||
cb.cb_id,
|
||||
cb.contract_id,
|
||||
cb.agent_id,
|
||||
a.agent_name,
|
||||
o.org_name,
|
||||
cb.policy_no,
|
||||
cb.lapse_month,
|
||||
cb.cb_rate,
|
||||
cb.cb_amount,
|
||||
cb.paid_amount,
|
||||
cb.remain_amount,
|
||||
cb.settle_month,
|
||||
cb.status
|
||||
FROM chargeback cb
|
||||
JOIN agent a ON a.agent_id = cb.agent_id
|
||||
LEFT JOIN organization o ON o.org_id = a.org_id;
|
||||
Reference in New Issue
Block a user