-- V85: 외부 연동(펌뱅킹/SMS·카카오) 호출 감사 이력
--
-- 목적: BankTransferAdapter / MessageAdapter 모든 호출을 자동 영속화.
-- 운영 감사·장애 추적·외부 SDK 통합 검증에 사용. AOP(@Around)가 INSERT.
-- PII 는 요약 필드에 어댑터에서 이미 마스킹된 값만 들어간다 (계좌·전화 뒤 4자리만).

CREATE TABLE IF NOT EXISTS external_call_log (
    log_id           BIGSERIAL    PRIMARY KEY,
    call_type        VARCHAR(20)  NOT NULL,                         -- BANK / MESSAGE
    adapter_class    VARCHAR(200) NOT NULL,                         -- 실제 호출된 구현체 (Mock/Kftc/Toast)
    method_name      VARCHAR(50)  NOT NULL,                         -- requestTransfer / queryStatus / send
    target_ref_type  VARCHAR(30),                                   -- WITHDRAW / APPROVAL 등 (가능 시)
    target_ref_id    BIGINT,                                        -- withdrawRequestId / refId 등
    request_summary  TEXT,                                          -- 요청 요약 (마스킹된 JSON 한 줄)
    response_summary TEXT,                                          -- 응답 요약
    result_code      VARCHAR(20),                                   -- 외부 응답 코드 (정상 시)
    result_message   TEXT,
    success          BOOLEAN      NOT NULL DEFAULT TRUE,
    duration_ms      INTEGER,                                       -- 호출 소요 시간 (ms)
    error_class      VARCHAR(200),                                  -- 예외 발생 시 클래스명
    error_message    TEXT,                                          -- 예외 메시지
    called_at        TIMESTAMP    NOT NULL DEFAULT CURRENT_TIMESTAMP,
    created_by       BIGINT                                         -- 시도자 (가능 시)
);

COMMENT ON TABLE  external_call_log              IS '외부 연동 호출 감사 이력 (AOP 자동 영속화)';
COMMENT ON COLUMN external_call_log.call_type    IS 'BANK / MESSAGE';
COMMENT ON COLUMN external_call_log.adapter_class IS '실제 호출된 어댑터 클래스 (Mock/Kftc/Toast)';
COMMENT ON COLUMN external_call_log.method_name  IS 'requestTransfer / queryStatus / send';
COMMENT ON COLUMN external_call_log.success      IS 'true=정상응답, false=예외/실패';

CREATE INDEX IF NOT EXISTS idx_ecl_called_at_desc
    ON external_call_log(called_at DESC);

CREATE INDEX IF NOT EXISTS idx_ecl_type_called_at
    ON external_call_log(call_type, called_at DESC);

CREATE INDEX IF NOT EXISTS idx_ecl_target
    ON external_call_log(target_ref_type, target_ref_id)
    WHERE target_ref_type IS NOT NULL;

CREATE INDEX IF NOT EXISTS idx_ecl_failures
    ON external_call_log(called_at DESC)
    WHERE success = FALSE;

-- ============================================================
-- 메뉴 등록 (시스템 그룹 하위)
-- ============================================================
INSERT INTO menu (menu_code, menu_name, menu_type, menu_path, component_path, menu_icon,
                  menu_level, sort_order, is_visible, is_active, parent_menu_id, description)
SELECT
    'SYSTEM_EXTERNAL_CALL',
    '외부연동 호출이력',
    'PAGE',
    '/system/external-call-log',
    'system/ExternalCallLogList',
    'api',
    2,
    20,
    'Y',
    'Y',
    (SELECT menu_id FROM menu WHERE menu_code = 'GRP_SYSTEM'),
    '펌뱅킹/SMS·카카오 어댑터 호출 감사 이력 (AOP 자동 영속화)'
WHERE EXISTS (SELECT 1 FROM menu WHERE menu_code = 'GRP_SYSTEM')
ON CONFLICT (menu_code) DO NOTHING;

-- ============================================================
-- 권한 정의 (READ 만 — 감사 로그는 수동 등록 없음)
-- ============================================================
INSERT INTO menu_permission (menu_id, perm_code, perm_name, sort_order)
SELECT menu_id, 'READ', '조회', 1 FROM menu WHERE menu_code = 'SYSTEM_EXTERNAL_CALL'
ON CONFLICT (menu_id, perm_code) DO NOTHING;

-- ============================================================
-- 역할 부여 (SUPER_ADMIN / ADMIN)
-- ============================================================
INSERT INTO role_menu_permission (role_id, menu_id, perm_code, is_granted)
SELECT r.role_id, m.menu_id, p.perm_code, 'Y'
  FROM role r
  CROSS JOIN menu m
  JOIN menu_permission p ON p.menu_id = m.menu_id
 WHERE r.role_code IN ('SUPER_ADMIN', 'ADMIN')
   AND m.menu_code = 'SYSTEM_EXTERNAL_CALL'
   AND p.perm_code = 'READ'
ON CONFLICT (role_id, menu_id, perm_code) DO NOTHING;
