Преглед на файлове

docs: plan web visualization project

Sam Lee преди 1 месец
родител
ревизия
af32867b83
променени са 6 файла, в които са добавени 1743 реда и са изтрити 0 реда
  1. 47 0
      web/README.md
  2. 331 0
      web/docs/01_产品功能规划.md
  3. 288 0
      web/docs/02_数据与接口规划.md
  4. 380 0
      web/docs/03_技术开发规划.md
  5. 288 0
      web/docs/04_show视觉迁移清单.md
  6. 409 0
      web/docs/05_Web实施简报.md

+ 47 - 0
web/README.md

@@ -0,0 +1,47 @@
+# ContentFindAgent Web
+
+`web/` 是新的可视化面板项目目录。后续 Next.js 代码、组件、API client、页面和前端测试都放在这里;旧 `show/` 只作为视觉和交互参考,不再作为真实数据实现底座。
+
+## 定位
+
+新 Web 的目标是把 ContentFindAgent 的真实运行数据展示给用户:
+
+- 查看 run 列表和运行状态。
+- 进入某次 run,按阶段查看数据源、Query、平台召回、规则判断、游走、资产沉淀和策略学习。
+- 诊断失败 run,例如平台失败、Query 生成失败、runtime 缺文件、validation 不通过。
+- 复盘哪些 Query、规则、游走路径和资产值得保留或调整。
+
+## 和 show 的关系
+
+`show/` 当前是旧静态沙盘:视觉完整,但数据主要写死在 `show/src/App.tsx`,不连接 FastAPI,也不是生产事实层。
+
+新 Web 要做到:
+
+- 视觉和交互尽量贴近 `show`。
+- 数据层和组件结构全部重写。
+- 不迁移 `show` 的静态样例作为事实数据。
+- 不把小红书、热点、养号、共创、相似作者等旧占位入口当成 V1 默认能力。
+
+## 数据原则
+
+- 生产事实层:FastAPI 读取云 MySQL `content_agent_*` 表或后端聚合后的事实数据。
+- 回放辅助层:本地 `runtime/v1/{run_id}/` JSON / JSONL 只作为开发调试和回放导出,UI 必须标注为“回放导出”。
+- 前端不直接连接 MySQL。
+- 前端不直接读取任意文件路径。
+- runtime 文件读取接口必须使用后端白名单。
+
+## 文档
+
+- [01_产品功能规划.md](docs/01_产品功能规划.md)
+- [02_数据与接口规划.md](docs/02_数据与接口规划.md)
+- [03_技术开发规划.md](docs/03_技术开发规划.md)
+- [04_show视觉迁移清单.md](docs/04_show视觉迁移清单.md)
+- [05_Web实施简报.md](docs/05_Web实施简报.md)
+
+## 后续实施顺序
+
+1. 补后端 Web 友好 API。
+2. 初始化 `web/` 下 Next.js 项目。
+3. 建立 API client、类型和数据 adapter。
+4. 复刻 `show` 的页面视觉与核心交互。
+5. 用真实 run 数据替换静态演示数据。

+ 331 - 0
web/docs/01_产品功能规划.md

