-- 000038_portal_chat.sql — 门户通用聊天:会话、消息链(哈希完整性)与用户运行时凭据。
-- 模型权限申请审批通过后,系统为该用户开通一把 gateway API Key(加密落库),
-- 门户"通用聊天"页面用这把 Key 直接调用 /v1/chat/completions,用量与审计
-- 均归属到用户自己的 Key,而不是共享一个全局凭据。

CREATE TABLE IF NOT EXISTS gateway.portal_user_runtime_credentials (
    portal_user_id uuid PRIMARY KEY REFERENCES gateway.portal_users(id) ON DELETE CASCADE,
    api_key_id uuid NOT NULL REFERENCES gateway.api_keys(id) ON DELETE CASCADE,
    encrypted_key bytea NOT NULL,
    key_kek_version integer NOT NULL,
    created_at timestamptz NOT NULL DEFAULT clock_timestamp()
);

COMMENT ON TABLE gateway.portal_user_runtime_credentials IS
    'Per-portal-user gateway credential used by the general chat. Plaintext is encrypted with the application KEK and never returned to a browser.';

CREATE TABLE IF NOT EXISTS gateway.portal_chat_sessions (
    id uuid PRIMARY KEY,
    portal_user_id uuid NOT NULL REFERENCES gateway.portal_users(id) ON DELETE CASCADE,
    title varchar(160) NOT NULL DEFAULT '',
    provider_code text NOT NULL DEFAULT '',
    model text NOT NULL CHECK (length(model) BETWEEN 1 AND 512),
    status text NOT NULL DEFAULT 'active' CHECK (status IN ('active', 'archived')),
    busy boolean NOT NULL DEFAULT false,
    busy_token text,
    busy_since timestamptz,
    next_sequence integer NOT NULL DEFAULT 1 CHECK (next_sequence >= 1),
    created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
    updated_at timestamptz NOT NULL DEFAULT clock_timestamp()
);

CREATE INDEX IF NOT EXISTS portal_chat_sessions_user_time_idx
    ON gateway.portal_chat_sessions (portal_user_id, updated_at DESC);

CREATE TABLE IF NOT EXISTS gateway.portal_chat_messages (
    id uuid PRIMARY KEY,
    session_id uuid NOT NULL REFERENCES gateway.portal_chat_sessions(id) ON DELETE CASCADE,
    sequence integer NOT NULL,
    role varchar(16) NOT NULL CHECK (role IN ('user', 'assistant')),
    content text NOT NULL,
    previous_hash varchar(64) NOT NULL,
    message_hash varchar(64) NOT NULL,
    created_at timestamptz NOT NULL DEFAULT clock_timestamp(),
    UNIQUE (session_id, sequence)
);

CREATE INDEX IF NOT EXISTS portal_chat_messages_session_idx
    ON gateway.portal_chat_messages (session_id, sequence);
