docs: 文档重构 — 清理 AI agent 残留,整合 docs/ 目录结构
- 删除 11 个残留文件: continuation.md, init_plan.md, reasonix.toml, djapi/continuation.md, djapi/.serena/, djapi/.claude/, djapi/.mcp.json, .claude/skills/, docs/usage.html, docs/db_schema.md, docs/report_db_design.md - 7 个 CLAUDE-*.md 移入 docs/ 并重命名去 CLAUDE- 前缀 - 新增 4 个文档: architecture.md, development.md, api.md, deployment.md - 重写 usage.md, README.md - 修复所有过时引用和交叉链接
This commit is contained in:
@@ -0,0 +1,129 @@
|
||||
# 日报结构化入库:数据库表结构与数据契约
|
||||
|
||||
> 版本:v1.1 | 2026-08-06
|
||||
> 变更(v1.0 → v1.1):新增 §3.1 stats 口径说明,修正 §3 中 pipeline "M1→M6" 的过时描述(实际 key 为 raw_total/raw_by_source/proc 等)。
|
||||
> 用途:供 API / 前端对接读取日报数据。表位于 MySQL `myquant` 库,表前缀 `news_`。
|
||||
> 连接:`192.168.1.10:13306`(pi 上 autossh 隧道 → doorcome.cn:3306 MariaDB 10.11),用户 `myquant`(密码在服务器 `.env` 的 `NEWS_DB_PASSWORD`)。
|
||||
|
||||
---
|
||||
|
||||
## 1. 表结构
|
||||
|
||||
### 1.1 news_report(日报主表,一行 = 一份日报)
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| id | BIGINT UNSIGNED PK | 自增主键 |
|
||||
| report_date | DATE | 日报日期 |
|
||||
| report_type | VARCHAR(16) | `finance`=A 股日报 / `intl`=国际财经日报 |
|
||||
| file_name | VARCHAR(160) | 历史文件源文件名;**新生成日报为空字符串 `""`** |
|
||||
| generated_at | DATETIME | 生成时间 |
|
||||
| ai_summary | TEXT | AI 摘要全文(含换行,按条目分行) |
|
||||
| stats | JSON | 数据总览统计快照(见第 3 节),可为 NULL |
|
||||
| created_at | DATETIME | 入库时间 |
|
||||
|
||||
唯一键:`(report_date, report_type, file_name)` —— 历史同一天多次生成(intl 一日 3 次)保留多行;新生成日报 `file_name=''` 每天每类型仅一行,重复生成覆盖。
|
||||
|
||||
### 1.2 news_event(日报事件明细,一行 = 一条事件)
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| id | BIGINT UNSIGNED PK | 自增主键 |
|
||||
| report_id | BIGINT UNSIGNED | FK → news_report.id |
|
||||
| section | VARCHAR(16) | 板块:`xwlb`=新闻联播 / `news`=财经新闻 / `cninfo`=公告调研 / `intl`=国际重要事件 |
|
||||
| rank | INT | 板块内序号(1 起) |
|
||||
| importance | INT NULL | 重要度 1-5 |
|
||||
| event_type | VARCHAR(64) NULL | 事件类型(如 宏观经济/地缘政治/新闻联播/公告) |
|
||||
| title | VARCHAR(512) | 标题 |
|
||||
| summary | TEXT NULL | 摘要/正文 |
|
||||
| sentiment | VARCHAR(8) NULL | `positive` / `negative` / `neutral` |
|
||||
| source | VARCHAR(64) NULL | 来源(如 `cls`、`investinglive.com`) |
|
||||
| sources | TEXT NULL | **该新闻全部来源**,JSON 数组字符串(如 `["yicai","stcn"]`);无多源/历史数据可为 `null` |
|
||||
| url | VARCHAR(512) NULL | 原文链接(新闻联播为空) |
|
||||
| created_at | DATETIME | 入库时间 |
|
||||
|
||||
索引:`idx_report_section (report_id, section)`。
|
||||
|
||||
---
|
||||
|
||||
## 2. 数据契约
|
||||
|
||||
- **幂等语义**:同一 `(report_date, report_type, file_name)` 重复写入会覆盖主表并全量替换事件(DELETE + INSERT),不会产生重复行。
|
||||
- **取最新**:同一天存在多份时(历史 intl 一日 3 次),前端按 `generated_at` 取最新;新日报 `file_name=''` 每天唯一。
|
||||
- **板块差异**:finance 日报含 `xwlb`+`news`+`cninfo` 三板块;intl 日报仅 `intl` 板块。前端按 `section` 过滤展示。
|
||||
- **历史覆盖范围**:2026-06-16 ~ 2026-08-03,共 177 行(finance 49 + intl 128;finance 少 1 因为两个目录存在同名文件被幂等合并)。事件总计 4222 条。
|
||||
|
||||
---
|
||||
|
||||
## 3. stats JSON 结构
|
||||
|
||||
`news_report.stats` 为数据总览快照,前端自行解析。finance 与 intl 的 key 集合不同:
|
||||
|
||||
| key | finance | intl | 内容 |
|
||||
| --- | --- | --- | --- |
|
||||
| `pipeline` | ✅ | ✅ | 管道各环节数量。**finance 与 intl 内部 key 集不同**:finance 为 `{raw_total, raw_by_source, raw_total_24h, raw_by_source_24h, proc, deduped, dups, emb_count, qdrant_count, cninfo_raw}`;intl 为 `{raw_total, processed, deduped, embedded, qdrant}`(口径见 §3.1) |
|
||||
| `sources` | ✅ | — | 各新闻源文章数:`{源名: 数量}` |
|
||||
| `news` | ✅ | — | 新闻统计:`{total, hi_threshold, sentiments, importances, event_types}` |
|
||||
| `cninfo` | ✅ | — | 公告调研统计:`{total, hi_threshold, by_day, announcement, research, irm}` |
|
||||
| `xwlb` | ✅ | — | 联播统计:`{total, date}`(有数据时才有) |
|
||||
| `sentiment` | ✅ | ✅ | 情绪分布(历史文件为图例文本列表;新生成在 `news.sentiments`) |
|
||||
| `importance` | ✅ | ✅ | 重要度分布:`[{重要度, 数量}, ...]` |
|
||||
| `event_types` | ✅ | ✅ | 事件类型 TOP:`[{事件类型, 数量}, ...]` |
|
||||
| `source_dist` | — | ✅ | 文章来源分布:`[{来源, 文章数}, ...]` |
|
||||
|
||||
> 历史文件与新生成日报的 stats 结构存在差异(历史为 HTML 解析快照,新生成为结构化组装),前端建议按 key 防御性读取。
|
||||
|
||||
### 3.1 口径说明(重要,避免误解)
|
||||
|
||||
`stats` 内各数字口径不同,请勿直接互相比较:
|
||||
|
||||
| 字段 | 口径 |
|
||||
| --- | --- |
|
||||
| `pipeline.raw_total` | **日报日期当天**抓取的文章数(`data/raw/{src}/{date}/index.jsonl` 中 `stage=article 且 success` 的条目)。`raw_by_source` 是各源明细,**其和 = raw_total**;当天未抓取/无文章的源显示 0 |
|
||||
| `pipeline.raw_total_24h` | 最近 24 小时内**抓取**(按 `fetched_at`)的文章数;`raw_by_source_24h` 为各源明细,和 = raw_total_24h。当天 07:00 抓取的数据其值 ≈ raw_total(并非"24h 内发布的新闻",raw 层无发布时间的可靠字段) |
|
||||
| `pipeline.proc / deduped / dups / emb_count / qdrant_count` | 抽取 / 去重后 / 重复 / 向量化 / Qdrant 总量(`qdrant_count` 为全量累计,非当天) |
|
||||
| `news.total` | **过去 30 小时窗口内**经 LLM 抽取的新闻事件数。**≠ raw_total**:raw 是抓取的文章数,news 是抽取后的事件数(会有过滤/合并),两者不可互相验证 |
|
||||
| `news.importances` | `{重要度等级(1-5): 事件数}`,**各等级之和 = news.total** |
|
||||
| `news.sentiments` | `{情绪: 事件数}`(positive/negative/neutral),和 = news.total |
|
||||
| `news.event_types` | `{事件类型: 事件数}`(TOP 10) |
|
||||
| `pipeline.*(finance)` | finance 日报专用:`proc`=抽取后条数、`deduped`=去重后、`dups`=重复条数、`emb_count`=向量化条数、`qdrant_count`=Qdrant 全量累计(非当天)、`cninfo_raw`=当天 cninfo 抓取数。`raw_by_source` 各源之和 = `raw_total` |
|
||||
| `pipeline.*(intl)` | intl 日报**结构不同**:`raw_total`=当天抓取文章数、`processed`=处理数(≈ raw_total)、`deduped`=去重后条数、`embedded`=向量化条数、`qdrant`=Qdrant 全量累计。intl 无 `raw_by_source` 明细与 `cninfo_raw` |
|
||||
|
||||
---
|
||||
|
||||
## 4. 常用查询示例(API 实现参考)
|
||||
|
||||
```sql
|
||||
-- 某类型日报列表(取每天最新一份)
|
||||
SELECT r.* FROM news_report r
|
||||
JOIN (
|
||||
SELECT report_date, report_type, MAX(generated_at) AS g
|
||||
FROM news_report GROUP BY report_date, report_type
|
||||
) t ON r.report_date = t.report_date AND r.report_type = t.report_type
|
||||
AND r.generated_at = t.g
|
||||
WHERE r.report_type = 'finance' AND r.report_date >= '2026-07-01'
|
||||
ORDER BY r.report_date DESC;
|
||||
|
||||
-- 某日报的全部事件(按板块)
|
||||
SELECT section, rank, importance, event_type, title, summary, sentiment, source, url
|
||||
FROM news_event WHERE report_id = ? ORDER BY section, rank;
|
||||
|
||||
-- 最近 N 天重要事件聚合(跨日报检索)
|
||||
SELECT e.* FROM news_event e
|
||||
JOIN news_report r ON r.id = e.report_id
|
||||
WHERE r.report_date >= DATE_SUB(CURDATE(), INTERVAL 7 DAY)
|
||||
AND e.importance >= 4
|
||||
ORDER BY e.importance DESC, r.report_date DESC;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. 相关命令(数据生产侧)
|
||||
|
||||
```bash
|
||||
uv run a-share report --date YYYYMMDD # 生成当日日报并入库(finance)
|
||||
uv run a-share report-import # 历史 HTML 全量解析入库(幂等)
|
||||
uv run a-share report-import --date YYYYMMDD --type intl
|
||||
```
|
||||
|
||||
代码:`report_db/`(连接/写入)、`report_import/`(历史解析/导入)、`scheduler/reporter.py`(日报生成)。
|
||||
Reference in New Issue
Block a user