# SaaS Dashboard "Cost per Token Trend" — 2-option PM Review build 复盘 (2026-05-11)

> Complementary to [`2026-05-11-mockup-conventions-trifecta-rule-update.md`](./2026-05-11-mockup-conventions-trifecta-rule-update.md)（聚焦 M14 + M21 + M22 三规则的同时更新）。本文聚焦同 session 的**build journey + 数据可行性 audit + annotation/connector registry 模式 + 2-option PM review 最终态**。

## 背景

US-3 任务：在 `TVU-SaaS-Dashboard-20230619` Figma 文件（同 product = Usage Service）新增 "Cost per Token Trend" dashboard page。

User PRD 关键 ask：

- "design proposal for the chart and overall dashboard direction"
- "feel more like a business health / profitability indicator rather than a technical monitoring graph"
- "for the first phase, we only need the graph section... the KPI cards at the top are not needed yet"

数据源（user 后期澄清）：

1. 各云平台账单 → `vendor_cost ($)` + `tokens_count` (per period)
2. 客户付款 → `customer_payment ($)` per period

---

## Build Journey（按时间线）

### Phase 1 — Setup
- `git status` 起手 → 识别 cwd 在 TVU repo 内、产品输出走 Figma 不污染 repo → 可继续
- M21/R6 在本 session 早期立完（基于 user "已有本地组件优先复用"反馈），commit `3060d296` 已 push

### Phase 2 — Clone + mutate sibling layout
- Source page 找到（`1641:789`），clone 整个 `1641:2212` frame（1920×1468）到 target page `1749:93`
- 重命名 target Page "Page 19" → "Cost per Token Trend"
- 5 cards 删除 + 1 留下 detach 改 1840×700
- Top bar pos1 active→normal swap + 新加 library Menu `Cost per Token` active 在 pos4

### Phase 3 — Build chart content
- 标题 + KEY METRIC tag + 副标题（formula 形式）+ date picker
- 紫色 area gradient + line + 7 data dots + Y/X 轴标 + grid
- Build self-test ❌ 失败：
  - 紫色 = user 截图主色照抄（违 **M14**）
  - sibling chart 是绿色（M21 视觉合同没 probe，违 **M21**）
  - PRD "business health rather than monitoring graph" design ask 直接跳过（违 **M22**，但 M22 此时还没立）

### Phase 4 — 三规则触发 + 修正
1. 紫色 → TVU brand 绿（`#2fb54e`），mirror sibling 视觉合同 ✅
2. status chip "Token margin improving — cost down 1.9% MoM" 加在副标题下方（business framing）✅
3. CURRENT 值 28→32pt + 绿色 delta pill
4. **User 反馈**：货币应该是 $ 不是 ¢；从 CFO/Boss 角度看 view 够 clear & effective 吗？
5. 修：¢ → $；加 "Saved $6,200 this month" 业务影响显式化

### Phase 5 — 数据可行性 audit（user push 介入）

User 问："只有 vendor 账单（cost + token 数）+ customer 付款 两个数据源，你能拿到你设计的那些 metric 吗？"

强制 audit：

| 元素 | 公式 | 可算? |
|---|---|---|
| Cost per Token trend | vendor_cost / tokens_count | ✅ |
| Saved $X this month | (baseline_cpt − this_cpt) × this_tokens | ✅ |
| ▼ MoM delta % | period 比较 | ✅ |
| Revenue per Token | customer_payment / tokens_count | ✅ |
| Gross Margin % | (customer_payment − vendor_cost) / customer_payment | ✅ |
| Volume context | tokens_count + 账单数 | ✅ |
| C — Driver attribution (e.g. "GPU spot pricing") | 需要 WHY，不在数据里 | ❌ |
| D — Forecast | 线性外推，技术可算但 quality 风险 | ⚠️ |

**修正**：drop C；defer D；保留 derivable 的 6 项。

教训：**feature 设计前应先做数据可行性 audit**（input data → derivable metrics → 然后 propose feature 清单）。这次堆 feature 在前、audit 在后，是反模式。

### Phase 6 — PRD scope 边界冲突

加完 3-cell Revenue/Cost/Margin grid + Saved 行 → user 反馈 "UI 太乱了 / chart 上适合放这么多吗"。

复盘 PRD 原话："only graph section, KPI cards not needed yet" —— 3-cell grid 是 KPI cards 在 chart 内的等价物，违 scope。

修：给 3 个 cleanup 选项（Option 1 严格遵 PRD = pure chart / Option 2 = hero margin chip / Option 3 = margin summary in subtitle）。

