forked from niuniu/llm-intelligence
feat(intraday): add discovery and verification watch pipeline
This commit is contained in:
106
db/migrations/017_intraday_news_candidates.sql
Normal file
106
db/migrations/017_intraday_news_candidates.sql
Normal file
@@ -0,0 +1,106 @@
|
||||
-- 日内新闻候选与验证持久化结构
|
||||
|
||||
CREATE TABLE IF NOT EXISTS intraday_news_candidate (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
candidate_date DATE NOT NULL,
|
||||
discovered_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
event_type TEXT NOT NULL,
|
||||
provider_name TEXT NOT NULL,
|
||||
model_name TEXT,
|
||||
provider_country TEXT,
|
||||
title TEXT NOT NULL,
|
||||
summary TEXT,
|
||||
candidate_urls JSONB NOT NULL DEFAULT '[]'::jsonb,
|
||||
discovery_source TEXT NOT NULL,
|
||||
discovery_query TEXT,
|
||||
discovery_evidence JSONB NOT NULL DEFAULT '{}'::jsonb,
|
||||
normalized_key TEXT NOT NULL,
|
||||
status TEXT NOT NULL DEFAULT 'candidate',
|
||||
verification_confidence TEXT NOT NULL DEFAULT 'candidate',
|
||||
verification_notes TEXT,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (
|
||||
SELECT 1 FROM pg_constraint WHERE conname = 'chk_intraday_news_candidate_status'
|
||||
) THEN
|
||||
ALTER TABLE intraday_news_candidate
|
||||
ADD CONSTRAINT chk_intraday_news_candidate_status
|
||||
CHECK (status IN ('candidate', 'verifying', 'verified', 'rejected', 'stale'));
|
||||
END IF;
|
||||
|
||||
IF NOT EXISTS (
|
||||
SELECT 1 FROM pg_constraint WHERE conname = 'chk_intraday_news_candidate_confidence'
|
||||
) THEN
|
||||
ALTER TABLE intraday_news_candidate
|
||||
ADD CONSTRAINT chk_intraday_news_candidate_confidence
|
||||
CHECK (verification_confidence IN ('candidate', 'secondary_confirmed', 'official_confirmed'));
|
||||
END IF;
|
||||
END
|
||||
$$;
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_intraday_news_candidate_normalized_key
|
||||
ON intraday_news_candidate(normalized_key);
|
||||
CREATE INDEX IF NOT EXISTS idx_intraday_news_candidate_date
|
||||
ON intraday_news_candidate(candidate_date DESC, discovered_at DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_intraday_news_candidate_status
|
||||
ON intraday_news_candidate(status);
|
||||
CREATE INDEX IF NOT EXISTS idx_intraday_news_candidate_provider_event
|
||||
ON intraday_news_candidate(provider_name, event_type, candidate_date DESC);
|
||||
|
||||
COMMENT ON TABLE intraday_news_candidate IS '搜索引擎与 LLM 发现的日内新闻候选池,尚未直接进入正式日报事实层';
|
||||
COMMENT ON COLUMN intraday_news_candidate.candidate_urls IS '候选来源 URL 数组,按发现层输出原样保留';
|
||||
COMMENT ON COLUMN intraday_news_candidate.discovery_evidence IS '发现阶段原始证据 JSONB,例如搜索命中、LLM 归纳结果';
|
||||
COMMENT ON COLUMN intraday_news_candidate.normalized_key IS '同日同事件的去重键,避免重复发现候选';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS intraday_news_verification (
|
||||
id BIGSERIAL PRIMARY KEY,
|
||||
candidate_id BIGINT NOT NULL REFERENCES intraday_news_candidate(id) ON DELETE CASCADE,
|
||||
verified_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
verifier_source TEXT NOT NULL,
|
||||
verifier_url TEXT,
|
||||
verifier_status TEXT NOT NULL,
|
||||
extracted_facts JSONB NOT NULL DEFAULT '{}'::jsonb,
|
||||
notes TEXT,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (
|
||||
SELECT 1 FROM pg_constraint WHERE conname = 'chk_intraday_news_verification_status'
|
||||
) THEN
|
||||
ALTER TABLE intraday_news_verification
|
||||
ADD CONSTRAINT chk_intraday_news_verification_status
|
||||
CHECK (verifier_status IN ('matched', 'contradicted', 'insufficient', 'error'));
|
||||
END IF;
|
||||
END
|
||||
$$;
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_intraday_news_verification_candidate_verified_at
|
||||
ON intraday_news_verification(candidate_id, verified_at DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_intraday_news_verification_source
|
||||
ON intraday_news_verification(verifier_source);
|
||||
CREATE INDEX IF NOT EXISTS idx_intraday_news_verification_status
|
||||
ON intraday_news_verification(verifier_status);
|
||||
|
||||
COMMENT ON TABLE intraday_news_verification IS '日内新闻候选的验证轨迹,记录验证来源、状态和提取事实';
|
||||
COMMENT ON COLUMN intraday_news_verification.extracted_facts IS '验证阶段提取出的结构化事实 JSONB';
|
||||
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM pg_trigger
|
||||
WHERE tgname = 'intraday_news_candidate_updated_at'
|
||||
) THEN
|
||||
CREATE TRIGGER intraday_news_candidate_updated_at
|
||||
BEFORE UPDATE ON intraday_news_candidate
|
||||
FOR EACH ROW
|
||||
EXECUTE FUNCTION update_updated_at_column();
|
||||
END IF;
|
||||
END
|
||||
$$;
|
||||
Reference in New Issue
Block a user