@@ -0,0 +1,331 @@
+# Web 产品功能规划
+
+## 目标用户
+
+新 Web 面向内部运营、产品、策略和工程用户。它不是营销页面,也不是单纯日志页,而是 ContentFindAgent 的运行观察、结果复盘和问题诊断面板。
+
+用户打开 Web 后,应能完成四件事:
+
+1. 找到一次真实 run。
+2. 看懂这次 run 从数据源到策略学习的完整链路。
+3. 看清每个 Query、内容、规则、游走动作为什么成功、失败、待复看或被规则阻断。
+4. 区分生产事实和回放导出,避免把静态样例当成真实结果。
+
+## 总体信息架构
+
+视觉结构参考旧 `show`:
+
+- 顶部 7 阶段 Pipeline:
+  - 数据源
+  - Query
+  - Platform
+  - 判断
+  - 游走
+  - 资产清洗沉淀
+  - 策略学习
+- 页面主体:
+  - 左侧列表 / 筛选区
+  - 右侧详情区
+  - 阶段内表格、卡片、抽屉和 trace strip
+- 状态标识:
+  - 生产事实
+  - 回放导出
+  - 缺失数据
+  - 失败诊断
+  - 部分成功
+
+新 Web 保留 `show` 的视觉心智,但功能范围以当前 V1 真实链路为准。
+
+## 页面规划
+
+### 1. Run 列表页
+
+用途:选择一次运行,并快速判断运行是否可复盘。
+
+核心信息:
+
+- `run_id`
+- `policy_run_id`
+- `status`
+- `platform`
+- `platform_mode`
+- `strategy_version`
+- `validation_status`
+- `error_code`
+- `started_at`
+- `ended_at`
+- 数据源标识,例如 `demand_content_id` 或 `run_label`
+
+筛选:
+
+- 状态:success / partial_success / failed
+- 平台:默认 douyin
+- 运行模式:real / mock
+- 校验状态:pass / fail
+- 时间范围
+- 搜索:run_id、policy_run_id、error_code
+
+空状态:
+
+- 如果生产 DB 只有失败 run,页面应显示“当前生产事实主要是失败诊断数据”,不能伪造完整成功链路。
+- 如果选择 runtime 回放,则明确显示“回放导出,不是生产事实”。
+
+### 2. Run 总览页
+
+用途:进入某次 run 后先看整体健康度和链路摘要。
+
+核心区域:
+
+- 顶部运行摘要:状态、平台、策略版本、policy bundle、validation。
+- 文件 / 表完整性:哪些 artifact 存在,哪些缺失。
+- 阶段进度:用与 `show` 一致的 7 阶段条展示。
+- 关键计数:
+  - Query 数
+  - 发现内容数
+  - 入池内容数
+  - 待复看数
+  - 淘汰数
+  - 规则阻断数
+  - walk action 数
+  - strategy review 状态
+
+### 3. 数据源阶段
+
+用途:解释这次 run 从哪个真实需求或证据开始。
+
+显示:
+
+- DemandAgent 来源:`demand_content_id`、`run_label`
+- `source_context.json`
+- `ext_data.evidence_pack`
+- Pattern 证据字段:
+  - `pattern_source_system`
+  - `pattern_execution_id`
+  - `mining_config_id`
+  - `source_post_id`
+  - `matched_post_ids`
+  - `itemset_ids`
+  - `category_bindings`
+  - `decode_case_ids`
+
+保留 show 视觉:
+
+- 左侧数据源列表。
+- 顶部筛选和搜索。
+- 右侧证据详情卡片。
+
+降级或隐藏:
+
+- 小红书、Case 独立数据源、历史作者、热点、养号默认不作为 V1 入口展示。
+- 如果要展示,只能放在“旧 show 占位 / 后续能力”区域。
+
+### 4. Query 阶段
+
+用途:看 seed terms 如何生成平台搜索 Query。
+
+显示:
+
+- `search_queries.jsonl`
+- Query 文本
+- 生成方式:
+  - `item_single`
+  - `llm_variant`
+  - `tag_query`
+- `query_source_terms`
+- `query_source_fields`
+- `pattern_seed_ref`
+- LLM 输入快照和生成模型
+
+保留 show 视觉:
+
+- Query 工作台三列布局。
+- evidence / prompt / query group 的层级表达。
+- Prompt 展开弹窗。
+
+注意:
+
+- 不显示旧的硬编码“案例 / 解读 / 警示”作为默认模板。
+- Query 少于预期时必须展示失败原因,而不是默默少显示。
+
+### 5. Platform / 发现内容阶段
+
+用途:看每条 Query 拉回了什么内容,以及平台数据质量如何。
+
+显示:
+
+- `discovered_content_items.jsonl`
+- `content_media_records.jsonl`
+- `platform_content_id`
+- `platform_author_id`
+- 描述、标签、互动统计
+- `has_more`
+- `next_cursor`
+- `platform_raw_payload` 摘要
+- 媒体状态和画像可用性
+
+核心交互:
+
+- 按 Query 筛选内容。
+- 按作者筛选内容。
+- 按平台内容 ID 搜索。
+- 查看同一内容被多个 Query 命中的来源合并。
+
+### 6. 判断阶段
+
+用途:解释规则包为什么让内容入池、待复看、淘汰或规则阻断。
+
+显示:
+
+- `rule_decisions.jsonl`
+- `decision_action`
+- `decision_reason_code`
+- `search_query_effect_status`
+- `score`
+- `scorecard`
+- `triggered_blocking_rules`
+- `decision_replay_data`
+- `source_evidence`
+
+保留 show 视觉:
+
+- 规则包卡片。
+- hard gate / scorecard / threshold 分区。
+- 右侧抽屉展示细则。
+
+状态口径:
+
+- `ADD_TO_CONTENT_POOL`:入池
+- `KEEP_CONTENT_FOR_REVIEW`:待复看
+- `REJECT_CONTENT`:淘汰
+- `rule_blocked`:规则阻断
+- `failed`:普通失败
+- `pending`:待复看或需复盘
+
+### 7. 游走阶段
+
+用途:展示 P6 WalkAction 如何决定下一步动作。
+
+显示:
+
+- `walk_actions.jsonl`
+- `source_path_records.jsonl`
+- `search_clues.jsonl`
+- edge:
+  - `query_next_page`
+  - `video_to_author`
+  - `author_to_works`
+  - `author_work_to_content`
+  - `video_to_hashtag`
+  - `hashtag_to_query`
+  - `path_stop`
+  - `budget_downgrade`
+- `walk_status`
+- `walk_action_id`
+- `budget_tier`
+- `depth`
+- `reason_code`
+
+保留 show 视觉:
+
+- 游走筛选器。
+- 策略边表格。
+- 右侧边详情。
+
+降级或隐藏:
+
+- 小红书。
+- 共创。
+- 相似作者。
+- 热点。
+- 养号。
+- 相关搜索如果当前 V1 未接入真实执行,必须标为后续能力。
+
+### 8. 资产沉淀阶段
+
+用途:展示最终沉淀的内容资产、作者资产、搜索线索资产。
+
+显示:
+
+- `final_output.json`
+- `content_assets`
+- `author_assets`
+- `search_clues`
+- `reject_records`
+- `decision_records`
+- 发布任务状态摘要
+
+注意:
+
+- 内容资产和媒体记录不是同一个概念。
+- 作者资产只有满足沉淀条件才展示为正式资产。
+- 不满足条件的作者只显示在 run 记录和原因中。
+
+### 9. 策略学习阶段
+
+用途:复盘本次运行给后续策略带来的建议。
+
+显示:
+
+- `strategy_review.json`
+- `summary`
+- `metric_summary`
+- `decision_distribution`
+- `effective_search_queries`
+- `top_reject_reasons`
+- `productive_paths`
+- `suggestions`
+- `performance_feedback_status`
+
+注意:
+
+- `content_agent_performance_feedback` 当前可能没有数据。
+- 无后验表现时显示 `performance_feedback_status=missing`,不能伪造学习结论。
+- `GET /strategy-review` 只读已有 review;重算必须用显式 regenerate。
+
+### 10. Runtime / Validation 调试页
+
+用途:给工程和策略用户快速定位数据缺失和结构漂移。
+
+显示:
+
+- runtime file 列表。
+- 每个文件是否存在。
+- 每个文件记录数。
+- validation findings。
+- missing / old alias / deprecated runtime 的提示。
+
+对旧 runtime 的处理:
+
+- 旧文件名如 `queries.jsonl`、`candidate_pool.jsonl` 只在回放模式中显示。
+- 使用 migration alias 做可读提示,但不把旧名当作当前合同。
+
+## show 视觉保留范围
+
+必须保留:
+
+- 顶部 7 阶段 Pipeline。
+- 数据源阶段的筛选、搜索、左列表、右详情。
+- Query 工作台。
+- 判断规则卡和抽屉。
+- 游走工作台。
+- 资产流程卡。
+- 策略学习 trace / 建议布局。
+
+必须替换:
+
+- 静态 demo 数据。
+- 模拟资产文字。
+- “页面模拟,不入库”类型文案。
+- 旧占位能力的默认展示。
+
+必须降级:
+
+- 小红书。
+- 热点。
+- 养号。
+- 共创。
+- 相似作者。
+- 历史作者。
+- Case 独立入口。
+
+这些只能作为“旧 show 占位 / 后续能力”,不能出现在 V1 默认真实链路里。

