Files
tps-dashboard/backend/sql/001_init.sql
T

238 lines
11 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.
-- ============================================================
-- 001_init.sql — 《军事科技》栏目内部工作台 数据库初始化脚本
-- 一次性建完所有核心表骨架(Phase 1-4 全部表)
-- 执行方式: psql -U postgres -d milsci_dev -f 001_init.sql
-- ============================================================
-- 扩展: pgvector(向量检索)
CREATE EXTENSION IF NOT EXISTS vector;
-- ============================================================
-- 1. users — 用户表(Phase 1 用)
-- ============================================================
CREATE TABLE IF NOT EXISTS users (
id SERIAL PRIMARY KEY,
username VARCHAR(50) NOT NULL UNIQUE,
display_name VARCHAR(100) NOT NULL,
password_hash VARCHAR(128) NOT NULL,
-- 角色: zhipianren=制片人/管理员, zebian=责编, biandao=编导
role VARCHAR(20) NOT NULL DEFAULT 'biandao'
CHECK (role IN ('zhipianren', 'zebian', 'biandao')),
profile_text TEXT,
is_active BOOLEAN NOT NULL DEFAULT TRUE,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX idx_users_role ON users (role);
-- ============================================================
-- 2. episodes — 节目期次(Phase 2 用,字段完整按 dev_plan.md 8.1 节)
-- ============================================================
CREATE TABLE IF NOT EXISTS episodes (
id SERIAL PRIMARY KEY,
episode_number INTEGER NOT NULL UNIQUE,
program_name VARCHAR(200) NOT NULL,
air_date DATE NOT NULL,
-- 编导(软引用 + 快照模式)
editor_id INTEGER REFERENCES users(id) ON DELETE SET NULL,
editor_name_snapshot VARCHAR(100) NOT NULL,
-- 收视数据
audience_share NUMERIC(6,4),
audience_rating NUMERIC(6,4),
-- 重播相关
is_rerun BOOLEAN NOT NULL DEFAULT FALSE,
original_episode_id INTEGER REFERENCES episodes(id) ON DELETE SET NULL,
is_time_sensitive BOOLEAN NOT NULL DEFAULT FALSE,
-- 外拍信息
is_outdoor_shoot BOOLEAN NOT NULL DEFAULT FALSE,
outdoor_contact_person VARCHAR(100),
outdoor_contact_info VARCHAR(200),
-- 线索
lead_source VARCHAR(300),
-- 责编备注
notes TEXT,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX idx_episodes_air_date ON episodes (air_date);
CREATE INDEX idx_episodes_editor_id ON episodes (editor_id);
CREATE INDEX idx_episodes_is_rerun ON episodes (is_rerun);
-- ============================================================
-- 3. yearly_targets — 年度收视目标(Phase 2 用,只增不改)
-- ============================================================
CREATE TABLE IF NOT EXISTS yearly_targets (
id SERIAL PRIMARY KEY,
year INTEGER NOT NULL UNIQUE,
base_target NUMERIC(6,4) NOT NULL,
stretch_target NUMERIC(6,4) NOT NULL,
issued_date DATE,
notes TEXT,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
-- ============================================================
-- 4. topics — 选题 / 报题单(Phase 4a 用)
-- ============================================================
CREATE TABLE IF NOT EXISTS topics (
id SERIAL PRIMARY KEY,
title VARCHAR(200) NOT NULL,
-- 内容概要(双段结构: 引子 + 列举)
content_summary TEXT,
-- 编导关联(软引用 + 快照)
editor_id INTEGER REFERENCES users(id) ON DELETE SET NULL,
editor_name_snapshot VARCHAR(100),
-- 选题状态: draft=草稿, submitted=已提交, reviewing=审阅中, approved=通过, rejected=退回
status VARCHAR(20) NOT NULL DEFAULT 'draft'
CHECK (status IN ('draft', 'submitted', 'reviewing', 'approved', 'rejected')),
-- AI 反馈(JSON 格式,含查重/画像/知识库参考等模块结果)
ai_feedback JSONB,
-- 关联的 episodes / knowledge_items id 列表
related_episodes JSONB,
related_knowledge JSONB,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX idx_topics_editor_id ON topics (editor_id);
CREATE INDEX idx_topics_status ON topics (status);
-- ============================================================
-- 5. topic_embeddings — 选题语义向量(Phase 4a 用,pgvector
-- ============================================================
CREATE TABLE IF NOT EXISTS topic_embeddings (
id SERIAL PRIMARY KEY,
topic_id INTEGER NOT NULL REFERENCES topics(id) ON DELETE CASCADE,
embedding vector(1536) NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX idx_topic_embeddings_topic_id ON topic_embeddings (topic_id);
-- pgvector 向量索引(IVFFlat,数据量上去后可用 HNSW
-- CREATE INDEX idx_topic_embeddings_vector ON topic_embeddings USING ivfflat (embedding vector_cosine_ops);
-- ============================================================
-- 6. schedules — 排期(Phase 4b 用)
-- ============================================================
CREATE TABLE IF NOT EXISTS schedules (
id SERIAL PRIMARY KEY,
episode_id INTEGER REFERENCES episodes(id) ON DELETE SET NULL,
planned_air_date DATE NOT NULL,
status VARCHAR(20) NOT NULL DEFAULT 'planned'
CHECK (status IN ('planned', 'confirmed', 'completed', 'cancelled')),
editor_id INTEGER REFERENCES users(id) ON DELETE SET NULL,
notes TEXT,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX idx_schedules_air_date ON schedules (planned_air_date);
-- ============================================================
-- 7. knowledge_items — 知识库条目(Phase 3 用,2.0 兼容预埋)
-- ============================================================
CREATE TABLE IF NOT EXISTS knowledge_items (
id SERIAL PRIMARY KEY,
title VARCHAR(300) NOT NULL,
-- Markdown 格式正文(向 2.0 Karpathy LLM Wiki 形态靠拢)
content_md TEXT,
-- 来源信息
source_type VARCHAR(30) NOT NULL DEFAULT 'manual'
CHECK (source_type IN ('baoti', 'manuscript', 'military_report', 'manual', 'rss')),
source_file_name VARCHAR(300),
source_url VARCHAR(1000),
-- 作者 / 编导
author VARCHAR(100),
publish_date DATE,
-- ⚠️ 2.0 兼容预埋字段(1.0 不用但要建)
tags JSONB DEFAULT '[]'::jsonb,
related_entities JSONB DEFAULT '[]'::jsonb,
related_concepts JSONB DEFAULT '[]'::jsonb,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX idx_knowledge_items_source_type ON knowledge_items (source_type);
CREATE INDEX idx_knowledge_items_tags ON knowledge_items USING gin (tags);
-- ============================================================
-- 8. knowledge_embeddings — 知识库向量(Phase 3 用,pgvector
-- ============================================================
CREATE TABLE IF NOT EXISTS knowledge_embeddings (
id SERIAL PRIMARY KEY,
knowledge_id INTEGER NOT NULL REFERENCES knowledge_items(id) ON DELETE CASCADE,
chunk_index INTEGER NOT NULL DEFAULT 0,
chunk_text TEXT NOT NULL,
embedding vector(1536) NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX idx_knowledge_embeddings_knowledge_id ON knowledge_embeddings (knowledge_id);
-- pgvector 向量索引
-- CREATE INDEX idx_knowledge_embeddings_vector ON knowledge_embeddings USING ivfflat (embedding vector_cosine_ops);
-- ============================================================
-- 9. review_comments — 审片意见(Phase 4b 用)
-- ============================================================
CREATE TABLE IF NOT EXISTS review_comments (
id SERIAL PRIMARY KEY,
episode_id INTEGER NOT NULL REFERENCES episodes(id) ON DELETE CASCADE,
comment_text TEXT NOT NULL,
reviewer VARCHAR(100),
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE INDEX idx_review_comments_episode_id ON review_comments (episode_id);
-- ============================================================
-- 10. shooting_resources — 拍摄资源 / 人脉(Phase 4b 用)
-- ============================================================
CREATE TABLE IF NOT EXISTS shooting_resources (
id SERIAL PRIMARY KEY,
contact_person VARCHAR(100) NOT NULL,
contact_info VARCHAR(200),
organization VARCHAR(200),
-- 资源类型: personnel=人员, location=场地, equipment=设备, other=其他
resource_type VARCHAR(20) DEFAULT 'other'
CHECK (resource_type IN ('personnel', 'location', 'equipment', 'other')),
notes TEXT,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
-- ============================================================
-- 11. radar_items — 热点雷达条目(Phase 4c 用)
-- ============================================================
CREATE TABLE IF NOT EXISTS radar_items (
id SERIAL PRIMARY KEY,
title VARCHAR(300) NOT NULL,
source_url VARCHAR(1000),
source_name VARCHAR(100),
summary TEXT,
-- AI 处理结果
ai_summary TEXT,
style_summary TEXT,
published_at TIMESTAMPTZ,
fetched_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
-- ============================================================
-- 12. radar_user_actions — 编导对热点的操作(Phase 4c 用)
-- ============================================================
CREATE TABLE IF NOT EXISTS radar_user_actions (
id SERIAL PRIMARY KEY,
radar_item_id INTEGER NOT NULL REFERENCES radar_items(id) ON DELETE CASCADE,
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
-- 操作类型: deep_dive=深入了解, bookmark=收藏, ignore=忽略
action_type VARCHAR(20) NOT NULL
CHECK (action_type IN ('deep_dive', 'bookmark', 'ignore')),
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
UNIQUE (radar_item_id, user_id, action_type)
);
-- ============================================================
-- 初始化完成
-- ============================================================