### Phase 7 — 2-option PM Review build

最终保留 2 个候选 PM review：

| Option | Chart card 内 KPI 位置 | 视觉特点 |
|---|---|---|
| **Option 2 — Single Hero Margin Chip** | 右上单胶囊 `GROSS MARGIN 58.3% ▲ 2.3% MoM` | hero chip 占角，chart 主导 |
| **Option 3 — Margin Summary in Subtitle** | 副标题位 `GROSS MARGIN 58.3% · ▲ 2.3% MoM · Saved $6,200 this month` | zero 额外 UI block，副标题槽位 absorb business signal |

两套各自独立 sidebar（4 注释卡 = chart trend + 差异元素 + date picker + volume footer，含 Calculation + UX Delivery 两段）+ 4 条 elbow 连接线 + sharedPluginData registry。

---

## 主要工程发现

### 发现 1 — 数据可行性 audit 应前置

当前的 feature design 流程：feature 设计 → user audit → 修正。
更好的流程：data source 列入 → 推 derivable metrics → propose feature → user 校 → build。

未来可考虑加进 Pre-Phase 0 或独立成 R0/M0 前置 audit 步。

### 发现 2 — PRD scope vs design ask 张力 → 找"已有 UI 槽位 absorb"

PRD 严格读 "no KPI cards" vs design ask "business health framing" 表面冲突。**Option 3 解法**：把 business signal 挤进**已有 subtitle 槽位**（替换 formula 表述），不新增 UI block —— 双重满足 PRD scope + design ask。

教训：**冲突时找 absorb 槽位**，不要新增 block。

### 发现 3 — Annotation + Connector registry 模式（可复用）

设计图 handoff 场景常见痛点：注释 / UX delivery note 跟元素失联，元素移动后注释飘走。

本次引入的模式：

```
Anchor (anchor dot at target right edge)
   ─ elbow connector ─
                       ╲ Annotation card (with calculation + UX delivery)

Stored in Figma file via sharedPluginData:
  sidebar.cpt_annotations.connectors = [{ connectorId, anchorId, annoId, targetId }, ...]
  vec.cpt_annotations.annoId, targetId
  dot.cpt_annotations.connectorOf
```

**"重连"命令**：user 手动移位后说一句 `重连 Option 2` / `reconnect Option 3`，AI 读 registry → recompute path → update vectorPaths + anchor xy。

模式可推广到任何 design handoff / review / spec doc 场景。

### 发现 4 — 规则 self-test = 唯一证据

立 M21/R6 当天 build 阶段就违 M21（紫色 + 没 probe sibling）。**规则不会自动 enforce 自己**（M11 元教训二次实证）。

更深教训：**规则上线后第一个用规则的 task 应当作 stress test 跑**，主动找规则覆盖盲区。M22 就是这次 stress test 发现 M21 + M14 没覆盖 "user design ask 显式 override" 维度后填补的。

---

## 最终交付清单

### Figma 产物（page `1749:93` "Cost per Token Trend"）

- **Option 2 dashboard** `1754:453` (0, 0) 1920×836 + sidebar `1776:93` (2080, 0) 700×1059
  - 4 注释卡 `1779:93` / `99` / `105` / `111`
  - 4 connectors `1777:...` + 4 anchor dots
- **Option 3 dashboard** `1780:93` (0, 1350) 1920×836 + sidebar `1781:93` (2080, 1350) 700×1072
  - 4 注释卡 `1781:96` / `102` / `108` / `114`
  - 4 connectors `1781:...` + 4 anchor dots

### Repo 产物

- `mockup-conventions.md` M21 + pre-design-system 澄清段
- `code-conventions.md` R6 + pre-design-system 澄清段
- `_metrics/phase0-ledger.md` 首条 entry
- 本 retrospect 文件

### 待 PM Review

两个 option 视觉对比已就位，等 PM 拍板 → 选定后保留单个 + 删另一个 → 进入正式开发 handoff。

---

## 元规则启发

1. **数据可行性 audit 应前置** —— 未来考虑加 R0/M0 前置步或 Pre-Phase 0 sub-step
2. **PRD scope vs design ask 冲突 → 找 absorb 槽位**，不新增 block
3. **Annotation + Connector registry 模式** —— sharedPluginData 持久化 + "重连"命令重路由，**可复用到任何 design handoff 场景**
4. **规则 self-test = 唯一证据**——立规则后第一个使用 task 当 stress test 跑，主动找盲区