+ 288 - 0
web/docs/02_数据与接口规划.md

@@ -0,0 +1,288 @@
+# Web 数据与接口规划
+
+## 数据源总原则
+
+新 Web 使用两层数据源:
+
+1. 生产事实层:FastAPI 后端读取云 MySQL `content_agent_*` 表或后端聚合后的事实数据。
+2. 回放辅助层:本地 `runtime/v1/{run_id}/` JSON / JSONL 兼容导出。
+
+UI 必须明确标识数据来源:
+
+- `生产事实`:来自 DB / 后端聚合。
+- `回放导出`:来自 runtime JSON / JSONL。
+- `缺失`:当前 run 没有该文件或该表无数据。
+- `历史格式`:旧 runtime 文件名或旧结构。
+
+前端不得直接连接 MySQL,也不得直接读取任意文件路径。
+
+## 现有 FastAPI 接口
+
+当前 FastAPI 位于 `content_agent/api.py`。
+
+| Method | Path | 用途 | 当前响应 |
+|---|---|---|---|
+| `POST` | `/runs` | 启动一次运行 | `RunStartResponse` |
+| `GET` | `/runs/{run_id}` | 查询单 run 摘要 | `RunSummaryResponse` |
+| `GET` | `/runs/{run_id}/discovered-content-items` | 查询发现内容 JSONL | `RecordsResponse` |
+| `GET` | `/runs/{run_id}/rule-decisions` | 查询规则判断 JSONL | `RecordsResponse` |
+| `GET` | `/runs/{run_id}/source-path-records` | 查询来源路径 JSONL | `RecordsResponse` |
+| `GET` | `/runs/{run_id}/final-output` | 查询最终输出 JSON | `JsonFileResponse` |
+| `GET` | `/runs/{run_id}/strategy-review` | 查询已有策略复盘 | `JsonFileResponse` |
+| `POST` | `/runs/{run_id}/strategy-review/regenerate` | 显式重新生成策略复盘 | `JsonFileResponse` |
+| `GET` | `/runs/{run_id}/validation` | 查询运行完整性校验 | `ValidationResponse` |
+
+现有缺口:
+
+- 没有 `GET /runs` run 列表。
+- 没有 dashboard 聚合接口。
+- 没有统一 runtime file 白名单读取接口。
+- 没有 Query、Timeline、Content Items 的 Web 聚合视图。
+- 没有 CORS / API base URL 的前端联调配置说明。
+
+## 现有 runtime 文件
+
+当前正式 runtime 文件:
+
+- `source_context.json`
+- `pattern_seed_pack.json`
+- `search_queries.jsonl`
+- `discovered_content_items.jsonl`
+- `content_media_records.jsonl`
+- `pattern_recall_evidence.jsonl`
+- `rule_decisions.jsonl`
+- `walk_actions.jsonl`
+- `run_events.jsonl`
+- `source_path_records.jsonl`
+- `search_clues.jsonl`
+- `final_output.json`
+- `strategy_review.json`
+
+Web 不应该直接绑定本地文件路径。后端如果暴露 runtime 文件,必须按 `RUNTIME_FILENAMES` 白名单读取。
+
+## 当前 DB 可展示实体
+
+当前生产 DB 是 21 张 `content_agent_*` 表。Web 第一版重点展示这些实体:
+
+| 实体 | 表 / 文件 | 用途 |
+|---|---|---|
+| Run | `content_agent_runs` | run 列表、状态、错误、时间 |
+| Source Context | `content_agent_source_contexts` / `source_context.json` | 需求来源和 evidence_pack |
+| Pattern Seed | `content_agent_pattern_seed_packs` / `pattern_seed_pack.json` | seed terms、itemset、category bindings |
+| Query | `content_agent_queries` / `search_queries.jsonl` | Query 文本、生成方式、LLM 变体 |
+| Discovered Content | `content_agent_discovered_content_items` / `discovered_content_items.jsonl` | 发现内容 |
+| Media Record | `content_agent_content_media_records` / `content_media_records.jsonl` | 媒体链接、画像、互动数据 |
+| Pattern Recall | `content_agent_pattern_recall_evidence` / `pattern_recall_evidence.jsonl` | P4 回扣证据 |
+| Rule Decision | `content_agent_rule_decisions` / `rule_decisions.jsonl` | P5 判断结果 |
+| Walk Action | `content_agent_walk_actions` / `walk_actions.jsonl` | P6 游走动作 |
+| Run Event | `content_agent_run_events` / `run_events.jsonl` | 运行事件和失败定位 |
+| Source Path | `content_agent_source_path_records` / `source_path_records.jsonl` | 来源链路 |
+| Search Clue | `content_agent_search_clues` / `search_clues.jsonl` | Query 效果聚合 |
+| Final Output | `content_agent_final_outputs` / `final_output.json` | 最终视图快照 |
+| Strategy Review | `content_agent_strategy_reviews` / `strategy_review.json` | 策略复盘 |
+| Author Asset | `content_agent_author_assets` | 作者资产 |
+| Performance Feedback | `content_agent_performance_feedback` | 后验表现反馈 |
+
+## 新增 Web 友好接口规划
+
+### 1. `GET /runs`
+
+用途:Run 列表页。
+
+查询参数:
+
+- `status`
+- `platform`
+- `platform_mode`
+- `strategy_version`
+- `validation_status`
+- `error_code`
+- `started_from`
+- `started_to`
+- `page`
+- `page_size`
+
+返回建议:
+
+```json
+{
+  "items": [
+    {
+      "run_id": "v1_run_xxx",
+      "policy_run_id": "policy_run_xxx",
+      "status": "success",
+      "platform": "douyin",
+      "platform_mode": "real",
+      "strategy_version": "V1",
+      "validation_status": "pass",
+      "error_code": null,
+      "started_at": "...",
+      "ended_at": "..."
+    }
+  ],
+  "page": 1,
+  "page_size": 20,
+  "total": 0
+}
+```
+
+### 2. `GET /runs/{run_id}/dashboard`
+
+用途:Run 总览页一次加载所需摘要。
+
+返回建议:
+
+- `summary`
+- `file_status`
+- `validation`
+- `final_output_summary`
+- `strategy_review_status`
+- `counts`
+- `data_source_label`
+- `data_origin`
+- `links`
+
+其中 `data_origin` 只允许:
+
+- `production_db`
+- `runtime_export`
+- `mixed_with_runtime_export`
+
+### 3. `GET /runs/{run_id}/runtime-files`
+
+用途:Runtime / Validation 调试页。
+
+返回:
+
+- 文件名
+- 是否存在
+- 记录数
+- 文件类型:json / jsonl
+- 当前合同状态
+- 是否历史 alias
+
+### 4. `GET /runs/{run_id}/runtime-files/{filename}`
+
+用途:调试查看原始 runtime artifact。
+
+要求:
+
+- `filename` 必须在 `RUNTIME_FILENAMES` 白名单内。
+- 支持 `limit` / `offset`。
+- 不允许 `../`、绝对路径或任意文件名。
+
+### 5. `GET /runs/{run_id}/queries`
+
+用途:Query 阶段。
+
+聚合:
+
+- `search_queries`
+- `search_clues`
+- `rule_decisions` 聚合计数
+- Query 失败事件
+
+返回每条 Query:
+
+- `search_query_id`
+- `search_query`
+- `search_query_generation_method`
+- `query_source_terms`
+- `result_count`
+- `pooled_content_count`
+- `review_content_count`
+- `pending_content_count`
+- `rejected_content_count`
+- `search_query_effect_status`
+- `walk_next_step`
+- `failure_reason`
+
+### 6. `GET /runs/{run_id}/timeline`
+
+用途:阶段时间线和运行诊断。
+
+聚合:
+
+- `run_events`
+- `walk_actions`
+- `source_path_records`
+
+返回:
+
+- stage
+- event_type
+- status
+- timestamp
+- source artifact
+- target artifact
+- error_code
+- walk_action_id
+
+### 7. `GET /runs/{run_id}/content-items`
+
+用途:Platform、判断和内容详情页。
+
+查询参数:
+
+- `search_query_id`
+- `decision_action`
+- `effect_status`
+- `author_id`
+- `platform_content_id`
+- `page`
+- `page_size`
+
+聚合:
+
+- discovered content
+- content media
+- pattern recall evidence
+- rule decision
+- source path
+
+返回每条内容:
+
+- 内容基础信息
+- 作者信息
+- Query 来源
+- 互动统计
+- Pattern 回扣结果
+- 规则判断结果
+- source path 引用
+
+## 前端 API 配置
+
+Next.js 前端第一版使用:
+
+- `VITE_CONTENTFIND_API_BASE_URL`
+
+如果 Next.js 使用 `NEXT_PUBLIC_*` 命名,技术实现阶段可选择:
+
+- 保留 `VITE_CONTENTFIND_API_BASE_URL` 作为兼容名。
+- 新增 `NEXT_PUBLIC_CONTENTFIND_API_BASE_URL`。
+- 在 `web/.env.example` 同时写两个 key,但 runtime 只使用一个。
+
+本规划默认:实现时使用 `NEXT_PUBLIC_CONTENTFIND_API_BASE_URL`,并在文档中说明旧 `VITE_CONTENTFIND_API_BASE_URL` 是历史/兼容命名。
+
+## 错误与缺失数据展示
+
+Web 必须优雅处理:
+
+- run 不存在。
+- runtime 文件缺失。
+- DB 中某表暂无数据。
+- validation fail。
+- strategy review 未生成。
+- performance feedback missing。
+- DB run 全是 failed。
+- 历史 runtime 旧命名。
+
+页面不得因为缺一个 artifact 整体白屏。
+
+## 不做
+
+- 前端直连 MySQL。
+- 前端读取本地任意文件路径。
+- 在前端拼接 DB SQL。
+- 把 runtime export 当作生产事实。
+- 把 show 静态 demo 当作真实 run。

