-- =============================================================
-- SNP Connection Monitoring - 테이블 생성 스크립트
-- 스키마: common
-- =============================================================

CREATE SCHEMA IF NOT EXISTS common;
SET search_path TO common;

-- -----------------------------------------------------------
-- 1. snp_tenant (테넌트)
-- -----------------------------------------------------------
CREATE TABLE IF NOT EXISTS snp_tenant (
    tenant_id       BIGSERIAL       PRIMARY KEY,
    tenant_code     VARCHAR(50)     NOT NULL UNIQUE,
    tenant_name     VARCHAR(200)    NOT NULL,
    description     TEXT,
    is_active       BOOLEAN         NOT NULL DEFAULT TRUE,
    created_at      TIMESTAMP       NOT NULL DEFAULT NOW(),
    updated_at      TIMESTAMP       NOT NULL DEFAULT NOW()
);

CREATE INDEX idx_snp_tenant_code ON snp_tenant (tenant_code);
CREATE INDEX idx_snp_tenant_active ON snp_tenant (is_active);

-- -----------------------------------------------------------
-- 2. snp_user (사용자)
-- -----------------------------------------------------------
CREATE TABLE IF NOT EXISTS snp_user (
    user_id         BIGSERIAL       PRIMARY KEY,
    tenant_id       BIGINT          REFERENCES snp_tenant(tenant_id),
    login_id        VARCHAR(100)    NOT NULL UNIQUE,
    password_hash   VARCHAR(255)    NOT NULL,
    user_name       VARCHAR(100)    NOT NULL,
    email           VARCHAR(200),
    role            VARCHAR(20)     NOT NULL DEFAULT 'USER',
    is_active       BOOLEAN         NOT NULL DEFAULT TRUE,
    last_login_at   TIMESTAMP,
    created_at      TIMESTAMP       NOT NULL DEFAULT NOW(),
    updated_at      TIMESTAMP       NOT NULL DEFAULT NOW()
);

CREATE INDEX idx_snp_user_login_id ON snp_user (login_id);
CREATE INDEX idx_snp_user_tenant ON snp_user (tenant_id);
CREATE INDEX idx_snp_user_role ON snp_user (role);

-- -----------------------------------------------------------
-- 3. snp_service (서비스)
-- -----------------------------------------------------------
CREATE TABLE IF NOT EXISTS snp_service (
    service_id          BIGSERIAL       PRIMARY KEY,
    service_code        VARCHAR(50)     NOT NULL UNIQUE,
    service_name        VARCHAR(200)    NOT NULL,
    service_url         VARCHAR(500),
    description         TEXT,
    health_check_url    VARCHAR(500),
    health_check_interval INTEGER       NOT NULL DEFAULT 30,
    health_status       VARCHAR(10)     NOT NULL DEFAULT 'UNKNOWN',
    health_checked_at   TIMESTAMP,
    health_response_time INTEGER,
    is_active           BOOLEAN         NOT NULL DEFAULT TRUE,
    created_at          TIMESTAMP       NOT NULL DEFAULT NOW(),
    updated_at          TIMESTAMP       NOT NULL DEFAULT NOW()
);

CREATE INDEX idx_snp_service_code ON snp_service (service_code);
CREATE INDEX idx_snp_service_status ON snp_service (health_status);
CREATE INDEX idx_snp_service_active ON snp_service (is_active);

-- -----------------------------------------------------------
-- 4. snp_service_health_log (서비스 헬스 로그)
-- -----------------------------------------------------------
CREATE TABLE IF NOT EXISTS snp_service_health_log (
    log_id          BIGSERIAL       PRIMARY KEY,
    service_id      BIGINT          NOT NULL REFERENCES snp_service(service_id),
    previous_status VARCHAR(10),
    current_status  VARCHAR(10)     NOT NULL,
    response_time   INTEGER,
    error_message   TEXT,
    checked_at      TIMESTAMP       NOT NULL DEFAULT NOW()
);

CREATE INDEX idx_snp_health_log_service ON snp_service_health_log (service_id);
CREATE INDEX idx_snp_health_log_checked ON snp_service_health_log (checked_at);

-- -----------------------------------------------------------
-- 5. snp_service_api (서비스 API)
-- -----------------------------------------------------------
CREATE TABLE IF NOT EXISTS snp_service_api (
    api_id          BIGSERIAL       PRIMARY KEY,
    service_id      BIGINT          NOT NULL REFERENCES snp_service(service_id),
    api_path        VARCHAR(500)    NOT NULL,
    api_method      VARCHAR(10)     NOT NULL,
    api_name        VARCHAR(200)    NOT NULL,
    description     TEXT,
    is_active       BOOLEAN         NOT NULL DEFAULT TRUE,
    created_at      TIMESTAMP       NOT NULL DEFAULT NOW(),
    updated_at      TIMESTAMP       NOT NULL DEFAULT NOW(),
    CONSTRAINT uq_service_api UNIQUE (service_id, api_path, api_method)
);

CREATE INDEX idx_snp_service_api_service ON snp_service_api (service_id);

