Phase 1: 실동작 Enduro/X + PostgreSQL XA 매입 슬라이스
- Enduro/X 7.0.12 소스빌드 이미지(-DENABLE_POSTGRES=ON, libndrxxaecpg XA 스위치) - docker-compose: postgres(max_prepared_transactions=100) + endurox app - ECPG XA 서비스 3종: ACQUIRE→RECONCILE→SETTLE (tpservice + EXEC SQL) - 클라이언트 tpbegin/tpcall체인/tpcommit → tmsrv 2PC(prepare/commit) 원자 커밋 - 검증: 서비스 AVAIL, 커밋 row(status=S) psql 확인, 롤백 시 무잔존, pg_prepared_xacts=0 - 규명된 런타임 요건: sysctl fs.mqueue.*, ulimit msgqueue/nofile, XA open-str JSON - docs/architecture.md, README, service-catalog 설계 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
commit
e6e29e6b5d
19 changed files with 1005 additions and 0 deletions
74
db/schema.sql
Normal file
74
db/schema.sql
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
-- Card-acquiring vertical-slice schema (카드 매입/승인/정산/원장)
|
||||
-- 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%)
|
||||
status TEXT NOT NULL DEFAULT 'ACTIVE',
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
-- ---------------------------------------------------------------------------
|
||||
-- 매입 (purchase) - the acquiring transaction
|
||||
-- purchase_id driven by an explicit sequence so ECPG can SELECT nextval first.
|
||||
-- ---------------------------------------------------------------------------
|
||||
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=대사완료(matched), S=정산완료(settled)
|
||||
biz_date DATE NOT NULL,
|
||||
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) - double-entry style recon check written during 대사
|
||||
-- ---------------------------------------------------------------------------
|
||||
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
|
||||
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()
|
||||
);
|
||||
|
||||
-- Seed a couple of merchants so ACQUIRE has a valid counterparty.
|
||||
INSERT INTO merchant (merchant_id, name, mdr_bps) VALUES
|
||||
('M0001', '클라로 커피', 25),
|
||||
('M0002', '포지 마트', 25)
|
||||
ON CONFLICT (merchant_id) DO NOTHING;
|
||||
Loading…
Add table
Add a link
Reference in a new issue