+ 380 - 0
web/docs/03_技术开发规划.md

@@ -0,0 +1,380 @@
+# Web 技术开发规划
+
+## 工程形态
+
+新 Web 使用独立 Next.js 应用,代码放在项目根目录 `web/`。
+
+后续推荐目录:
+
+```text
+web/
+  app/
+    page.tsx
+    runs/
+      page.tsx
+      [runId]/
+        page.tsx
+  components/
+    layout/
+    pipeline/
+    cards/
+    tables/
+    drawer/
+    badges/
+  features/
+    runs/
+    pipeline/
+    source/
+    query/
+    platform/
+    rules/
+    walk/
+    assets/
+    review/
+    runtime/
+  lib/
+    api/
+    adapters/
+    formatters/
+    status/
+  docs/
+```
+
+本轮只写规划文档,不初始化 Next.js,不生成 `package.json`,不新增前端依赖。
+
+## 技术原则
+
+- 视觉复刻 `show`,数据层重写。
+- 组件按业务阶段拆分,不再写 4000 行单文件。
+- API client 集中管理,不在组件里散落 `fetch`。
+- Adapter 负责把后端数据变成 UI view model。
+- UI 不直接依赖 runtime 原始字段的所有细节。
+- 缺数据时显示明确空状态,不白屏。
+- 生产事实和回放导出使用不同 badge。
+
+## 前端模块规划
+
+### `features/runs`
+
+职责:
+
+- Run 列表。
+- Run 筛选。
+- Run 状态 badge。
+- 最近运行入口。
+
+依赖接口:
+
+- `GET /runs`
+- `GET /runs/{run_id}/dashboard`
+
+### `features/pipeline`
+
+职责:
+
+- 顶部 7 阶段 Pipeline。
+- 阶段状态高亮。
+- 阶段切换。
+
+视觉参考:
+
+- `show/src/App.tsx` 的 `pipelineStages`
+- `PipelineHeader`
+- `show/src/styles.css` 的 `.pipeline-header`、`.pipeline-grid`、`.pipeline-step`
+
+### `features/source`
+
+职责:
+
+- 数据源阶段。
+- evidence_pack 展示。
+- Pattern seed 和 DemandAgent 来源说明。
+
+依赖接口:
+
+- dashboard 中的 data source 摘要。
+- runtime file `source_context.json`。
+- runtime file `pattern_seed_pack.json`。
+
+### `features/query`
+
+职责:
+
+- Query 工作台。
+- Query 列表、生成方式、来源字段。
+- Query 效果。
+- LLM 变体输入快照。
+
+依赖接口:
+
+- `GET /runs/{run_id}/queries`
+
+### `features/platform`
+
+职责:
+
+- 发现内容列表。
+- 内容详情。
+- 媒体记录。
+- 平台 raw payload 摘要。
+
+依赖接口:
+
+- `GET /runs/{run_id}/content-items`
+- 必要时 runtime file `content_media_records.jsonl`
+
+### `features/rules`
+
+职责:
+
+- 规则判断卡片。
+- hard gate / scorecard / threshold 展示。
+- RuleDecision 抽屉。
+
+依赖接口:
+
+- `GET /runs/{run_id}/content-items`
+- `GET /runs/{run_id}/runtime-files/rule_decisions.jsonl`
+
+### `features/walk`
+
+职责:
+
+- Walk action 工作台。
+- edge 筛选。
+- source path 追溯。
+- Query 下一页 / 作者 / tag 路径展示。
+
+依赖接口:
+
+- `GET /runs/{run_id}/timeline`
+- `GET /runs/{run_id}/runtime-files/walk_actions.jsonl`
+- `GET /runs/{run_id}/runtime-files/source_path_records.jsonl`
+
+### `features/assets`
+
+职责:
+
+- 内容资产。
+- 作者资产。
+- 搜索线索资产。
+- 淘汰记录。
+
+依赖接口:
+
+- `GET /runs/{run_id}/final-output`
+- 后续资产聚合接口。
+
+### `features/review`
+
+职责:
+
+- 策略复盘。
+- Query / rule / walk 建议。
+- performance feedback 缺失状态。
+
+依赖接口:
+
+- `GET /runs/{run_id}/strategy-review`
+- `POST /runs/{run_id}/strategy-review/regenerate`
+
+### `features/runtime`
+
+职责:
+
+- runtime file 状态。
+- validation findings。
+- 原始 artifact 调试。
+
+依赖接口:
+
+- `GET /runs/{run_id}/runtime-files`
+- `GET /runs/{run_id}/runtime-files/{filename}`
+- `GET /runs/{run_id}/validation`
+
+## 后端配套规划
+
+### API Service
+
+新增后端 service 层,不建议在 `api.py` 里直接拼复杂数据。
+
+建议新增:
+
+- `content_agent/dashboard_service.py`
+- 或 `content_agent/business_modules/dashboard/`
+
+职责:
+
+- run list 聚合。
+- dashboard summary 聚合。
+- query 聚合。
+- content item 聚合。
+- timeline 聚合。
+- runtime file 安全读取。
+
+### CORS
+
+开发期需要允许 Next.js dev server 调 FastAPI。
+
+建议:
+
+- 新增 env:`CONTENT_AGENT_WEB_CORS_ORIGINS`
+- 默认开发允许 `http://127.0.0.1:3000` 和 `http://localhost:3000`
+- 生产环境显式配置
+
+### Runtime File 白名单
+
+后端必须使用 `RUNTIME_FILENAMES` 限制可读文件。
+
+禁止:
+
+- 任意 path
+- `../`
+- 绝对路径
+- 未登记 runtime 文件名
+
+### DB 与 runtime 的读取策略
+
+默认读取生产事实层。
+
+当生产事实缺少完整成功链路、用户选择回放模式时,可读取 runtime export,但 response 必须带:
+
+```json
+{
+  "data_origin": "runtime_export"
+}
+```
+
+如果同时使用 DB 和 runtime:
+
+```json
+{
+  "data_origin": "mixed_with_runtime_export"
+}
+```
+
+## 开发顺序
+
+### Web-0:文档与合同确认
+
+本轮完成:
+
+- `web/README.md`
+- 产品功能规划
+- 数据与接口规划
+- 技术开发规划
+- show 视觉迁移清单
+
+### Web-1:后端 Web API
+
+先补:
+
+- `GET /runs`
+- `GET /runs/{run_id}/dashboard`
+- `GET /runs/{run_id}/runtime-files`
+- `GET /runs/{run_id}/runtime-files/{filename}`
+
+验收:
+
+- FastAPI tests 覆盖列表、dashboard、白名单读取、非法 filename。
+- 不影响现有 `/runs/{run_id}` 等接口。
+
+### Web-2:Next.js 初始化
+
+在 `web/` 初始化 Next.js。
+
+最低要求:
+
+- TypeScript
+- App Router
+- CSS Modules 或全局 CSS
+- API base URL 配置
+- 基础 layout
+
+不在这一步接复杂业务。
+
+### Web-3:Run 列表与总览
+
+实现:
+
+- Run 列表。
+- Run 总览。
+- Pipeline 阶段条。
+- validation 状态。
+- artifact 状态。
+
+### Web-4:阶段详情
+
+实现:
+
+- 数据源。
+- Query。
+- Platform / 内容。
+- 判断。
+- 游走。
+- 资产。
+- 策略学习。
+
+### Web-5:视觉对齐 show
+
+对齐:
+
+- 布局密度。
+- 按钮形态。
+- 筛选器。
+- 抽屉。
+- 卡片。
+- 状态 badge。
+- trace strip。
+
+### Web-6:回放模式
+
+实现 runtime export 的只读回放。
+
+要求:
+
+- 明确标注“回放导出”。
+- 支持历史缺文件。
+- 支持旧 runtime alias 的提示。
+
+## 测试规划
+
+### 后端测试
+
+- `GET /runs` 正常返回列表。
+- `GET /runs` 支持筛选。
+- `GET /runs/{run_id}/dashboard` 返回 summary / counts / data_origin。
+- `GET /runs/{run_id}/runtime-files` 返回 13 个 runtime 文件状态。
+- 非白名单 filename 返回结构化错误。
+- 不存在 run 返回 `RUN_NOT_FOUND`。
+- strategy review GET 不产生写副作用。
+
+### 前端测试
+
+后续 Next.js 初始化后再加:
+
+- Run 列表渲染。
+- Run 总览渲染。
+- 阶段切换。
+- 空状态。
+- runtime export badge。
+- API 错误状态。
+
+### 视觉验收
+
+用 Playwright 对比:
+
+- 顶部 Pipeline 是否存在 7 阶段。
+- 数据源页是否为筛选 + 左列表 + 右详情。
+- 判断页是否有规则卡和抽屉。
+- 游走页是否有筛选器和边详情。
+- 移动端不作为第一优先级;当前 show 本身是宽屏工作台。
+
+## 不做
+
+- 本轮不搭 Next.js 代码。
+- 本轮不改 FastAPI。
+- 本轮不改 DB。
+- 本轮不改 `show/`。
+- 后续也不从前端直连 MySQL。
+- 不把 `show` 静态数据迁移成事实源。

