-- mg 모듈 (전문게이트웨이 / message gateway) 스키마
-- ISO8583 전문 로그/라우팅/채번/채널세션/큐/통계 테이블.
-- Loaded into PostgreSQL on first boot (docker-entrypoint-initdb.d). Prefix 60.

-- ---------------------------------------------------------------------------
-- 전문 채번 (STAN / 전문 시퀀스) - MG_STAN 이 nextval 로 채번
-- ---------------------------------------------------------------------------
CREATE SEQUENCE IF NOT EXISTS mg_stan_seq;      -- System Trace Audit Number
CREATE SEQUENCE IF NOT EXISTS mg_msg_seq;       -- 전문 로그 PK
CREATE SEQUENCE IF NOT EXISTS mg_route_seq;     -- 라우팅 룰 PK
CREATE SEQUENCE IF NOT EXISTS mg_queue_seq;     -- 송수신 큐 PK

-- 이름있는 카운터 (세션 시퀀스 등 채번용 - MG_SESSION/MG_KEYEXCH)
CREATE TABLE IF NOT EXISTS mg_seq (
    seq_name   TEXT PRIMARY KEY,
    seq_val    BIGINT NOT NULL DEFAULT 0,
    updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);

-- ---------------------------------------------------------------------------
-- 전문 로그 (mg_msg_log) - 수신/송신 전문의 원장
-- ---------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS mg_msg_log (
    msg_id      BIGINT PRIMARY KEY,
    stan        BIGINT NOT NULL,                 -- 전문 추적번호
    mti         TEXT NOT NULL,                   -- 전문유형(0200/0210/0800...)
    channel     TEXT NOT NULL,                   -- 채널ID
    direction   TEXT NOT NULL,                   -- IN / OUT
    proc_code   TEXT NOT NULL DEFAULT '000000',  -- 처리코드
    bitmap      TEXT NOT NULL DEFAULT '',        -- 비트맵(hex)
    amount      BIGINT NOT NULL DEFAULT 0,
    pan         TEXT NOT NULL DEFAULT '',        -- (마스킹된) 카드번호
    mac         TEXT NOT NULL DEFAULT '',        -- 메시지 인증코드
    rc          TEXT NOT NULL DEFAULT '00',      -- 응답코드
    raw_msg     TEXT NOT NULL DEFAULT '',        -- 원 전문
    status      TEXT NOT NULL DEFAULT 'R',       -- R=수신, S=송신, A=ACK, N=NACK, C=확인
    biz_date    DATE NOT NULL,
    created_at  TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS ix_mg_msg_log_stan ON mg_msg_log (stan);
CREATE INDEX IF NOT EXISTS ix_mg_msg_log_chan ON mg_msg_log (channel, biz_date);

-- ---------------------------------------------------------------------------
-- 라우팅 룰 (mg_route) - 채널/전문유형 -> 목적지 매핑
-- ---------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS mg_route (
    route_id    BIGINT PRIMARY KEY,
    channel     TEXT NOT NULL,
    mti         TEXT NOT NULL,
    dest        TEXT NOT NULL,                   -- 목적지 서비스/노드
    priority    INTEGER NOT NULL DEFAULT 100,
    active      BOOLEAN NOT NULL DEFAULT true,
    biz_date    DATE NOT NULL,
    created_at  TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS ix_mg_route_lookup ON mg_route (channel, mti, active);

-- ---------------------------------------------------------------------------
-- 채널 (mg_channel) - 세션/사인온 상태
-- ---------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS mg_channel (
    channel     TEXT PRIMARY KEY,
    name        TEXT NOT NULL DEFAULT '',
    status      TEXT NOT NULL DEFAULT 'DOWN',    -- UP / DOWN / SIGNON / SIGNOFF
    session_key TEXT NOT NULL DEFAULT '',
    last_stan   BIGINT NOT NULL DEFAULT 0,
    signon_at   TIMESTAMPTZ,
    updated_at  TIMESTAMPTZ NOT NULL DEFAULT now()
);

-- ---------------------------------------------------------------------------
-- 송수신 큐 (mg_queue) - 재전송 대상 관리
-- ---------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS mg_queue (
    queue_id    BIGINT PRIMARY KEY,
    stan        BIGINT NOT NULL,
    channel     TEXT NOT NULL,
    mti         TEXT NOT NULL DEFAULT '',
    payload     TEXT NOT NULL DEFAULT '',
    status      TEXT NOT NULL DEFAULT 'Q',       -- Q=대기, S=송신, D=완료, F=실패
    retry_cnt   INTEGER NOT NULL DEFAULT 0,
    biz_date    DATE NOT NULL,
    created_at  TIMESTAMPTZ NOT NULL DEFAULT now(),
    updated_at  TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS ix_mg_queue_status ON mg_queue (status, biz_date);

-- ---------------------------------------------------------------------------
-- 채널 일별 통계 (mg_stat) - mg_stat_batch 가 채움
-- ---------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS mg_stat (
    channel     TEXT NOT NULL,
    biz_date    DATE NOT NULL,
    in_cnt      BIGINT NOT NULL DEFAULT 0,
    out_cnt     BIGINT NOT NULL DEFAULT 0,
    err_cnt     BIGINT NOT NULL DEFAULT 0,
    amount_sum  BIGINT NOT NULL DEFAULT 0,
    updated_at  TIMESTAMPTZ NOT NULL DEFAULT now(),
    PRIMARY KEY (channel, biz_date)
);

-- ---------------------------------------------------------------------------
-- Seed: 채널 + 기본 라우팅 룰
-- ---------------------------------------------------------------------------
INSERT INTO mg_channel (channel, name, status) VALUES
    ('CH01', 'VAN 게이트웨이', 'DOWN'),
    ('CH02', '매입사 링크',   'DOWN'),
    ('CH03', '해외 네트워크', 'DOWN')
ON CONFLICT (channel) DO NOTHING;

INSERT INTO mg_route (route_id, channel, mti, dest, priority, active, biz_date) VALUES
    (nextval('mg_route_seq'), 'CH01', '0200', 'ACQUIRE',   10, true, '2026-07-19'),
    (nextval('mg_route_seq'), 'CH01', '0800', 'MG_ECHO',   20, true, '2026-07-19'),
    (nextval('mg_route_seq'), 'CH02', '0200', 'ACQ_EDC',   10, true, '2026-07-19')
ON CONFLICT DO NOTHING;

INSERT INTO mg_seq (seq_name, seq_val) VALUES
    ('SESSION', 0), ('KEYVER', 0)
ON CONFLICT (seq_name) DO NOTHING;
