# PRD · 投研看板交互升级 —— 从「只读看板」到「可探索的驾驶舱」

> 版本 v1.0 · 2026-07-14 · 状态：待评审
> 对象：卫星互联网投研看板（`index.html`，oaf.world 根）
> 网页版（含界面设计稿）：[prd-dashboard-interactive.html](../prd-dashboard-interactive.html)

---

## 1. 背景与目的

oaf.world 的**投研看板**（根 `index.html`）是卫星互联网决策的门面页：9 个面板（CEO Brief / 投资 Brief / 事件流 / 风险预警 / 主线热度趋势 / 公司矩阵 / 数据来源账本 / 叙事链 / 知识图谱·概念热度），由 agent 管线每 6 小时刷新、页面每 10 分钟自动拉新。

但它当前是**纯只读**：取数即渲染，用户能做的交互仅限右上齿轮（切数据源）与刷新。信息密度很高，却**无法按自己的问题去切片**——想只看「运载发射」主线近 7 天的事件、想点一个概念看它牵动哪些公司、想把「过滤后的看板视角」分享给同事，目前都做不到。

本 PRD 的目的：**给看板加一层「交互层」，把只读看板升级为可探索的驾驶舱**，让用户能在同一页里按时间窗 / 主线 / 概念 / 关键词切片、跨面板联动、逐条下钻、并把视角深链分享——**全部在已取的真实数据上操作，不新增任何编造**。

**北极星隐喻**：报表 → 驾驶舱。度量：看板会话时长、过滤/搜索使用率、深链分享回访、看板→工作台/议事厅穿透率。

---

## 2. 现状盘点 —— 看板有什么、缺什么

| 面板 | 数据源 | 现状 | 可交互性缺口 |
|---|---|---|---|
| CEO / 投资 Brief | `/decision/weekly` | 只读文本 | 无法按主线聚焦 |
| 事件流 | `/events` | 一行摘要列表，含 `concept_tags`/`thread` | 不能展开详情、不能按主线/时间过滤、概念 tag 不可点 |
| 风险预警 | `/alerts` | 只读列表 | 不能按主线/严重度过滤、不能下钻 |
| 主线热度趋势 | `/trend` | 折线图（5 主线 × 时间） | 图例不可 toggle、无 hover 读数、不能刷选联动 |
| 公司矩阵 | `/decision/weekly` | 只读表 | 不能排序/按市场筛选、公司不可深链工作台 |
| 数据来源账本 | `/sources/ledger` | 只读 | — |
| 叙事链 | `/decision/weekly` | 只读 | — |
| 知识图谱·概念热度 | `agent/docs/sample/concept_stats.json` | 概念 chip（已深链 wiki） | 不能按主线过滤、点概念不能反查关联事件 |

**共性缺口**：① 无**全局切片**（时间窗 / 主线）；② 面板之间**互不联动**（点这里不影响那里）；③ 列表项**不能下钻**（看不到详情/来源/关联公司）；④ 状态**不可分享**（URL 无参数）；⑤ 无**个性化**（不能收藏关注）。

---

## 3. 设计原则（交互层的铁律，对齐既有不变量）

1. **交互只切片，不造数**：过滤 / 排序 / 搜索 / 联动**只改变已取真实数据的可见性与顺序**，绝不新增、补全或推断任何数值。过滤后为空 → **诚实空态**（「该主线 / 时间窗内暂无事件」），绝不用占位数据填充。
2. **数字仍来自工具，叙事仍来自 LLM**：交互不改变任何数值；LLM 生成的叙事段落原样展示，不因交互二次编辑。所有交互产物（如「近 7 天该主线事件数」）是对真实数据的**确定性计数**。
3. **无账号、无 PII、无上传**：自选关注 / 布局偏好只落 `localStorage`（本地、可清除），**不需登录、不上传、不采集行为数据**。凭证仍只在数据源设置层。
4. **状态可深链、可回退**：当前 时间窗 / 主线 / 概念 / 搜索 / 展开项 编码进 URL query（同工作台 `?v=` 深链），刷新与分享可还原，`history` 可前进后退。**默认无参数 = 全量看板**（SEO / 首屏不受影响）。
5. **离线可测**：过滤 / 搜索 / 排序 / URL 编解码 / 计数全为**纯函数**，离线单测覆盖；交互路径用 Playwright e2e 断言。
6. **免责常显、自动刷新不打断**：免责声明不被任何交互隐藏；10 分钟自动刷新**保留当前过滤态**，不把用户跳回全量。

---

## 4. 需求详述

### P0-A 全局切片条 + 跨面板联动（核心）

