멀티모듈 인프라: schema.d/ 분리 + acq.fd 범용필드 (병렬 팬아웃 충돌회피)

- db/schema.sql → db/schema.d/00-base.sql, compose가 schema.d 디렉터리 마운트
  (모듈들이 db/schema.d/NN-<mod>.sql 로 disjoint 추가)
- acq.fd에 범용 스크래치필드(T_ARG/T_STR/T_AMT/T_KEY/T_ID) → 모듈이 acq.fd 미수정
- setapp.sh gitignore 제외(필수 런타임 config)
- 검증: 4서버 runok, 41서비스, 체인 커밋 유지

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
forge-bot 2026-07-19 09:40:13 +00:00
parent 05a0ff3e56
commit 8219b85f14
6 changed files with 69 additions and 2 deletions

170
db/schema.d/00-base.sql Normal file
View file

@ -0,0 +1,170 @@
-- Card-acquiring schema (카드 매입/승인/정산/원장 + ac 모듈 상세 테이블)
-- Loaded into PostgreSQL on first boot (docker-entrypoint-initdb.d).
-- ---------------------------------------------------------------------------
-- 가맹점 (merchant)
-- ---------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS merchant (
merchant_id TEXT PRIMARY KEY,
name TEXT NOT NULL,
mdr_bps INTEGER NOT NULL DEFAULT 25, -- Merchant Discount Rate, basis points (0.25%)
daily_limit BIGINT NOT NULL DEFAULT 100000000,
status TEXT NOT NULL DEFAULT 'ACTIVE',
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
-- ---------------------------------------------------------------------------
-- 매입 (purchase) - the acquiring transaction
-- ---------------------------------------------------------------------------
CREATE SEQUENCE IF NOT EXISTS purchase_seq;
CREATE TABLE IF NOT EXISTS purchase (
purchase_id BIGINT PRIMARY KEY,
merchant_id TEXT NOT NULL,
amount BIGINT NOT NULL, -- minor units (원, 정수)
fee BIGINT NOT NULL, -- MDR fee
net BIGINT NOT NULL, -- amount - fee
status TEXT NOT NULL, -- A=접수, M=대사완료, S=정산완료, C=취소, H=보류, V=void
biz_date DATE NOT NULL,
channel TEXT NOT NULL DEFAULT 'POS', -- POS/EDC/EDI/FOREIGN
issuer TEXT NOT NULL DEFAULT 'UNKNOWN',
category TEXT NOT NULL DEFAULT 'GEN',
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
-- ---------------------------------------------------------------------------
-- 승인 (approval)
-- ---------------------------------------------------------------------------
CREATE SEQUENCE IF NOT EXISTS approval_seq;
CREATE TABLE IF NOT EXISTS approval (
approval_id BIGINT PRIMARY KEY,
purchase_id BIGINT NOT NULL,
approved BOOLEAN NOT NULL DEFAULT true,
approved_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
-- ---------------------------------------------------------------------------
-- 원장 (ledger) - recon/settle entries
-- ---------------------------------------------------------------------------
CREATE SEQUENCE IF NOT EXISTS ledger_seq;
CREATE TABLE IF NOT EXISTS ledger (
ledger_id BIGINT PRIMARY KEY,
purchase_id BIGINT NOT NULL,
entry_type TEXT NOT NULL, -- RECON / SETTLE / XFER / SETTLELINK
amount BIGINT NOT NULL,
biz_date DATE NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
-- ---------------------------------------------------------------------------
-- 정산 (settlement) - netting written during 정산
-- ---------------------------------------------------------------------------
CREATE SEQUENCE IF NOT EXISTS settlement_seq;
CREATE TABLE IF NOT EXISTS settlement (
settlement_id BIGINT PRIMARY KEY,
purchase_id BIGINT NOT NULL,
merchant_id TEXT NOT NULL,
net BIGINT NOT NULL,
biz_date DATE NOT NULL,
status TEXT NOT NULL DEFAULT 'SETTLED',
settled_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
-- ---------------------------------------------------------------------------
-- ac 모듈 상세 테이블 (취소/할부/수수료조정/원천/세금계산서/해외/EDI/미매입/집계)
-- ---------------------------------------------------------------------------
CREATE SEQUENCE IF NOT EXISTS ac_cancel_seq;
CREATE TABLE IF NOT EXISTS ac_cancel (
cancel_id BIGINT PRIMARY KEY,
purchase_id BIGINT NOT NULL,
cancel_type TEXT NOT NULL, -- FULL / PARTIAL / REFUND / VOID
amount BIGINT NOT NULL,
reason TEXT NOT NULL DEFAULT '',
biz_date DATE NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE SEQUENCE IF NOT EXISTS ac_install_seq;
CREATE TABLE IF NOT EXISTS ac_install (
install_id BIGINT PRIMARY KEY,
purchase_id BIGINT NOT NULL,
seq_no INTEGER NOT NULL,
months INTEGER NOT NULL,
month_amount BIGINT NOT NULL,
biz_date DATE NOT NULL
);
CREATE SEQUENCE IF NOT EXISTS ac_feeadj_seq;
CREATE TABLE IF NOT EXISTS ac_fee_adj (
adj_id BIGINT PRIMARY KEY,
purchase_id BIGINT NOT NULL,
delta BIGINT NOT NULL,
reason TEXT NOT NULL DEFAULT '',
biz_date DATE NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE SEQUENCE IF NOT EXISTS ac_wht_seq;
CREATE TABLE IF NOT EXISTS ac_wht (
wht_id BIGINT PRIMARY KEY,
purchase_id BIGINT NOT NULL,
tax_amount BIGINT NOT NULL,
biz_date DATE NOT NULL
);
CREATE SEQUENCE IF NOT EXISTS ac_taxinv_seq;
CREATE TABLE IF NOT EXISTS ac_tax_invoice (
inv_id BIGINT PRIMARY KEY,
purchase_id BIGINT NOT NULL,
merchant_id TEXT NOT NULL,
supply BIGINT NOT NULL,
vat BIGINT NOT NULL,
biz_date DATE NOT NULL
);
CREATE SEQUENCE IF NOT EXISTS ac_fx_seq;
CREATE TABLE IF NOT EXISTS ac_fx (
fx_id BIGINT PRIMARY KEY,
purchase_id BIGINT NOT NULL,
ccy TEXT NOT NULL,
fx_amount BIGINT NOT NULL,
krw_amount BIGINT NOT NULL,
rate_bps BIGINT NOT NULL,
biz_date DATE NOT NULL
);
CREATE SEQUENCE IF NOT EXISTS ac_edi_seq;
CREATE TABLE IF NOT EXISTS ac_edi (
edi_id BIGINT PRIMARY KEY,
merchant_id TEXT NOT NULL,
doc_no TEXT NOT NULL,
amount BIGINT NOT NULL,
biz_date DATE NOT NULL
);
CREATE SEQUENCE IF NOT EXISTS ac_unmatch_seq;
CREATE TABLE IF NOT EXISTS ac_unmatch (
unmatch_id BIGINT PRIMARY KEY,
purchase_id BIGINT NOT NULL,
reason TEXT NOT NULL,
biz_date DATE NOT NULL
);
-- 가맹점 일별 집계 (배치가 채움)
CREATE TABLE IF NOT EXISTS merchant_summary (
merchant_id TEXT NOT NULL,
biz_date DATE NOT NULL,
txn_count BIGINT NOT NULL DEFAULT 0,
gross_amount BIGINT NOT NULL DEFAULT 0,
fee_amount BIGINT NOT NULL DEFAULT 0,
net_amount BIGINT NOT NULL DEFAULT 0,
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
PRIMARY KEY (merchant_id, biz_date)
);
-- Seed merchants so ACQUIRE has a valid counterparty.
INSERT INTO merchant (merchant_id, name, mdr_bps, daily_limit) VALUES
('M0001', '클라로 커피', 25, 100000000),
('M0002', '포지 마트', 25, 100000000),
('M0003', '클라로 면세점', 30, 500000000)
ON CONFLICT (merchant_id) DO NOTHING;