PRAGMA journal_mode = WAL; PRAGMA foreign_keys = ON; -- 文章表:公众号文章 + 视频号ASR转写文本 CREATE TABLE IF NOT EXISTS articles ( id INTEGER PRIMARY KEY AUTOINCREMENT, canonical_url TEXT NOT NULL UNIQUE, source TEXT NOT NULL DEFAULT 'hongcan', -- 来源平台 source_name TEXT, -- 公众号名称 / 视频号名称 source_type TEXT NOT NULL DEFAULT '公众号', -- 公众号 | 视频号 title TEXT, author TEXT, published_at TEXT, summary TEXT, content TEXT, content_hash TEXT, category TEXT, -- 赛道:茶饮咖啡/快餐/火锅/正餐/烘焙/供应链/综合 crawl_status TEXT NOT NULL DEFAULT 'pending', -- pending | success | failed retry_count INTEGER NOT NULL DEFAULT 0, last_error TEXT, media_url TEXT, -- 原始视频文件路径(视频号专用) discovered_at TEXT NOT NULL, crawled_at TEXT, updated_at TEXT NOT NULL ); CREATE INDEX IF NOT EXISTS idx_articles_published_at ON articles(published_at); CREATE INDEX IF NOT EXISTS idx_articles_crawl_status ON articles(crawl_status, retry_count); CREATE INDEX IF NOT EXISTS idx_articles_source_type ON articles(source_type); CREATE INDEX IF NOT EXISTS idx_articles_category ON articles(category); -- 采集运行记录 CREATE TABLE IF NOT EXISTS crawl_runs ( id INTEGER PRIMARY KEY AUTOINCREMENT, started_at TEXT NOT NULL, finished_at TEXT, status TEXT NOT NULL DEFAULT 'running', source_type TEXT NOT NULL DEFAULT '公众号', discovered_count INTEGER NOT NULL DEFAULT 0, inserted_count INTEGER NOT NULL DEFAULT 0, updated_count INTEGER NOT NULL DEFAULT 0, failed_count INTEGER NOT NULL DEFAULT 0, message TEXT ); -- AI 结构化分析结果 CREATE TABLE IF NOT EXISTS ai_analyses ( id INTEGER PRIMARY KEY AUTOINCREMENT, article_id INTEGER NOT NULL, model TEXT NOT NULL, analysis_type TEXT NOT NULL DEFAULT 'editorial', result_json TEXT NOT NULL, -- 完整结构化JSON content_hash TEXT, created_at TEXT NOT NULL, updated_at TEXT NOT NULL, UNIQUE(article_id, model, analysis_type), FOREIGN KEY(article_id) REFERENCES articles(id) ON DELETE CASCADE ); CREATE INDEX IF NOT EXISTS idx_ai_analyses_article ON ai_analyses(article_id, updated_at); -- 向量嵌入表(用于RAG检索) CREATE TABLE IF NOT EXISTS embeddings ( id INTEGER PRIMARY KEY AUTOINCREMENT, article_id INTEGER NOT NULL, chunk_index INTEGER NOT NULL DEFAULT 0, chunk_text TEXT NOT NULL, embedding BLOB, -- JSON序列化的float数组 model TEXT NOT NULL, content_hash TEXT, created_at TEXT NOT NULL, FOREIGN KEY(article_id) REFERENCES articles(id) ON DELETE CASCADE, UNIQUE(article_id, chunk_index, model) ); CREATE INDEX IF NOT EXISTS idx_embeddings_article ON embeddings(article_id); -- 品牌实体库 CREATE TABLE IF NOT EXISTS brands ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL UNIQUE, category TEXT, stores INTEGER DEFAULT 0, avg_price INTEGER DEFAULT 0, model TEXT, -- 直营 | 加盟 | 直营+加盟 city_tier_json TEXT DEFAULT '[]', -- [{tier, pct}] trend_json TEXT DEFAULT '[]', -- 近12个月门店数 latest_news TEXT, news_date TEXT, growth REAL DEFAULT 0, created_at TEXT NOT NULL, updated_at TEXT NOT NULL ); -- 行业信号(跨文章聚合) CREATE TABLE IF NOT EXISTS industry_signals ( id INTEGER PRIMARY KEY AUTOINCREMENT, signal_date TEXT NOT NULL, title TEXT NOT NULL, summary TEXT NOT NULL, trend TEXT NOT NULL DEFAULT 'emerging', confidence REAL NOT NULL DEFAULT 0.5, implications_json TEXT NOT NULL DEFAULT '[]', article_ids_json TEXT NOT NULL DEFAULT '[]', tags_json TEXT NOT NULL DEFAULT '[]', model TEXT NOT NULL, created_at TEXT NOT NULL, updated_at TEXT NOT NULL, UNIQUE(signal_date, title) ); CREATE INDEX IF NOT EXISTS idx_industry_signals_date ON industry_signals(signal_date DESC, confidence DESC); -- 报告表 CREATE TABLE IF NOT EXISTS reports ( id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT NOT NULL, report_date TEXT NOT NULL, period TEXT, highlights_json TEXT NOT NULL DEFAULT '[]', sections_json TEXT NOT NULL DEFAULT '[]', created_at TEXT NOT NULL ); CREATE INDEX IF NOT EXISTS idx_reports_date ON reports(report_date DESC); CREATE TABLE IF NOT EXISTS pipeline_runs ( id INTEGER PRIMARY KEY AUTOINCREMENT, run_type TEXT NOT NULL, started_at TEXT NOT NULL, finished_at TEXT, status TEXT NOT NULL DEFAULT 'running', current_step TEXT, steps_json TEXT NOT NULL DEFAULT '{}', error_message TEXT, created_at TEXT NOT NULL ); CREATE INDEX IF NOT EXISTS idx_pipeline_runs_started ON pipeline_runs(started_at DESC); -- 信源配置表(公众号 + 视频号) CREATE TABLE IF NOT EXISTS sources ( id INTEGER PRIMARY KEY AUTOINCREMENT, source_type TEXT NOT NULL DEFAULT '公众号', -- 公众号 | 视频号 name TEXT NOT NULL, -- 信源名称(公众号名称/视频号账号名) finder TEXT, -- 视频号 finder ID(视频号专用) list_url TEXT, -- 列表页URL(公众号专用) download_dir TEXT, -- 下载目录(视频号专用) enabled INTEGER NOT NULL DEFAULT 1, -- 是否启用 1/0 last_crawled_at TEXT, -- 最近采集时间 created_at TEXT NOT NULL, updated_at TEXT NOT NULL, UNIQUE(source_type, name) );