**用户故事**：作为卫星互联网投资者，我想用一个全局控件把整块看板按**时间窗**和**主线**切片，让所有面板只显示我关心的那一片。

**功能说明**
1. 顶部（status 条下方）新增**全局切片条**，两组 chips：
   - **时间窗**：`近7天 · 近30天 · 近90天 · 全部`（默认全部）。
   - **主线**：`全部 · 核心网 · 终端 · 芯片 · 运载发射 · 运营支撑`（默认全部，配色沿用主线色）。
2. 选中后**全看板联动**：事件流、风险预警、公司矩阵、概念热度**只渲染命中**该主线/时间窗的条目；趋势图高亮选中主线、淡化其余；Brief 顶部加一行「当前视角：运载发射 · 近 7 天 · N 条事件」。
3. **趋势图 → 主线联动**：点趋势图某条主线线（或其图例）= 把全局主线切到该主线（cross-panel brushing）。
4. 空态诚实：某面板在当前切片下无数据 → 显示「该主线 / 时间窗内暂无<该面板>」，不留空、不编。

**验收**：切「运载发射 + 近7天」后各面板计数正确（纯函数单测）；趋势图点线联动主线（Playwright）；空切片显示诚实空态；默认无切片 = 现状全量。

**不变量检查**：仅按 `event.thread` / `event.date`（真实字段）过滤已取数据；计数是确定性计数；空态不编。

---

### P0-B 列表下钻（事件 / 预警展开 + 概念反查 + 深链联动）

**用户故事**：作为投资者，我想点开一条事件看到它的完整描述、概念标签、来源和牵动的公司，并能一键跳去工作台深挖或带进议事厅。

**功能说明**
1. **事件 / 预警行可展开**：点一行 → 就地展开详情卡：完整描述、`concept_tags` chips、来源链接、`thesis_impact`（若有，标注为 AI 研判）、**关联上市公司深链**（`/web/app?co=<uid>` 进工作台公司页）。
2. **概念 chip 可点 = 反查联动**：点事件详情或概念热度里的某概念 → 把全局「概念」过滤设为该概念，看板只留含此概念的事件/公司（与知识图谱面板互为联动）；概念 chip 上仍保留「→ wiki 词条」次级入口。
3. **看板 → 议事厅**：事件/公司详情卡加「⚖ 带入议事厅」，深链工作台议事厅并预填题目（接工作台 P0-A `openCouncilFor`）。
4. 展开态计入 URL（`?ev=<id>`），分享即定位到该条展开。

**验收**：点事件展开出详情卡含来源/概念/公司深链；点概念过滤全看板 + wiki 次级入口仍在；「带入议事厅」跳工作台并预填；`?ev=` 深链定位（Playwright）。

**不变量检查**：详情字段全部来自 `/events` 已有字段，无源的段（如某事件无 thesis_impact）不显示、不编；公司深链只对有 `uid` 的上市公司可点。

---

### P0-C URL 状态深链 · 可分享的看板视角

**用户故事**：作为分析师，我想把「运载发射 · 近7天 · 概念=星间链路」这个筛好的看板视角发给同事，他打开即是同一视角。

**功能说明**
1. 全局状态 `{window, thread, concept, q, ev}` 双向绑定 URL query；任何交互即时 `history.replaceState` 同步（不刷屏）。
2. 载入时解析 URL 还原状态；`popstate` 支持浏览器前进/后退。
3. 顶部加「🔗 复制当前视角链接」；「重置」一键回全量。
4. 默认无参数 = 全量看板（首屏 / SEO 不变）。

**验收**：设过滤后 URL 出现对应参数；带参 URL 打开即还原（Playwright）；后退键回上一视角；复制链接可用。

---

### P1-A 全局搜索 / 快速跳转（⌘K）

**用户故事**：我想按 `⌘K` 打开搜索，键入「铱星 / 星间链路 / 发射」，直接跳到相关公司页 / 过滤看板 / 定位概念。

**功能说明**：快捷键 `⌘K`/`Ctrl+K`（或点搜索框）唤起命令面板，在**已取数据**（事件 / 公司 / 概念）里模糊匹配 → 分组命中列表 → 回车：公司→深链工作台公司页 · 概念→设为全局概念过滤 · 事件→展开定位。纯客户端，无新增网络。

**验收**：`⌘K` 唤起；键入命中分组正确；选公司深链 / 选概念过滤 / 选事件定位；无匹配显示「未找到」（Playwright + 纯函数单测搜索排序）。

---

### P1-B 自选关注（localStorage · 无需登录）