+ 288 - 0
web/docs/04_show视觉迁移清单.md

@@ -0,0 +1,288 @@
+# show 视觉迁移清单
+
+本文件用于指导新 `web/` 复刻旧 `show/` 的视觉和交互。迁移目标是“用户看起来像 show”,不是复用旧静态数据。
+
+## 总体结论
+
+`show/` 当前是 Vite React 单页应用:
+
+- 入口:`show/src/main.tsx`
+- 主体:`show/src/App.tsx`
+- 样式:`show/src/styles.css`
+- 静态构建:`show/dist/`
+
+`show/src/App.tsx` 是单文件大组件,包含类型、静态数据、页面组件和全部交互。新 Web 不应继续这种结构,应拆为 Next.js 页面、feature 组件和 adapter。
+
+## 必须保留的视觉 / 交互
+
+### 1. 顶部 PipelineHeader
+
+来源:
+
+- `pipelineStages`
+- `PipelineHeader`
+- `.pipeline-header`
+- `.pipeline-grid`
+- `.pipeline-step`
+
+保留:
+
+- 7 阶段横向条。
+- 当前阶段蓝色高亮。
+- 数据源和 Platform 可作为下拉选择区域。
+- 其它阶段作为点击按钮。
+
+替换:
+
+- 数据源选项以当前 V1 真实链路为准。
+- 平台默认只显示抖音;其他平台放后续能力或隐藏。
+
+### 2. DataSourceStageBrowser
+
+来源:
+
+- `DataSourceStageBrowser`
+- `SourceFilterBar`
+- `SourceRecordList`
+- `SourceRecordDetail`
+- `.source-filter-bar`
+- `.source-browser`
+- `.source-list-panel`
+- `.source-detail-panel`
+
+保留:
+
+- 顶部筛选条。
+- 搜索框。
+- 左侧记录列表。
+- 左侧列表可收起。
+- 右侧详情卡片。
+
+替换:
+
+- 静态 Pattern / Case / 历史作者 / 热点 / 养号记录。
+- 改为真实 run 的 source context、evidence pack、pattern seed。
+
+降级:
+
+- Case 独立入口。
+- 历史优质搜索记录。
+- 历史沉淀账号。
+- 热点。
+- 养号。
+
+这些默认不作为 V1 Web 的主入口。
+
+### 3. QueryWorkshop
+
+来源:
+
+- `QueryWorkshopView`
+- `PromptModal`
+- Query evidence / prompt / query group 三列布局
+
+保留:
+
+- Query 工作台。
+- evidence、prompt、query 分区。
+- Prompt 展开查看。
+- Query group 说明。
+
+替换:
+
+- 静态 prompt 文案。
+- 静态 query 示例。
+
+接入:
+
+- `search_queries.jsonl`
+- Query 生成方式。
+- LLM 输入快照。
+- `search_clues.jsonl` 聚合效果。
+
+### 4. JudgeRulePackBoard
+
+来源:
+
+- `JudgeRulePackBoard`
+- `RulePackCard`
+- `RulePackDrawer`
+
+保留:
+
+- 规则包卡片。
+- 分组展示。
+- 抽屉详情。
+- hard gate / scorecard / threshold / output 分区。
+
+替换:
+
+- 静态规则解释。
+- 静态 scorecard。
+
+接入:
+
+- `rule_decisions.jsonl`
+- `decision_replay_data`
+- `scorecard`
+- `triggered_blocking_rules`
+- `decision_reason_code`
+
+### 5. WalkStrategyWorkbench
+
+来源:
+
+- `WalkStrategyWorkbench`
+- `walkFilterGroups`
+- `walkStrategyRows`
+- `WalkStrategyEdgeDetail`
+
+保留:
+
+- 游走筛选器。
+- 策略边表格。
+- 当前选中边详情。
+- 继续 / 停止 / 降预算等动作表达。
+
+替换:
+
+- 静态 walk events。
+- 小红书、共创、相似作者等旧占位。
+
+接入:
+
+- `walk_actions.jsonl`
+- `source_path_records.jsonl`
+- `search_clues.jsonl`
+- `run_events.jsonl`
+
+### 6. AssetFlowBoard
+
+来源:
+
+- `AssetFlowBoard`
+- `assetFlows`
+
+保留:
+
+- 资产流程卡。
+- 内容资产、作者资产、来源关系、搜索线索的视觉分区。
+
+替换:
+
+- “页面模拟,不入库”。
+- 静态资产示例。
+
+接入:
+
+- `final_output.json`
+- `content_assets`
+- `author_assets`
+- `search_clues`
+- `reject_records`
+
+### 7. StrategyLearningBoard
+
+来源:
+
+- `StrategyLearningBoard`
+- `learningMethodSteps`
+- `learningTraceGroups`
+- `learningRecommendations`
+- `learningExperiments`
+
+保留:
+
+- 策略学习方法区。
+- trace 数据分组。
+- 建议列表。
+- 实验 / 下轮动作表达。
+
+替换:
+
+- 静态学习建议。
+- 静态实验示例。
+
+接入:
+
+- `strategy_review.json`
+- `performance_feedback`
+- `suggestions`
+- `productive_paths`
+- `top_reject_reasons`
+
+## 必须删除或降级的 show 旧口径
+
+### 不进入 V1 默认展示
+
+- 小红书。
+- 快手。
+- B 站。
+- 视频号。
+- 票圈。
+- 热点。
+- 养号。
+- 历史作者。
+- 共创作者。
+- 相似作者。
+- 推荐流。
+- Case 独立数据源。
+
+### 只能作为“后续能力”展示
+
+如果产品需要保留这些按钮的视觉位置,应以禁用态或后续能力卡展示:
+
+- 文案:`后续能力`
+- 状态:disabled
+- 不触发 API
+- 不参与真实 run 统计
+
+### 不迁移为事实的静态内容
+
+- `demoScenarios`
+- 静态 Pattern ID 和 Case ID。
+- 静态作者作品接口返回。
+- 静态 query workshop 文案。
+- 静态规则包解释。
+- 静态策略学习建议。
+- “页面模拟,不入库”相关表格。
+
+## 新 Web 的视觉验收标准
+
+用户第一眼应觉得它和 show 是同一个产品:
+
+- 顶部阶段条相似。
+- 页面密度相似。
+- 卡片边框、圆角、表格和状态 badge 相似。
+- 数据源页的左右结构相似。
+- 判断页的规则卡和抽屉相似。
+- 游走页的筛选与边详情相似。
+
+但用户继续点击后,应看到真实 run 数据,而不是静态样例。
+
+## 迁移实施建议
+
+1. 先复制视觉 token:
+   - 字体。
+   - 背景色。
+   - 卡片边框。
+   - badge。
+   - 表格密度。
+
+2. 再拆组件:
+   - Pipeline。
+   - StageLayout。
+   - RecordList。
+   - DetailPanel。
+   - RuleDrawer。
+   - WalkWorkbench。
+
+3. 最后接数据:
+   - Run list。
+   - Dashboard。
+   - Queries。
+   - Content items。
+   - Timeline。
+   - Runtime files。
+
+不要反过来先搬静态数据。

