- CREATE TYPE approvalstatus / risklevel(SQLAlchemy native_enum) - approval_records 已在 prod awoooi_prod 建立 - telegram_chat_id BIGINT(支援 -1003711974679) - status approvalstatus enum(非 VARCHAR) - awoooi_migrator 角色需 superuser 才能建,留 backlog Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
88 lines
3.7 KiB
SQL
88 lines
3.7 KiB
SQL
-- ADR-093: Notification Matrix Migration
|
||
-- =========================================
|
||
-- 1. 建立 approval_records 表(BIGINT telegram_chat_id,支援群組負數 ID)
|
||
-- 2. 建立 awoooi_migrator 角色
|
||
-- 2026-04-25 ogt + Claude Sonnet 4.6
|
||
|
||
-- awoooi_migrator 角色(ADR-090b 計畫的實作)
|
||
DO $$
|
||
BEGIN
|
||
IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = 'awoooi_migrator') THEN
|
||
CREATE ROLE awoooi_migrator LOGIN;
|
||
END IF;
|
||
END
|
||
$$;
|
||
|
||
GRANT CONNECT ON DATABASE awoooi_prod TO awoooi_migrator;
|
||
GRANT USAGE ON SCHEMA public TO awoooi_migrator;
|
||
GRANT CREATE ON SCHEMA public TO awoooi_migrator;
|
||
|
||
-- SQLAlchemy native enum types(SQLEnum 預設 native_enum=True)
|
||
DO $$ BEGIN
|
||
CREATE TYPE approvalstatus AS ENUM ('pending','approved','rejected','expired','execution_success','execution_failed');
|
||
EXCEPTION WHEN duplicate_object THEN NULL; END $$;
|
||
|
||
DO $$ BEGIN
|
||
CREATE TYPE risklevel AS ENUM ('low','medium','high','critical');
|
||
EXCEPTION WHEN duplicate_object THEN NULL; END $$;
|
||
|
||
-- approval_records 主表(全新建立,直接用 BIGINT)
|
||
-- 注意:test schema setup_test_schema.sql 同步更新為 BIGINT
|
||
CREATE TABLE IF NOT EXISTS approval_records (
|
||
id VARCHAR(36) PRIMARY KEY,
|
||
action VARCHAR(500) NOT NULL,
|
||
description TEXT NOT NULL,
|
||
status approvalstatus NOT NULL DEFAULT 'pending',
|
||
risk_level risklevel NOT NULL,
|
||
required_signatures INTEGER DEFAULT 1,
|
||
current_signatures INTEGER DEFAULT 0,
|
||
signatures JSON DEFAULT '[]',
|
||
blast_radius JSON DEFAULT '{}',
|
||
dry_run_checks JSON DEFAULT '[]',
|
||
requested_by VARCHAR,
|
||
rejection_reason TEXT,
|
||
extra_metadata JSON DEFAULT '{}',
|
||
fingerprint VARCHAR,
|
||
hit_count INTEGER DEFAULT 1,
|
||
last_seen_at TIMESTAMPTZ,
|
||
approval_level VARCHAR DEFAULT 'standard',
|
||
approval_votes JSONB,
|
||
required_votes INTEGER DEFAULT 1,
|
||
incident_id VARCHAR,
|
||
telegram_message_id INTEGER,
|
||
telegram_chat_id BIGINT, -- 支援群組負數 ID(原 INTEGER 會 int32 overflow)
|
||
matched_playbook_id VARCHAR(36),
|
||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||
expires_at TIMESTAMPTZ,
|
||
resolved_at TIMESTAMPTZ
|
||
);
|
||
|
||
-- 若表已存在(舊環境),執行欄位型別升級
|
||
DO $$
|
||
BEGIN
|
||
IF EXISTS (
|
||
SELECT 1 FROM information_schema.columns
|
||
WHERE table_name = 'approval_records'
|
||
AND column_name = 'telegram_chat_id'
|
||
AND data_type = 'integer'
|
||
) THEN
|
||
ALTER TABLE approval_records
|
||
ALTER COLUMN telegram_chat_id TYPE BIGINT;
|
||
RAISE NOTICE 'approval_records.telegram_chat_id upgraded INTEGER → BIGINT';
|
||
END IF;
|
||
END
|
||
$$;
|
||
|
||
-- 索引
|
||
CREATE INDEX IF NOT EXISTS idx_approval_records_status ON approval_records(status);
|
||
CREATE INDEX IF NOT EXISTS idx_approval_records_incident ON approval_records(incident_id);
|
||
CREATE INDEX IF NOT EXISTS idx_approval_records_fingerprint ON approval_records(fingerprint);
|
||
CREATE INDEX IF NOT EXISTS idx_approval_records_playbook ON approval_records(matched_playbook_id);
|
||
|
||
GRANT SELECT, INSERT, UPDATE, DELETE ON approval_records TO awoooi;
|
||
GRANT SELECT, INSERT, UPDATE ON approval_records TO awoooi_migrator;
|
||
|
||
COMMENT ON TABLE approval_records IS 'ADR-093 2026-04-25: telegram_chat_id 改 BIGINT 支援群組負數 ID';
|
||
COMMENT ON COLUMN approval_records.telegram_chat_id IS 'BIGINT: 支援 SRE 群組 ID (-1003711974679) 不 overflow';
|