-- -----------------------------------------------------------
-- 6. snp_api_key (API 키)
-- -----------------------------------------------------------
CREATE TABLE IF NOT EXISTS snp_api_key (
    api_key_id      BIGSERIAL       PRIMARY KEY,
    user_id         BIGINT          NOT NULL REFERENCES snp_user(user_id),
    api_key         VARCHAR(128)    NOT NULL UNIQUE,
    api_key_prefix  VARCHAR(10),
    key_name        VARCHAR(200)    NOT NULL,
    status          VARCHAR(20)     NOT NULL DEFAULT 'PENDING',
    approved_by     BIGINT          REFERENCES snp_user(user_id),
    approved_at     TIMESTAMP,
    expires_at      TIMESTAMP,
    last_used_at    TIMESTAMP,
    created_at      TIMESTAMP       NOT NULL DEFAULT NOW(),
    updated_at      TIMESTAMP       NOT NULL DEFAULT NOW()
);

CREATE INDEX idx_snp_api_key_user ON snp_api_key (user_id);
CREATE INDEX idx_snp_api_key_key ON snp_api_key (api_key);
CREATE INDEX idx_snp_api_key_status ON snp_api_key (status);

-- -----------------------------------------------------------
-- 7. snp_api_permission (API 권한)
-- -----------------------------------------------------------
CREATE TABLE IF NOT EXISTS snp_api_permission (
    permission_id   BIGSERIAL       PRIMARY KEY,
    api_key_id      BIGINT          NOT NULL REFERENCES snp_api_key(api_key_id),
    api_id          BIGINT          NOT NULL REFERENCES snp_service_api(api_id),
    is_active       BOOLEAN         NOT NULL DEFAULT TRUE,
    granted_by      BIGINT,
    granted_at      TIMESTAMP       NOT NULL DEFAULT NOW(),
    revoked_at      TIMESTAMP,
    CONSTRAINT uq_api_permission UNIQUE (api_key_id, api_id)
);

CREATE INDEX idx_snp_api_permission_key ON snp_api_permission (api_key_id);
CREATE INDEX idx_snp_api_permission_api ON snp_api_permission (api_id);

-- -----------------------------------------------------------
-- 8. snp_api_request_log (API 요청 로그)
-- -----------------------------------------------------------
CREATE TABLE IF NOT EXISTS snp_api_request_log (
    log_id          BIGSERIAL       PRIMARY KEY,
    request_url     VARCHAR(2000),
    request_params  TEXT,
    request_method  VARCHAR(10),
    request_status  VARCHAR(20),
    request_headers TEXT,
    request_ip      VARCHAR(45),
    service_id      BIGINT          REFERENCES snp_service(service_id),
    user_id         BIGINT          REFERENCES snp_user(user_id),
    api_key_id      BIGINT          REFERENCES snp_api_key(api_key_id),
    response_size   BIGINT,
    response_time   INTEGER,
    response_status INTEGER,
    error_message   TEXT,
    requested_at    TIMESTAMP       NOT NULL DEFAULT NOW(),
    tenant_id       BIGINT          REFERENCES snp_tenant(tenant_id)
);

CREATE INDEX idx_snp_request_log_service ON snp_api_request_log (service_id);
CREATE INDEX idx_snp_request_log_user ON snp_api_request_log (user_id);
CREATE INDEX idx_snp_request_log_requested ON snp_api_request_log (requested_at);
CREATE INDEX idx_snp_request_log_tenant ON snp_api_request_log (tenant_id);

-- 대시보드 통계 쿼리 최적화 인덱스
CREATE INDEX idx_snp_request_log_daily_stats ON snp_api_request_log (requested_at, request_status);
CREATE INDEX idx_snp_request_log_daily_user ON snp_api_request_log (requested_at, user_id);
CREATE INDEX idx_snp_request_log_svc_stats ON snp_api_request_log (requested_at, service_id, request_status);
CREATE INDEX idx_snp_request_log_top_api ON snp_api_request_log (requested_at, request_url, request_method);
-- Gateway API Key 인증 인덱스
CREATE INDEX idx_snp_api_key_prefix ON snp_api_key (api_key_prefix);

-- -----------------------------------------------------------
-- 9. snp_api_key_request (API 키 발급 요청)
-- -----------------------------------------------------------
CREATE TABLE IF NOT EXISTS snp_api_key_request (
    request_id      BIGSERIAL       PRIMARY KEY,
    user_id         BIGINT          NOT NULL REFERENCES snp_user(user_id),
    key_name        VARCHAR(200)    NOT NULL,
    purpose         TEXT,
    requested_apis  TEXT,
    status          VARCHAR(20)     NOT NULL DEFAULT 'PENDING',
    reviewed_by     BIGINT          REFERENCES snp_user(user_id),
    reviewed_at     TIMESTAMP,
    review_comment  TEXT,
    created_at      TIMESTAMP       NOT NULL DEFAULT NOW(),
    updated_at      TIMESTAMP       NOT NULL DEFAULT NOW()
);

CREATE INDEX idx_snp_key_request_user ON snp_api_key_request (user_id);
CREATE INDEX idx_snp_key_request_status ON snp_api_key_request (status);
