Files
awoooi/apps/api/tests/integration/setup_test_schema.sql
Your Name f09a8f56a9
Some checks failed
CD Pipeline / build-and-deploy (push) Has been cancelled
fix(ci): test_schema 加 P2.1 fusion 欄位 — 解 CI 1162-1172 阻塞
Production PG migration 已上線(commit c58bdd0c),但 CI 用獨立 docker pgvector
test container(pg-test-b5),由 setup_test_schema.sql 初始化 → 無 fusion 欄位
→ test_b5_core_flows.py 整合測試失敗於 composite_score column does not exist。

修法:把 P2.1 ALTER TABLE 加入 setup_test_schema.sql(idempotent IF NOT EXISTS)

新增(對齊 production p2_decision_fusion_columns.sql):
- composite_score REAL
- complexity_tier VARCHAR(16) + CHECK ('low','medium','high','critical')
- decision_fusion_details JSONB

partial index 不需要在 test schema(B5 整合測試不依賴 index)。
DO $$ block 處理 CHECK constraint 因 PG 不支援 ADD CONSTRAINT IF NOT EXISTS。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 14:39:06 +08:00

142 lines
5.4 KiB
SQL
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
-- Integration Test Schema Setup
-- ================================
-- 為 CI 環境的臨時 PostgreSQL 建立測試所需的 schema
-- 使用: psql $TEST_DATABASE_URL -f setup_test_schema.sql
-- 2026-04-10 Claude Sonnet 4.6 Asia/Taipei
CREATE EXTENSION IF NOT EXISTS vector;
DO $$ BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'incidentstatus') THEN
CREATE TYPE incidentstatus AS ENUM ('INVESTIGATING','MITIGATING','RESOLVED','CLOSED','ESCALATED');
END IF;
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'severity') THEN
CREATE TYPE severity AS ENUM ('P0','P1','P2','P3');
END IF;
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'approvalstatus') THEN
CREATE TYPE approvalstatus AS ENUM ('PENDING','APPROVED','REJECTED','EXPIRED','EXECUTION_SUCCESS','EXECUTION_FAILED');
END IF;
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'risklevel') THEN
CREATE TYPE risklevel AS ENUM ('LOW','MEDIUM','HIGH','CRITICAL');
END IF;
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'entrysource') THEN
CREATE TYPE entrysource AS ENUM ('AI_EXTRACTED','HUMAN');
END IF;
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'entrystatus') THEN
CREATE TYPE entrystatus AS ENUM ('DRAFT','REVIEW','APPROVED','ARCHIVED','published');
END IF;
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'entrytype') THEN
CREATE TYPE entrytype AS ENUM ('INCIDENT_CASE','RUNBOOK','BEST_PRACTICE','POSTMORTEM','auto_runbook','anti_pattern');
END IF;
END $$;
CREATE TABLE IF NOT EXISTS incidents (
incident_id VARCHAR(30) PRIMARY KEY,
status incidentstatus NOT NULL DEFAULT 'INVESTIGATING',
severity severity NOT NULL DEFAULT 'P2',
signals JSON DEFAULT '[]',
affected_services JSON DEFAULT '[]',
decision_chain JSON DEFAULT '[]',
proposal_ids JSON DEFAULT '[]',
outcome JSON DEFAULT '{}',
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
resolved_at TIMESTAMPTZ,
closed_at TIMESTAMPTZ,
ttl_days INTEGER DEFAULT 30,
vectorized BOOLEAN DEFAULT false
);
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, -- ADR-093 2026-04-25: 支援群組負數 ID
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
);
-- 2026-04-27 P2.1 DecisionFusion 欄位(對齊 p2_decision_fusion_columns.sql 已上 production
-- IF NOT EXISTS 形式 idempotent重跑安全
ALTER TABLE approval_records
ADD COLUMN IF NOT EXISTS composite_score REAL,
ADD COLUMN IF NOT EXISTS complexity_tier VARCHAR(16),
ADD COLUMN IF NOT EXISTS decision_fusion_details JSONB;
DO $$
BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'chk_complexity_tier') THEN
ALTER TABLE approval_records
ADD CONSTRAINT chk_complexity_tier CHECK (
complexity_tier IS NULL
OR complexity_tier IN ('low','medium','high','critical')
);
END IF;
END $$;
CREATE TABLE IF NOT EXISTS knowledge_entries (
id VARCHAR(36) PRIMARY KEY,
title VARCHAR NOT NULL,
content TEXT,
entry_type entrytype NOT NULL,
category VARCHAR,
tags JSON DEFAULT '[]',
source entrysource NOT NULL DEFAULT 'HUMAN',
status entrystatus NOT NULL DEFAULT 'DRAFT',
related_incident_id VARCHAR,
related_playbook_id VARCHAR,
symptoms_hash VARCHAR,
view_count INTEGER DEFAULT 0,
created_by VARCHAR,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS rag_chunks (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
source TEXT NOT NULL,
source_id TEXT NOT NULL,
title TEXT,
chunk_text TEXT NOT NULL,
embedding vector(768),
metadata JSONB DEFAULT '{}',
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
-- adr091: aider_events schema (2026-04-22 @ Asia/Taipei, 補入 integration test schema)
CREATE TABLE IF NOT EXISTS aider_events (
id BIGSERIAL PRIMARY KEY,
session_id TEXT NOT NULL,
ts TIMESTAMPTZ NOT NULL,
type TEXT NOT NULL,
host TEXT DEFAULT 'ogt-mac',
payload JSONB NOT NULL,
incident_id TEXT,
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
CREATE INDEX IF NOT EXISTS aider_events_session_idx ON aider_events(session_id);
CREATE INDEX IF NOT EXISTS aider_events_type_ts_idx ON aider_events(type, ts DESC);
CREATE INDEX IF NOT EXISTS aider_events_ts_idx ON aider_events(ts DESC);
CREATE INDEX IF NOT EXISTS aider_events_payload_gin ON aider_events USING GIN (payload);