-- ===========================================================================
-- 72-security.sql : 패리티 고도화 (Wave J) — 카드보안·자금연동·수수료·분쟁·리포팅
--   실제 매입사 대비 갭이던 PCI/3DS/AVS·CVV, 은행 rails 펀딩, DCC, 채그백수수료,
--   retrieval, 규제보고를 데이터 모델로 추가. 기존 구조 불변(추가만).
-- ===========================================================================

-- ---------------------------------------------------------------------------
-- J-1. 카드보안
-- ---------------------------------------------------------------------------
-- 토큰볼트: PAN 을 토큰으로 치환, 원문은 저장하지 않음(마스킹만 보관). PCI 스코프 축소.
CREATE SEQUENCE IF NOT EXISTS card_token_seq START 4000000;
CREATE TABLE IF NOT EXISTS card_vault (
    token        TEXT PRIMARY KEY,            -- 표면 토큰(비민감). 예: TKN-xxxxxxxx
    pan_masked   TEXT NOT NULL,               -- 4111-****-****-1111 (마스킹)
    pan_hash     TEXT NOT NULL,               -- SHA-256(PAN) — 중복탐지/조회용(원문 불가역)
    bin          TEXT NOT NULL,               -- 앞 6자리(라우팅)
    last4        TEXT NOT NULL,
    card_type    TEXT NOT NULL DEFAULT 'CREDIT',
    issuer       TEXT NOT NULL DEFAULT 'BC',
    exp_ym       TEXT,                         -- YYYYMM (만료)
    created_at   TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS ix_vault_hash ON card_vault(pan_hash);
CREATE INDEX IF NOT EXISTS ix_vault_bin  ON card_vault(bin);

-- 3DS/SCA 인증 결과 (비대면 거래 인증·책임전환)
CREATE SEQUENCE IF NOT EXISTS au_3ds_seq START 500000;
CREATE TABLE IF NOT EXISTS au_3ds (
    tds_id       BIGINT PRIMARY KEY,
    purchase_id  BIGINT,
    token        TEXT,
    version      TEXT NOT NULL DEFAULT '2.2.0',  -- 3DS 버전
    eci          TEXT NOT NULL,                  -- 05=완전인증 06=시도 07=미인증
    cavv         TEXT,                           -- 인증검증값(Base64)
    ds_trans_id  TEXT,                           -- Directory Server txn id
    auth_status  TEXT NOT NULL,                  -- Y=인증 A=시도 N=실패 U=불가 R=거부
    liability    TEXT NOT NULL DEFAULT 'ISSUER', -- 책임주체: ISSUER(전환됨)/MERCHANT
    created_at   TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS ix_3ds_pid ON au_3ds(purchase_id);

-- AVS/CVV 검증 응답
CREATE SEQUENCE IF NOT EXISTS au_verify_seq START 550000;
CREATE TABLE IF NOT EXISTS au_verify (
    vrf_id       BIGINT PRIMARY KEY,
    purchase_id  BIGINT,
    token        TEXT,
    avs_code     TEXT NOT NULL DEFAULT 'U',   -- Y/A/Z/N/U (주소·우편일치)
    cvv_code     TEXT NOT NULL DEFAULT 'U',   -- M=일치 N=불일치 P=미처리 U=불가
    risk_score   INTEGER NOT NULL DEFAULT 0,  -- 0~999
    decision     TEXT NOT NULL DEFAULT 'APPROVE', -- APPROVE/DECLINE/REVIEW
    created_at   TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS ix_verify_pid ON au_verify(purchase_id);

-- ---------------------------------------------------------------------------
-- J-2. 자금이동 실연동
-- ---------------------------------------------------------------------------
-- 펀딩 지시/반환 (펌뱅킹/ACH 등가). 순액정산 결과를 은행 rails 로 지급 지시.
CREATE SEQUENCE IF NOT EXISTS st_fundinstr_seq START 850000;
CREATE TABLE IF NOT EXISTS st_funding_instr (
    instr_id     BIGINT PRIMARY KEY,
    merchant_id  TEXT NOT NULL,
    biz_date     DATE NOT NULL,
    bank_code    TEXT NOT NULL DEFAULT 'KB',   -- 입금은행
    account_no   TEXT NOT NULL,
    amount       BIGINT NOT NULL,              -- 지급액(펀딩 deposit)
    rail         TEXT NOT NULL DEFAULT 'FIRMBANK', -- FIRMBANK/ACH/RTGS
    status       TEXT NOT NULL DEFAULT 'SENT', -- SENT/CONFIRMED/RETURNED
    return_code  TEXT,                         -- 반환사유(계좌오류 등)
    sent_at      TIMESTAMPTZ NOT NULL DEFAULT now(),
    confirmed_at TIMESTAMPTZ
);
CREATE INDEX IF NOT EXISTS ix_fundinstr_merch ON st_funding_instr(merchant_id, biz_date);

-- DCC (해외카드 원화가맹점 결제시 통화선택) — 승인시점 환율고정.
CREATE SEQUENCE IF NOT EXISTS ac_dcc_seq START 450000;
CREATE TABLE IF NOT EXISTS ac_dcc (
    dcc_id        BIGINT PRIMARY KEY,
    purchase_id   BIGINT NOT NULL,
    base_ccy      TEXT NOT NULL DEFAULT 'KRW', -- 가맹점 통화
    txn_ccy       TEXT NOT NULL,               -- 카드소지자 통화(USD/JPY/EUR...)
    base_amount   BIGINT NOT NULL,             -- 원화 금액
    txn_amount    NUMERIC(18,2) NOT NULL,      -- 외화 금액
    fx_rate       NUMERIC(14,6) NOT NULL,      -- 고정환율
    markup_bps    INTEGER NOT NULL DEFAULT 300,-- DCC 마크업(3%)
    opted_in      BOOLEAN NOT NULL DEFAULT true,
    created_at    TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS ix_dcc_pid ON ac_dcc(purchase_id);

-- ---------------------------------------------------------------------------
-- J-3. 수수료·분쟁 운영
-- ---------------------------------------------------------------------------
-- 채그백 수수료 (분쟁 발생시 가맹점 부과 건당 수수료)
CREATE SEQUENCE IF NOT EXISTS st_cbfee_seq START 950000;
CREATE TABLE IF NOT EXISTS st_cb_fee (
    cbfee_id     BIGINT PRIMARY KEY,
    dispute_id   BIGINT NOT NULL,
    merchant_id  TEXT NOT NULL,
    fee_amount   BIGINT NOT NULL DEFAULT 15000, -- 건당 채그백 수수료(원)
    stage        TEXT NOT NULL,                 -- 어느 단계에서 부과
    billed       BOOLEAN NOT NULL DEFAULT false,
    biz_date     DATE NOT NULL,
    created_at   TIMESTAMPTZ NOT NULL DEFAULT now()
);

-- retrieval request (매출전표 조회요청 — 채그백 전 단계)
CREATE SEQUENCE IF NOT EXISTS ac_retrieval_seq START 620000;
CREATE TABLE IF NOT EXISTS ac_retrieval (
    retr_id      BIGINT PRIMARY KEY,
    purchase_id  BIGINT NOT NULL,
    merchant_id  TEXT NOT NULL,
    reason       TEXT NOT NULL,                -- 조회사유
    status       TEXT NOT NULL DEFAULT 'OPEN', -- OPEN/FULFILLED/EXPIRED
    sla_due      DATE NOT NULL,                -- SLA 마감일
    fulfilled_at TIMESTAMPTZ,
    created_at   TIMESTAMPTZ NOT NULL DEFAULT now()
);

-- 분쟁 SLA 타이머 컬럼 추가 (기존 ac_dispute 확장)
ALTER TABLE ac_dispute ADD COLUMN IF NOT EXISTS sla_due DATE;
ALTER TABLE ac_dispute ADD COLUMN IF NOT EXISTS fraud_flag BOOLEAN NOT NULL DEFAULT false;

-- ---------------------------------------------------------------------------
-- J-4. 리포팅·규제
-- ---------------------------------------------------------------------------
-- 가맹점 월 명세서
CREATE SEQUENCE IF NOT EXISTS rp_stmt_seq START 700000;
CREATE TABLE IF NOT EXISTS rp_merchant_stmt (
    stmt_id      BIGINT PRIMARY KEY,
    merchant_id  TEXT NOT NULL,
    stmt_month   TEXT NOT NULL,               -- YYYYMM
    gross_sales  BIGINT NOT NULL DEFAULT 0,
    txn_count    BIGINT NOT NULL DEFAULT 0,
    total_fees   BIGINT NOT NULL DEFAULT 0,
    interchange  BIGINT NOT NULL DEFAULT 0,
    scheme_fee   BIGINT NOT NULL DEFAULT 0,
    markup       BIGINT NOT NULL DEFAULT 0,
    cb_fees      BIGINT NOT NULL DEFAULT 0,
    net_deposit  BIGINT NOT NULL DEFAULT 0,
    issued_at    TIMESTAMPTZ NOT NULL DEFAULT now(),
    UNIQUE (merchant_id, stmt_month)
);

-- 규제보고 (여신전문금융업법 정산주기 준수 등)
CREATE SEQUENCE IF NOT EXISTS rp_reg_seq START 710000;
CREATE TABLE IF NOT EXISTS rp_regulatory (
    reg_id       BIGINT PRIMARY KEY,
    report_type  TEXT NOT NULL,               -- SETTLE_CYCLE/FEE_DISCLOSURE/TXN_VOLUME
    period       TEXT NOT NULL,               -- YYYYMM
    metric       TEXT NOT NULL,
    value        NUMERIC(18,2) NOT NULL,
    compliant    BOOLEAN NOT NULL DEFAULT true,
    note         TEXT,
    created_at   TIMESTAMPTZ NOT NULL DEFAULT now()
);