**用户故事**：我想把「铱星通信」「运载发射」主线、「星间链路」概念收藏，用「⭐ 我的关注」一键只看它们相关的内容。

**功能说明**：公司 / 主线 / 概念旁加 ★ 收藏按钮 → 落 `localStorage`（本地、可导出/清除）；全局加「⭐ 我的关注」开关，开启后看板只留与关注项相关的事件/热度/公司。**无账号、无上传、无 PII**。

**验收**：★ 收藏后刷新仍在（localStorage）；开「我的关注」过滤生效；清空后回全量；隐私说明标注「仅存本地」。

---

### P1-C 趋势图交互

**功能说明**：图例点击 toggle 各主线线显隐；hover 十字线读数（日期 × 各主线值，mono）；可选：刷选日期区间 → 联动全局时间窗。数值只读、不改。

**验收**：toggle 主线线显隐；hover 出读数；（若做刷选）刷选联动时间窗（Playwright）。

---

### P1-D 公司矩阵排序 / 筛选

**功能说明**：矩阵表头可点排序（信号 / 热度 / 涨跌，升降序）；按市场（A股 / 海外）筛选 chip；公司名深链工作台公司页。排序为确定性稳定排序。

**验收**：点表头排序正确（纯函数单测含并列稳定性）；市场筛选生效；公司深链可达。

---

### P2

- **P2-B 布局自定义** ✅ **已上线**：每面板折叠/展开 + 显示/隐藏 + ↑↓ 重排（9 面板），偏好落 `localStorage`（`ir_dash_layout_v1`）持久化；「🎛 布局」菜单集中管理 + 一键恢复默认。仅本地无上传。
- **P2-C 对比模式** ✅ **已上线**：「⚖ 对比」两条主线并排比**确定性指标**——最新热度 / 动量(后半−前半) / 本窗口事件数 / 涉及概念数 / 龙头(composite)；较大值高亮；事件数按当前时间窗。缺数留白不编。
- **P2-A 反馈 / 标注**（roadmap）：对事件「标记关注 / 无关」、提交反馈——需轻后端持久化，缺持久化源不硬做（本期不做）。
- **P2-D 实时协作光标 / 多人视角**（roadmap）：偏离工具定位，暂缓（仅记灵感）。

---

## 5. 界面设计

> 视觉规范：**零新增颜色**，全部沿用站点令牌（`--paper/--ink/--gold/--clay/--sage/--sky/--plum`、衬线标题、mono 数字）。高保真设计稿见网页版 [prd-dashboard-interactive.html](../prd-dashboard-interactive.html)。

### 5.1 全局切片条（P0-A / P0-C）

```
┌─────────────────────────────────────────────────────────────────────┐
│ ● 自动更新看板        [🔗 复制视角] [重置]                      ⚙   │
├─────────────────────────────────────────────────────────────────────┤
│ 时间窗: (近7天) 近30天 近90天  全部     主线: 全部 核心网 终端 芯片    │
│                                              (运载发射) 运营支撑  ⭐关注 │
├─────────────────────────────────────────────────────────────────────┤
│ 当前视角: 运载发射 · 近7天 · 12 条事件 · 5 家公司 · 8 个概念           │
└─────────────────────────────────────────────────────────────────────┘
```

### 5.2 事件下钻（P0-B）

```
事件流
  ┌───────────────────────────────────────────────┐
  │ 07-12  猎鹰9 一箭21星 星链组网      运载发射 ▸ │   ← 点行展开
  ├───────────────────────────────────────────────┤
  │ 07-11  铱星发布 Q2 指引            运营支撑 ▾ │
  │   ┌─────────────────────────────────────────┐ │
  │   │ 详情：铱星通信 Q2 收入指引上修…            │ │
  │   │ 概念: [卫星物联网] [直连手机] [星间链路]   │ │  ← 概念可点=反查过滤
  │   │ 关联: 铱星通信 US:IRDM → 工作台公司页 ↗    │ │
  │   │ AI 研判: 对运营层景气度偏正面（AI 生成）    │ │
  │   │ [来源 ↗]   [⚖ 带入议事厅]                  │ │
  │   └─────────────────────────────────────────┘ │
  └───────────────────────────────────────────────┘
```

### 5.3 命令面板（P1-A · ⌘K）

```
        ┌──────────────────────────────────────┐
        │ 🔍 星间链路                            │
        ├──────────────────────────────────────┤
        │ 概念   星间链路          → 过滤看板     │
        │ 公司   铱星通信 US:IRDM  → 工作台公司页 │
        │ 事件   07-11 铱星 Q2…    → 展开定位     │
        └──────────────────────────────────────┘
```

