Files
awoooi/apps/api/tests/integration/setup_test_schema.sql
Your Name e24c8ea051
Some checks failed
CD Pipeline / tests (push) Has been cancelled
CD Pipeline / build-and-deploy (push) Has been cancelled
CD Pipeline / post-deploy-checks (push) Has been cancelled
Code Review / ai-code-review (push) Has been cancelled
fix(ci): align B5 schema with tenant isolation
2026-05-05 15:00:07 +08:00

173 lines
6.9 KiB
SQL
Raw Permalink 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','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 $$;
-- 2026-04-27 P3.2.2 — AI Provider 版本歷史表(對齊 p3_2_provider_version_history.sql
CREATE TABLE IF NOT EXISTS ai_provider_version_history (
id SERIAL PRIMARY KEY,
provider VARCHAR(40) NOT NULL,
model VARCHAR(100) NOT NULL,
version VARCHAR(200),
digest VARCHAR(80),
captured_at TIMESTAMPTZ NOT NULL DEFAULT now(),
prev_version VARCHAR(200),
changed BOOLEAN NOT NULL DEFAULT FALSE
);
CREATE TABLE IF NOT EXISTS knowledge_entries (
id VARCHAR(36) PRIMARY KEY,
project_id VARCHAR(64) NOT NULL DEFAULT 'awoooi',
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,
-- 2026-04-29 ogt + Claude Opus 4.7: M4 KMWriter 反查鏈 + 冪等補欄
-- 解 CD #1115-1118 全 failurecolumn "related_approval_id" does not exist
-- 對應 commit c22e5f33 KMWriter ORM 加的欄位
related_approval_id VARCHAR(64),
path_type VARCHAR(50),
view_count INTEGER DEFAULT 0,
created_by VARCHAR,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
-- 2026-05-05 AwoooP Phase 2 tenant isolation: align integration schema with KnowledgeEntryRecord.project_id.
ALTER TABLE knowledge_entries
ADD COLUMN IF NOT EXISTS project_id VARCHAR(64) NOT NULL DEFAULT 'awoooi';
CREATE INDEX IF NOT EXISTS ix_knowledge_entries_project_id
ON knowledge_entries(project_id);
-- M3 冪等 unique index (incident_id + path_type)
CREATE UNIQUE INDEX IF NOT EXISTS uix_knowledge_incident_path
ON knowledge_entries(related_incident_id, path_type)
WHERE related_incident_id IS NOT NULL AND path_type IS NOT NULL;
-- M4 反查鏈 partial index
CREATE INDEX IF NOT EXISTS ix_knowledge_related_approval
ON knowledge_entries(related_approval_id)
WHERE related_approval_id IS NOT NULL;
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);