docs: document read-only dashboard and preview workflow

This commit is contained in:
kairee committed 2026-10-31 23:47:02 +08:00
1 parent cbba405271
commit d18ebbfb2f
3 files changed
+122 -51

No files matched your search

+52 -29
View File
@@ -1,6 +1,6 @@
# 咻咻满 Reaction 视频数据看板开发文档
> **状态:** P0(数据底座与收藏夹同步)、P1(每日快照与粉丝追踪)已实施并通过只读联调;P2 待开始
> **状态:** P0(数据底座与收藏夹同步)、P1(每日快照与粉丝追踪)、P2(只读本地看板)、P3(Telegram 与一键加入)已实施
>
> **技术基线:** Python 3.14、Python 标准库、SQLite、原生 HTML/CSS/JavaScript、`uv`
>
@@ -107,8 +107,15 @@ uv run python app.py auth-check
uv run python app.py status
# P2 起启动本地看板服务
uv run python app.py serve
uv run python app.py serve --config .\config.json
# 无子命令启动完整服务:只读 Web + 调度 + Telegram
uv run python app.py
uv run python app.py --config .\config.json
# 生成 7 天预览库并启动预览
uv run python tools/seed_preview_db.py --days 7
uv run python app.py serve --preview --config data/preview/config.json
```
不建议直接激活 `.venv`;优先使用 `uv run ...`,这样命令总是运行在项目锁定的解释器和环境中。
@@ -218,10 +225,10 @@ PRAGMA synchronous = NORMAL;
│ │ ├── snapshot.py
│ │ └── maintenance.py
│ ├── notify/telegram.py # Telegram 消息与按钮
│ └── web/ # P2 预留
│ ├── server.py
│ ├── api.py
│ └── static/
│ └── web/ # P2 只读看板
│ ├── server.py # HTTP、路由、鉴权、静态资源
│ ├── queries.py # 看板 SQL 与数据整形
│ └── static/ # 原生 JS/CSS、ECharts、预览页面
│
├── tests/
└── data/ # 本地运行期数据,默认不提交
@@ -487,9 +494,10 @@ P3 实现说明:
### 9.1 API 原则
- `/api/health` 可匿名,仅返回健康状态;
- 其他 `/api/*` 默认要求 `Authorization: Bearer <token>`;
- 写操作额外要求 CSRF 防护与 Origin/Referer 校验;
- P2 看板**只读**:业务接口只注册 GET,写方法统一返回 `405`;
- 数据管理(收藏、忽略、拉黑、移出库、移除黑名单)继续通过 Telegram、CLI 或数据库完成;
- `/api/health` 可匿名;配置 `web.auth_token` 后其他 `/api/*` 要求 Cookie 或 `Authorization: Bearer <token>`;
- 只读接口不需要 CSRF;登录 POST 只建立会话,不修改业务数据;
- API 返回 JSON;前端不复制热度、状态机或收藏夹归属判断;
- CSV 导出由后端根据当前筛选条件生成。
@@ -497,32 +505,38 @@ P3 实现说明:
| 方法 | 路径 | 用途 |
|---|---|---|
| `GET` | `/api/overview` | 总览指标、容量、采集状态 |
| `GET` | `/api/videos` | 视频分页、筛选和排序 |
| `GET` | `/api/overview` | 首页动态、总览指标、容量、采集状态 |
| `GET` | `/api/videos` | 视频分页、筛选和排序(支持 added/published/heat/七项/互动/增长) |
| `GET` | `/api/videos/{aid}` | 视频详情 |
| `GET` | `/api/videos/{aid}/trend` | 七项趋势数据 |
| `GET` | `/api/rankings` | 热度、增长、互动率与单项榜 |
| `GET` | `/api/rankings` | 视频榜或 `scope=up` 的 UP 聚合榜 |
| `GET` | `/api/ups` | UP 聚合榜单 |
| `GET` | `/api/ups/{mid}` | UP 详情、聚合趋势和视频列表 |
| `GET` | `/api/fans` | 粉丝曲线与增量 |
| `GET` | `/api/candidates` | 候选池 |
| `GET` | `/api/system/status` | 最近任务、下次任务、错误日志 |
| `POST` | `/api/candidates/{aid}/favorite` | 收藏候选 |
| `POST` | `/api/candidates/{aid}/ignore` | 忽略候选 |
| `POST` | `/api/candidates/{aid}/blacklist` | 拉黑候选所属 UP |
| `DELETE` | `/api/blacklist/{mid}` | 移除黑名单 |
| `POST` | `/api/videos/{aid}/drop` | 手动停止追踪 |
| `GET` | `/api/candidates` | 候选池(只读) |
| `GET` | `/api/system` | 最近任务、下次任务、备份、黑名单 |
| `GET` | `/api/export.csv` | 按当前视频筛选导出 CSV |
### 9.2 页面
| 页面 | 内容 |
|---|---|
| 总览 | 库内数、UP 数、今日新增、增量、容量条、采集成功率、故障提示。 |
| 首页 | 最新动态优先:今日增量、最新入库、最近发布、增长动态、热度速览、容量与采集状态。 |
| 榜单 | 综合热度、七项单项、增长、增速、互动率、UP 聚合、筛选和 CSV。 |
| 视频详情 | 元数据、七项趋势、快照表、失败标记、同 UP 对比。 |
| UP 页 | UP 的全部视频、聚合趋势和平均互动率。 |
| 视频详情 | 元数据、七项指标、单指标趋势、快照表、失败标记、同 UP 对比。 |
| UP 页 | UP 的全部视频、聚合趋势、单视频对比和平均互动率。 |
| 粉丝页 | 粉丝总数、日增、7 日净增、累计增长;不叠加视频数据。 |
| 候选池 | 待确认候选、规则命中、剩余保留时间和三个操作。 |
| 系统状态 | 最近扫描、同步、快照、下一次运行时间和错误。 |
| 候选池 | 待确认候选、规则命中、剩余保留时间;操作指向 Telegram/CLI。 |
| 系统状态 | 最近扫描、同步、快照、下次运行、备份、鉴权和黑名单。 |
### 9.3 预览模式
- `tools/seed_preview_db.py` 复制真实库并回填合成快照,真实库只读;
- 合成快照写 `src='preview'`,预览库写 `kv preview:seeded=1`;
- `python app.py serve --preview` 校验标记,缺失时拒绝启动;
- 预览配置不包含真实凭据,默认端口 8081,Telegram 关闭;
- 预览页面显示固定“预览数据 · 只读”横幅;
- 重新生成预览库前必须停止预览服务,避免 Windows 文件占用。
---
@@ -583,7 +597,10 @@ uv run python tests/test_moves.py
- 热度、增长和互动率计算;
- 收藏夹目标选择与排序锚点;
- `fav_action` 的重复点击、失败重试和过期处理;
- Telegram 用户与 chat ID 授权校验。
- Telegram 用户与 chat ID 授权校验;
- 看板查询的筛选、分页、增长冷启动与状态过滤;
- 只读路由、鉴权、静态资源路径穿越和预览标记校验;
- 预览库生成的确定性、单调性、异常样本与真实库隔离。
只有当标准库测试维护成本明显过高时,才考虑通过 `uv add --dev pytest` 引入 pytest。
@@ -656,11 +673,17 @@ uv run python tests/test_moves.py
- 真实 `deal` / `sort` 尚未在收藏夹执行,等待用户点击 Telegram 按钮或授权测试视频后验证;
- 自动化测试见 `tests/test_classify.py`、`test_search.py`、`test_candidates.py`、`test_discovery.py`、`test_fav_position.py`、`test_favorites.py`、`test_telegram.py`、`test_httpx_transport.py`、`test_favsort_http.py`。
### P2:本地看板
### P2:只读本地看板 ✅
- 总览、榜单、详情、UP、粉丝、候选和系统状态页面;
- 原生前端和 ECharts;
- 本机默认绑定 `127.0.0.1:8080`。
- 首页、榜单、视频/UP 详情、粉丝、候选和系统状态页面;
- 原生前端和本地 vendored ECharts;
- 本机默认绑定 `127.0.0.1:8080`;
- Web 业务接口只读,写操作继续由 Telegram/CLI/数据库承担;
- 首页默认“最新动态”,增长榜在不足 2 天时显示空态;
- 视频趋势按单指标切换,缺失日断开、失败快照按缺失处理;
- 实现 `tools/seed_preview_db.py`:复制真实库并回填 7 天合成快照,支持 `--profile live|first-day`;
- `serve --preview` 校验 `preview:seeded=1` 标记,预览页面显示只读横幅;
- 自动化测试见 `tests/test_analytics.py`、`test_preview_seed.py`、`test_web_queries.py`、`test_web_server.py`。
### P4:可选部署
+44 -3
View File
@@ -4,9 +4,9 @@
项目以 B 站年度收藏夹为可信视频来源,补充关键词发现和 Telegram 人工确认,持续采集 reaction 视频的七项数据与咻咻满粉丝数,并提供本地数据看板。现有的收藏夹排序工具仍保留并作为一键加入后的排序能力基础。
> 当前状态:**P0(数据底座与收藏夹同步)、P1(快照与粉丝追踪)、P3(Telegram 与一键加入)已实施;P2 待开始。**
> 当前状态:**P0(数据底座与收藏夹同步)、P1(快照与粉丝追踪)、P2(只读本地看板)、P3(Telegram 与一键加入)已实施。**
>
> 当前已可用:扫码授权、收藏夹读取、排序计划生成、执行与校验;SQLite 建库迁移、收藏夹首次导入与增量同步、失效识别、黑名单种子;每日七项视频快照、粉丝数快照、失败占位、断点续跑与日备份;搜索发现、候选池、Telegram 通知与收藏/忽略/拉黑回调。
> 当前已可用:扫码授权、收藏夹读取、排序计划生成、执行与校验;SQLite 建库迁移、收藏夹首次导入与增量同步、失效识别、黑名单种子;每日七项视频快照、粉丝数快照、失败占位、断点续跑与日备份;搜索发现、候选池、Telegram 通知与收藏/忽略/拉黑回调;只读本地看板与可重复生成的预览数据。
>
> 详细业务口径、接口验证和风险记录见 [project.md](project.md);开发架构与实施计划见 [DEVELOPMENT.md](DEVELOPMENT.md)。
@@ -21,7 +21,7 @@
| 粉丝追踪 | 可用(P1) | 每日记录咻咻满等配置 UP 的粉丝数。 |
| 搜索发现与候选池 | 可用(P3) | 每小时搜索前 2 页,分类打分后写入候选池。 |
| Telegram 通知与一键加入 | 可用(P3) | 收藏 / 忽略 / 拉黑按钮,`deal` + `sort` 回读校验。 |
| 本地数据看板 | 规划(P2) | 总览、榜单、视频/UP 详情、粉丝曲线、候选池和系统状态。 |
| 本地数据看板 | 可用(P2) | 只读总览、榜单、视频/UP 详情、粉丝曲线、候选池和系统状态。 |
## 核心工作流
@@ -150,6 +150,41 @@ uv run python app.py run
> 真实 `deal` / `sort` 需要用户点击 Telegram 按钮才会触发;离线测试使用契约一致的 Mock 覆盖。
## P2:只读本地看板
P2 提供移动端优先的只读看板,默认绑定 `127.0.0.1:8080`。Web 页面不提供收藏、忽略、拉黑、移出库等写操作;数据管理仍通过 Telegram、CLI 或数据库完成。
```powershell
# 只启动只读 Web(不运行调度、不连 B 站)
uv run python app.py serve
# 无子命令启动完整服务:只读 Web + 调度 + Telegram
uv run python app.py
# 生成 7 天预览库并启动预览
uv run python tools/seed_preview_db.py --days 7
uv run python app.py serve --preview --config data/preview/config.json
```
- 首页默认“最新动态”:今日增量、最新入库、最近发布、增长动态、热度速览、收藏夹容量与采集状态;
- 榜单支持综合热度、七项单项、互动率、增长/增速,以及 UP 聚合榜;服务端筛选、排序、分页和 CSV 导出;
- 视频详情提供七项指标、单指标趋势、快照表和同 UP 对比;UP 页提供聚合趋势与单视频对比;
- 粉丝页只绘制粉丝曲线,不叠加视频数据;
- 候选池和系统状态只读展示,操作入口指向 Telegram/CLI;
- 本地回环地址默认免登录;配置 `web.auth_token` 后启用登录页和 HttpOnly Cookie;非回环地址且未配置 token 时拒绝启动;
- 所有业务接口只接受 GET,写方法返回 `405`。
### 预览数据
`tools/seed_preview_db.py` 通过 SQLite backup API 复制真实库到 `data/preview/app.db`,再回填 7 天合成快照:
- 合成行标记 `src='preview'`,并写入 `kv preview:seeded=1`;
- 真实库只读,预览库与真实库完全分离;
- 默认包含少量缺失日、3 条失败快照、4 条预览候选和 1 条预览黑名单;
- `--profile first-day` 可生成保持“首次导入”状态的冷启动库;
- 预览配置不包含真实 Cookie,端口 8081,Telegram 关闭;
- 重新生成前必须先停止预览服务,否则 Windows 会因数据库被占用而拒绝覆盖。
## 配置
复制样例配置,并填写 B 站账号信息:
@@ -293,6 +328,10 @@ uv run python tests/test_folder_sync.py # 首次导入、差集、失效识
uv run python tests/test_snapshot.py # 七项快照、补采、断点续跑、粉丝、备份重试
uv run python tests/test_maintenance.py # 日备份与保留期
uv run python tests/test_timeutil.py # 上海时区与每日任务时间
uv run python tests/test_analytics.py # 热度、互动率、增长与封面
uv run python tests/test_preview_seed.py # 预览库回填、确定性与安全边界
uv run python tests/test_web_queries.py # 看板查询层与冷启动
uv run python tests/test_web_server.py # 只读路由、鉴权、静态资源与预览模式
uv run python tests/test_scheduler.py # 内置调度器到期/失败隔离
uv run python tests/test_provider.py # 凭据变化重建客户端与配置 revision
uv run python tests/test_favsort_run.py # 排序参数校验与混合资源类型
@@ -309,6 +348,8 @@ data/journal-<media_id>.jsonl 排序执行日志
data/app.db SQLite 数据库(收藏夹、视频、快照、粉丝、黑名单)
data/backup/app-YYYYMMDD.db 每日快照后的 SQLite 备份
data/backup/app-pre-v*.db 数据库迁移前的自动备份
data/preview/app.db 合成预览数据库(不提交)
data/preview/config.json 无凭据的预览配置(不提交)
```
## 文档索引
+26 -19
View File
@@ -1,7 +1,7 @@
# 咻咻满 Reaction 视频数据看板 —— 可行性分析与技术路线
> 状态:**设计定稿;P0(数据底座与收藏夹同步)、P1(每日快照与粉丝追踪)、P3(Telegram 与一键加入)已实施;P2 待开始**
> 最后更新:2026-10-31(第 7 轮:P3 落地)
> 状态:**设计定稿;P0(数据底座与收藏夹同步)、P1(每日快照与粉丝追踪)、P2(只读本地看板)、P3(Telegram 与一键加入)已实施**
> 最后更新:2026-10-31(第 8 轮:P2 只读看板与预览数据落地)
> B 站探测均为只读(GET),尚未调用 `fav/resource/deal`、`fav/resource/sort`
---
@@ -666,25 +666,28 @@ fan_delta_cum = follower(d) - follower(首日)
| 页面 | 内容 |
|---|---|
| 总览 | 库内视频数、活跃 UP 数、今日新增、今日总播放/增量、**收藏夹容量条**(664/1000)、昨日采集成功率 |
| 榜单 | Tab:综合热度/播放/点赞/硬币/收藏/转发/评论/弹幕/增长最快/互动率;筛选 UP、搜标题、导出 CSV |
| 视频详情 | 元数据 + 7 项趋势 + 同 UP 对比 + 快照表(含失败标记)+ 「加入收藏夹」按钮 |
| UP 页 | 该 UP 全部视频、聚合趋势、平均互动率 |
| 首页 | 最新动态优先:今日增量、最新入库、最近发布、增长动态、热度速览、收藏夹容量、采集状态 |
| 榜单 | Tab:综合热度/播放/点赞/投币/收藏/转发/评论/弹幕/互动率/增长/增速;视频与 UP 范围切换;筛选、搜索、导出 CSV |
| 视频详情 | 元数据 + 七项指标 + 单指标趋势(7/30/90/全部)+ 同 UP 对比 + 快照表(含失败标记) |
| UP 页 | 该 UP 全部视频、聚合趋势、单视频对比、平均互动率 |
| **粉丝页** | 咻咻满粉丝数曲线 + 每日/7 日净增 + 累计增长(只画粉丝,不叠加视频数据) |
| **候选池** | 未达通知阈值 / 未决策的候选(7 天后自动删除),支持收藏/忽略/拉黑 |
| **系统状态** | 最近扫描、采集成功率、收藏夹同步时间、下次任务时间、错误日志 |
| **候选池** | 候选、得分、通知时间、剩余 TTL;只读展示,操作指向 Telegram/CLI |
| **系统状态** | 最近任务、采集成功率、收藏夹同步时间、下次任务、备份、鉴权、黑名单 |
### 9.2 技术
- 单 `index.html` + 原生 JS,无构建链;
- 图表 **vendored ECharts**(Apache-2.0,离线);
- 单 `index.html` + 原生 ES Module,无构建链;
- 图表本地 vendored ECharts(Apache-2.0,离线);
- `/api/*` JSON,前端只渲染;
- 移动端优先(通知点进来多为手机)。
- 移动端优先,底部 5 项导航;桌面端左侧导航;
- 首页增长榜在不足 2 天快照时显示空态,不伪造 0。
### 9.3 鉴权
### 9.3 只读边界与鉴权
- 公网部署,默认开启:`Authorization: Bearer <token>` 或一次性登录换 HttpOnly cookie;
- 写操作(加入/忽略)同样校验,CSRF 用签名 token;
- P2 Web 业务接口只读,写方法统一 `405`;数据管理继续通过 Telegram/CLI/数据库;
- 本地回环地址且未配置 `web.auth_token` 时免登录;
- 配置 token 后启用登录页 + HttpOnly Cookie,或使用 `Authorization: Bearer <token>`;
- 非回环地址且未配置 token 时拒绝启动;
- 不做多用户(YAGNI)。
---
@@ -792,6 +795,9 @@ storage:SQLite WAL,单写线程
| 31 | **P3 真实发现** | 4 次 WBI 搜索、168 条结果、161 已入库、6 条超时间窗、1 条候选(score=6) |
| 32 | **P3 Telegram 通知** | 真实 Bot 发送成功;发现重复结果后已修复按 aid 去重,离线测试覆盖 |
| 33 | **P3 同步联动** | 候选被人工加入收藏夹后,同步识别 1 条新增并当天补采快照;候选行自动删除 |
| 34 | **P2 预览数据** | 复制真实库回填 7 天:796 条视频、4,606 条合成快照、3 条失败、4 条候选、1 条预览黑名单 |
| 35 | **P2 只读页面** | 首页/榜单/视频/UP/粉丝/候选/系统 7 个页面在 390px 与 1280px 下无脚本错误 |
| 36 | **P2 只读边界** | 业务 POST/PUT/PATCH/DELETE 均返回 405,请求前后数据库行数不变 |
**未验证(需授权或外部配合)**:
@@ -806,11 +812,12 @@ storage:SQLite WAL,单写线程
## 14. 下一步
P0、P1、P3 已实施。下一步是 **P2 本地看板**:
P0、P1、P2、P3 已实施。P2 交付了只读本地看板与可重复生成的 7 天预览数据:
1. 总览、榜单、视频/UP 详情、粉丝曲线、候选池和系统状态页面;
2. 原生前端 + ECharts,本机默认绑定 `127.0.0.1:8080`;
3. 复用现有 SQLite 查询与状态机,不在前端复制业务判断;
4. P3 的真实 `deal` / `sort` 待用户点击 Telegram 按钮或授权测试视频后补充验证记录。
1. 首页、榜单、视频/UP 详情、粉丝曲线、候选池和系统状态页面;
2. 原生 ES Module + 本地 ECharts,本机默认绑定 `127.0.0.1:8080`;
3. 查询、热度、增长和互动率全部在服务端计算,前端只渲染;
4. Web 不提供业务写操作,数据管理继续通过 Telegram/CLI/数据库;
5. P3 的真实 `deal` / `sort` 待用户点击 Telegram 按钮或授权测试视频后补充验证记录。
> P4(容器化 + 反代)继续保持可选。