+ 409 - 0
web/docs/05_Web实施简报.md

@@ -0,0 +1,409 @@
+# Web 实施简报
+
+## 状态
+
+本简报用于 Web 可视化正式开发前的执行拆分。它只约束 `web/` 新项目和必要的后端只读 Web API,不要求修改 `show/`,也不把 `show/` 的静态数据迁移为事实源。
+
+当前依据:
+
+- `web/docs/01_产品功能规划.md` 已定义页面和用户目标。
+- `web/docs/02_数据与接口规划.md` 已盘点现有 FastAPI、DB 表和 runtime 文件。
+- `web/docs/03_技术开发规划.md` 已规划 Next.js 目录、后端配套和开发顺序。
+- `web/docs/04_show视觉迁移清单.md` 已明确哪些 show 视觉保留、哪些旧入口降级。
+
+## 总目标
+
+开发一个独立 Next.js Web 应用,让用户用接近 `show/` 的视觉和交互查看真实 CFA run 数据:
+
+- DB 数据是生产事实。
+- runtime JSON / JSONL 是回放导出。
+- 页面不伪造完整成功链路。
+- 前端不直连 MySQL,不任意读本地文件路径。
+- `show/` 只作为视觉参考,不再作为未来事实源。
+
+## 不修改范围
+
+- 不在 `show/` 中继续开发新功能。
+- 不把旧 show 静态样例作为真实数据。
+- 不在前端直接读取 MySQL。
+- 不在前端传任意文件路径给后端。
+- 不新增 DB 表作为 Web 前置条件。
+- 不改变已有 run 成功响应字段。
+- 不改变 P0-P6 业务链路语义。
+
+## Web-A:后端只读 Web API
+
+### 目标
+
+先补齐 Web 需要的只读聚合接口。前端第一版不要直接拼 runtime 文件,也不要在组件里理解所有 DB 表细节。
+
+### 修改范围
+
+建议新增:
+
+- `content_agent/dashboard_service.py`
+- 或 `content_agent/business_modules/dashboard/`
+
+建议修改:
+
+- `content_agent/api.py`
+- `content_agent/integrations/runtime_files.py`
+- `content_agent/integrations/database_runtime.py`
+
+### 涉及接口
+
+新增规划接口:
+
+- `GET /runs`
+- `GET /runs/{run_id}/dashboard`
+- `GET /runs/{run_id}/queries`
+- `GET /runs/{run_id}/timeline`
+- `GET /runs/{run_id}/content-items`
+- `GET /runs/{run_id}/runtime-files`
+- `GET /runs/{run_id}/runtime-files/{filename}`
+
+保留现有接口:
+
+- `POST /runs`
+- `GET /runs/{run_id}`
+- `GET /runs/{run_id}/discovered-content-items`
+- `GET /runs/{run_id}/rule-decisions`
+- `GET /runs/{run_id}/source-path-records`
+- `GET /runs/{run_id}/final-output`
+- `GET /runs/{run_id}/strategy-review`
+- `POST /runs/{run_id}/strategy-review/regenerate`
+- `GET /runs/{run_id}/validation`
+
+### 数据合同
+
+`GET /runs` 返回 run 列表,最少包含:
+
+- `run_id`
+- `policy_run_id`
+- `status`
+- `platform`
+- `platform_mode`
+- `strategy_version`
+- `validation_status`
+- `error_code`
+- `started_at`
+- `ended_at`
+
+`GET /runs/{run_id}/dashboard` 返回总览摘要,最少包含:
+
+- `summary`
+- `counts`
+- `file_status`
+- `validation`
+- `final_output_summary`
+- `strategy_review_status`
+- `data_origin`
+
+`data_origin` 只允许:
+
+- `production_db`
+- `runtime_export`
+- `mixed_with_runtime_export`
+
+`GET /runs/{run_id}/runtime-files/{filename}` 必须只允许读取 `RUNTIME_FILENAMES` 白名单内文件。
+
+### 验证命令
+
+```bash
+uv run pytest tests/test_api.py -q
+uv run python scripts/validate_schema_registry.py
+uv run --with pymysql python scripts/validate_content_agent_db.py --env-file .env
+```
+
+### 失败归因
+
+- API 返回缺字段:归因到 dashboard service 聚合合同。
+- runtime 文件读取越界:归因到白名单校验。
+- DB 查不到完整成功链路:归因到当前数据状态,页面只能展示失败诊断或空状态,不能伪造数据。
+- schema validator 失败:归因到 registry / schema,不归因到 Web 前端。
+
+## Web-B:Next.js 项目初始化
+
+### 目标
+
+在 `web/` 下初始化独立 Next.js 应用,建立项目骨架、基础布局和 API client。
+
+### 修改范围
+
+新增:
+
+- `web/package.json`
+- `web/next.config.*`
+- `web/tsconfig.json`
+- `web/app/`
+- `web/components/`
+- `web/features/`
+- `web/lib/`
+
+### 目录合同
+
+```text
+web/
+  app/
+  components/
+    layout/
+    pipeline/
+    cards/
+    tables/
+    drawer/
+    badges/
+  features/
+    runs/
+    pipeline/
+    source/
+    query/
+    platform/
+    rules/
+    walk/
+    assets/
+    review/
+    runtime/
+  lib/
+    api/
+    adapters/
+    formatters/
+    status/
+```
+
+### 配置
+
+前端 API base URL 建议使用:
+
+- `NEXT_PUBLIC_CONTENTFIND_API_BASE_URL`
+
+如果为了兼容旧规划保留 `VITE_CONTENTFIND_API_BASE_URL`,只能作为文档兼容名,不作为 Next.js 主配置名。
+
+### 验证命令
+
+```bash
+cd web
+npm run lint
+npm run build
+```
+
+### 失败归因
+
+- build 失败:归因到前端依赖或 TypeScript 类型。
+- API base URL 缺失:开发期显示配置错误页,不静默请求空地址。
+- CORS 失败:归因到 FastAPI CORS 配置,不归因到页面组件。
+
+## Web-C:Run 列表与总览
+
+### 目标
+
+完成 Web 第一屏:Run 列表、Run 总览、顶部 7 阶段 Pipeline。
+
+### 页面
+
+- `/`
+- `/runs`
+- `/runs/[runId]`
+
+### 组件
+
+- `RunList`
+- `RunStatusBadge`
+- `RunOverviewHeader`
+- `PipelineHeader`
+- `PipelineStageCard`
+- `DataOriginBadge`
+
+### 数据来源
+
+- `GET /runs`
+- `GET /runs/{run_id}/dashboard`
+
+### show 视觉参考
+
+保留:
+
+- 顶部 7 阶段横向结构。
+- 阶段状态颜色。
+- 左列表右详情的信息密度。
+
+替换:
+
+- 静态 scenario 数据。
+- 手写的 run 成功样例。
+
+### 验证命令
+
+```bash
+cd web
+npm run lint
+npm run build
+```
+
+后续有 Playwright 后增加:
+
+```bash
+cd web
+npm run test:e2e
+```
+
+## Web-D:阶段详情页面
+
+### 目标
+
+实现真实 run 的阶段详情展示。
+
+### 功能范围
+
+数据源阶段:
+
+- `source_context`
+- `pattern_seed_pack`
+- evidence pack 摘要
+
+Query 阶段:
+
+- query 文本
+- generation method
+- LLM 变体来源
+- query effect status
+
+Platform / 发现内容阶段:
+
+- discovered content
+- media record
+- pattern recall evidence
+
+判断阶段:
+
+- rule decision
+- hard gate
+- scorecard
+- threshold action
+
+游走阶段:
+
+- walk action
+- source path
+- query next page / author / tag 来源
+
+资产沉淀阶段:
+
+- final output
+- author assets
+- search clues
+
+策略学习阶段:
+
+- strategy review
+- regeneration action
+
+### 数据来源
+
+- `GET /runs/{run_id}/queries`
+- `GET /runs/{run_id}/content-items`
+- `GET /runs/{run_id}/timeline`
+- `GET /runs/{run_id}/final-output`
+- `GET /runs/{run_id}/strategy-review`
+- `GET /runs/{run_id}/runtime-files/{filename}`
+
+### 验证重点
+
+- 缺文件显示“缺失”,不白屏。
+- DB 与 runtime 混合时显示 `mixed_with_runtime_export`。
+- 失败 run 也能展示错误定位。
+- pending / failed / rule_blocked / partial_success 状态不被错误翻译。
+
+## Web-E:视觉迁移与交互对齐
+
+### 目标
+
+让新 Web 看起来和 `show` 的核心交互一致,但组件和数据层全部重写。
+
+### 保留视觉
+
+- PipelineHeader
+- DataSourceStageBrowser
+- QueryWorkshop
+- JudgeRulePackBoard
+- WalkStrategyWorkbench
+- AssetFlowBoard
+- StrategyLearningBoard
+
+### 删除或隐藏
+
+- 小红书
+- 快手
+- B站
+- 视频号
+- 票圈
+- 热点
+- 养号
+- 共创作者
+- 相似作者
+- 历史作者库
+- Case 独立数据源
+
+这些只允许作为旧 show 入口或未来能力说明,不进入 V1 默认展示。
+
+### 验收方式
+
+- 桌面视口截图。
+- 移动视口基础可读。
+- 文本不溢出按钮和卡片。
+- 左列表右详情切换不抖动。
+- 抽屉打开后信息完整可读。
+
+## Web-F:运行回放与调试页
+
+### 目标
+
+提供 runtime / validation 调试页,给工程排错使用,不作为业务事实主视图。
+
+### 功能
+
+- runtime file 列表。
+- runtime JSON / JSONL 查看。
+- validation findings。
+- file status。
+- data origin badge。
+
+### 安全边界
+
+- 文件名必须来自白名单。
+- 不接受绝对路径。
+- 不接受 `../`。
+- 不展示 token / password / cookie / authorization。
+
+### 验证命令
+
+```bash
+rg -n "PASSWORD=|TOKEN=|API_KEY=|SECRET=|Authorization:|Cookie:" web
+```
+
+期望没有真实敏感赋值。
+
+## 总体验收
+
+开发完成后建议执行:
+
+```bash
+uv run pytest tests/test_api.py -q
+uv run python scripts/validate_schema_registry.py
+uv run --with pymysql python scripts/validate_content_agent_db.py --env-file .env
+cd web && npm run lint && npm run build
+```
+
+如果已有 Playwright:
+
+```bash
+cd web && npm run test:e2e
+```
+
+## 开发纪律
+
+- 先补后端只读聚合 API,再做前端页面。
+- 前端只读 API,不直接查 DB。
+- show 只做视觉参考,不做数据依赖。
+- runtime 回放必须和生产事实分开标识。
+- 不为了页面方便新增模糊 `utils.ts`;格式化、状态映射、API adapter 分目录维护。
+- 不把 P6 之外的未来边能力默认展示成已实现。