---

## 6. 技术方案概要（对齐四层架构与不变量）

| 需求 | 前端 | 后端/数据 | 不变量落点 |
|---|---|---|---|
| 全局切片 + 联动 | `index.html` 加轻状态层 `DASH_STATE`；`applyFilters(data, state)` 纯函数派生可见数据；各渲染函数改读派生结果 | **零新增**（全客户端在已取 `/events`·`/alerts`·`/trend`·`concept_stats` 上过滤） | 过滤纯函数可单测；空态诚实 |
| 列表下钻 | 展开态 + 详情卡渲染既有字段；概念 chip 联动；`openCouncil` 深链 | 复用 `/events` 现有字段 | 无源段不显示不编；公司深链仅限有 uid |
| URL 深链 | `syncURL()`/`parseURL()` + `history` + `popstate` | — | 默认无参 = 全量 |
| ⌘K 搜索 | 命令面板 + `search(index, q)` 纯函数（模糊 + 排序） | 在已取数据上建轻索引 | 纯客户端、无新增网络 |
| 自选关注 | `loadWatch()/saveWatch()` localStorage；`⭐` 过滤 | — | 仅本地、无 PII、无上传 |
| 图表 / 矩阵交互 | 图例 toggle / hover 读数 / 表头排序 `sortRows()` 纯函数 | — | 数值只读不改 |

**关键设计**：把现有「取数 → 渲染」改为「取数 → `DASH_STATE` → `applyFilters` 派生 → 渲染」。`applyFilters` / `search` / `sortRows` / URL 编解码 / 计数全部抽成**纯函数**（可 Node 侧单测，不依赖 DOM）。**无新增后端端点**（P2 反馈若做才需轻端点）。

---

## 7. 里程碑

| 阶段 | 内容 | 验收 |
|---|---|---|
| M1（本期）**✅ 已上线** | P0-A 全局切片+联动 · P0-B 下钻 · P0-C URL 深链（`index.html`，纯前端） | Playwright 实测：切片 15→8 事件联动、趋势淡化、事件展开、概念反查 `?c=`、深链还原、复制视角/重置全绿 |
| M2 **✅ 已上线** | P1-A ⌘K 搜索 · P1-B 自选关注 · P1-C 趋势交互 · P1-D 矩阵排序 | Playwright 实测：⌘K 搜索命中并跳转、★ 关注 localStorage 持久化 + 联动过滤、趋势卡点击聚焦 + 悬停读数、矩阵排序切换全绿 |
| M3 **✅ 已上线** | P2-B 布局自定义 · P2-C 对比模式 | Playwright 实测：折叠/隐藏/重排/持久化、对比两主线确定性指标全绿 |
| Backlog | P2-A 反馈标注（需轻后端）· P2-D 多人视角 | — |

---

## 8. 风险与合规

- **不得制造「数据在变」的错觉**：过滤 / 排序改变的是**可见性与顺序**，数值与来源标注不变；每个切片视角都显示「基于 N 条真实数据」而非凭空生成。空态一律诚实。
- **隐私**：自选关注 / 布局仅存 `localStorage`（本地、可清除），**不上传、不采集**；页面标注「仅存本地」。若未来做行为分析，须另立隐私说明并征得同意。
- **自动刷新一致性**：10 分钟自动刷新须**保留当前过滤态**，刷新后重跑 `applyFilters` 而非跳回全量，避免打断用户。
- **性能**：数据量小（事件 ~20 / 概念 ~30 / 公司矩阵十余行），主线程 O(n) 过滤无忧；交互零额外网络。
- **表述边界**：`thesis_impact` 等 AI 研判在下钻卡中**明示「AI 生成」**；全站免责常显，交互不隐藏免责。

---

## 附录 · 现状数据字段清单（交互层依赖）

- `/events`：`date` · `title/desc` · `thread`（主线）· `concept_tags`（概念，中英）· `source` · 关联公司 `uid` · `thesis_impact`（可选 AI 研判）。
- `/alerts`：`window` · 严重度 · `thread` · 描述。
- `/trend`：5 主线 × 时间序列（趋势图）。
- `/decision/weekly`：CEO/投资 Brief · 公司矩阵（信号 / 热度 / 市场 / uid）· 叙事链。
- `concept_stats`（`agent/docs/sample/concept_stats.json`）：`concept` · `concept_zh` · `thread` · `count`。

> 全部为**已取的真实数据**；交互层不引入任何新数据源，只在上述字段上切片 / 联动 / 排序 / 搜索。
