# MicroApps Console · Code 复盘（2026-05-11 → 05-13）

> **目的**：内部分享 — UX/Dev 设计师用 `@TVU code` 把 MicroApps Console 从 mockup 落到可演示 demo 的真实过程复盘 + 高效对话建议。
> **场景**：Master Console / My Sessions 监控页面，从 ~2300 行单 HTML PoC（Plan A）到 Vue + Vite 工程化版本（Plan B）+ cloudflared 公网托管给 PM 验收。配对的 Figma mockup 复盘见 [2026-05-09 篇](2026-05-09-microapps-console-figma-mockup-retrospect-internal-share.md)。

---

## TL;DR

- **总轮次**：~15+ 轮 user feedback（跨 2 个 code session：05-11 HTML PoC + 05-13 Plan B Vue）
- **最终交付**：
  - **Plan A** [`microapps-console-demo.html`](../../microapps-console-demo.html)（~2300 行单 HTML，TVU library 全 icon swap）
  - **Plan B** [`vue-app/`](../../vue-app/) + [`microapps-console-planb.html`](../../microapps-console-planb.html)（Vue + Vite 工程化版本，241KB / gzip 71KB）
  - cloudflared quick tunnel 公网链接给 PM 验收
  - 18 节 Plan B spec 文档 + Figma handoff prompt
- **核心 process gap 数**：5 条关键规则回流（`code-conventions.md` R1-R5 + Topbar 公共组件规则 + Empty state icon 语义三分 + 列排序 Phase 优先级 + 公网托管选型）
- **关键 insight**：

> **UX 设计师用 AI 写 code 不是"AI 自动生成 demo"，而是"用代码 probe 设计决策"** — 列排序刚需 / Empty state 语义 / Topbar 公共组件约束都是在写 code 过程中被代码逼出来的产品决策。

---

## 1 · Session 概览

### 任务起点

Figma mockup 完成后（[05-09 Figma 篇](2026-05-09-microapps-console-figma-mockup-retrospect-internal-share.md)），需要一个**可演示 / 可分享 PM 的 demo**：(1) 验证 mockup 在真实视口下的交互、(2) 给 PM 公网链接验收，不依赖 Figma 阅读、(3) 后续可演进到正式工程化。

### 最终落地

**Plan A — Single HTML PoC**（[`microapps-console-demo.html`](../../microapps-console-demo.html)，~2300 行）：
- 17 个 inline `<symbol>` 全部 sourced from TVU `dist/icons/svg/`（health / Search / Edit/Copy / share / open-link / Menu / Waffle 等）
- Topbar 3 列 grid 居中 nav + 金黄时钟
- Action 列左对齐固定锚位
- ≥1920 media query
- mock data 7 条 Inactive 变体（含 stopped-with-error）
- New Session / Open in MicroApp 用 Blob URL 打开占位 GUI 页（替代被 Chrome 拦截的 data: URL）

**Plan B — Vue + Vite**（[`vue-app/`](../../vue-app/)）：
- Sidebar 280px + 折叠态 + Overview status chip 聚合
- TVU Topbar 公共组件规则修正（右侧 cluster 固定 + persona/admin 下沉 sub-header）
- AutoRefresh 倒计时数字为主信息
- Empty States 圆形 icon 背景 + 三分语义（i-empty-tray 被动 / i-search 过滤 / i-add 创建）
- 5 列可排序（Event Name / Object ID / Input URL / Output URL / State）+ 3 状态循环 + aria-sort
- cloudflared quick tunnel 公网托管

**Process artifacts**：
- [`code-conventions.md`](../../../tvu-design-system/docs/internal/code-conventions.md) 新建（R1-R5，与 mockup-conventions 平级）
- [`docs/MICROAPPS_PRODUCT_CONTEXT.md`](../MICROAPPS_PRODUCT_CONTEXT.md) §10.5 当前状态 + §11-13 链路重构
- [`docs/handoffs/2026-05-11-handoff.md`](../handoffs/2026-05-11-handoff.md) 第一份按 Session Handoff Protocol 产出的 handoff
- [`docs/specs/2026-05-13-plan-b-spec.md`](../specs/2026-05-13-plan-b-spec.md) 18 节设计规范
- [`docs/specs/2026-05-13-plan-b-figma-prompt.md`](../specs/2026-05-13-plan-b-figma-prompt.md) 新 session 起手 prompt（喂 Figma mockup 创建）
- feedback memory `feedback_tvu-icons-mandatory.md` 落 user 全局 memory

---

## 2 · 时间线 / 主要迭代

| # | 阶段 | 用户 feedback 触发 | 改动量 | 性质 |
|---|---|---|---|---|
| 1 | Plan A 起手 | "做个 MC + MS HTML demo" | ~1500 行起手 | AI 默认实现 |
| 2 | Plan A 图标审查 | "**TVU 设计库应约束图标来源**" | 17 个 inline symbol 全换 TVU dist source | **AI 自己造图标，没看真源** |
| 3 | Plan A topbar | "topbar layout 居中 nav + 金黄时钟" | 3 列 grid + flexbox 重排 | 视觉对齐 |
| 4 | Plan A action | "Action 列锚位固定不要随表内容跑" | left-align + min-width | 监控页交互 |
| 5 | Plan A filter | "**MC 和 MS 的 filter bar 应保持一致**" | 移除 showActiveSegment prop 条件 + filteredApps 去 page 门 | **R4 反模式实证：先实现再问**|
| 6 | Plan A Blob URL | "Chrome 拦截 data: URL" | New Session / Open in MicroApp 改 Blob URL | Browser 限制 |
| 7 | Plan A 收尾 | wrap-up + handoff | code-conventions.md R1-R5 诞生 + handoff 协议落地 | **规则工程化** |
| 8 | Plan B 起手 | "迁 Vue + Vite 工程化" | 单 HTML → 多组件 Vue + dist | 架构升级 |
| 9 | Plan B Sidebar | "侧栏要能折叠 + 完整产品名" | 280px + toggle icon-only + 折叠 tooltip 弹右 | 监控页布局 |
| 10 | Plan B Topbar | "**TVU Topbar 是公共组件，左右两侧 cluster 固定不可改**" | persona/admin pill 下沉到 sub-header 内 | **AI 改了公共组件，错** |
| 11 | Plan B AutoRefresh | "倒计时数字应该是主信息，不是辅助" | "12s" 字号 ↑ + label 字号 ↓ | 视觉权重纠正 |
| 12 | Plan B Empty | "Empty 用 + 号 icon 太误导（看起来像可点）" | i-empty-tray 被动 / i-search 过滤 / i-add 仅 button 内 | **图标语义三分** |
| 13 | Plan B Sort | "**列排序得加，监控场景刚需**" | 5 列 asc/desc/clear + 双三角 + aria-sort | **Phase 2 提前到 Phase 1** |
| 14 | Plan B 公网托管 | "PM 要个公网链接" | cloudflared quick tunnel 选型 | 协作工具 |

---

## 3 · Top 5 Process Gap（按返工成本排序）

### Gap 1 · **没约束图标来源，AI 自己造 / 误用图标**

**实证**：Plan A 起手我用了一堆"看起来对"的 inline SVG 图标，没去 TVU `dist/icons/svg/` 翻真源。用户元提醒："**TVU 设计库应约束图标来源**"。这不是单次错误，是规则缺口 — 后续触发：
- `code-conventions.md` 新建（与 `mockup-conventions.md` 平级，code 规则独立成文件）
- R1：图标必须 source from TVU library，禁止 inline 重画
- R2-R5：含 fonts / colors / spacing / session handoff convention

**返工成本**：17 个 inline symbol 全 swap 一遍 + 全新规则文件诞生（500+ 行规则工程化）

**原因**：`@TVU code` skill 之前只约束 mockup 层（M 系列规则），code 层没有平行约束。AI 默认行为是"按视觉模仿生成 SVG"，没有"必须从设计库 source"的硬约束。

**✅ 解决方案**：
- **当下修复**：17 个 inline `<symbol>` 全部 swap 为 TVU `dist/icons/svg/` source（health Success/warning/Error / Search / Edit/Copy 系列 / share / open-link / Menu / Waffle）
- **长期防护**：新建 `code-conventions.md` R1-R5 与 mockup-conventions M 系列平级硬约束 — R1 图标必须 source from TVU library 禁止 inline 重画 / R2-R3 字体颜色 token-only / R4 不"先实现再问" / R5 Session Handoff Convention；user-level memory 全局生效
- **真源落地**：✅ 已落 `tvu-design-system/docs/internal/code-conventions.md` R1-R5 + ✅ 已落 user global memory `feedback_tvu-icons-mandatory.md`

---

### Gap 2 · **MC / MS filter parity bug — R4 "先实现再问" 反模式实证**

**实证**：Plan A 我在 FilterBar 加了 `showActiveSegment` prop，让 MC 显示 All / Active / Inactive radio，MS 不显示。后来用户指出 "**MC 和 MS 的 filter bar 应保持一致，仅 search placeholder 不同**" — 我误读了 Figma mockup，凭印象记得 MS 没 radio。

修复：3 处编辑（FilterBar props + template + RootApp filteredApps 中 activeOnly 过滤逻辑去掉 `currentPage === 'master-console'` 的页面门）。

**返工成本**：~3 处代码改 + bug 跨整 PoC 暴露用户验收时

**原因**：**AI 在数值/结构问题上不 probe，凭印象推断 "哪页有 / 没有"**。这是 R4 "不'先实现，再问'" 反模式的真实实证 — 应在写 filter 逻辑前重新 probe Figma 两页 filter bar 的 children 真值。

**✅ 解决方案**：
- **当下修复**：FilterBar 移除 `showActiveSegment` prop 条件分支；RootApp `filteredApps` 中 `activeOnly` 过滤去掉 `currentPage === 'master-console'` 的页面门 — MC / MS 共享同一 filter bar 行为，仅 search placeholder 文字不同
- **长期防护**：任何"哪页有 / 没有 X"类结构问题写代码前**强制 probe Figma 两页节点真值**（用 `get_metadata` 对比 children 数量 / 类型）— 不允许凭"我记得 mockup 是 X"写 props 条件分支
- **真源落地**：✅ 已落 `code-conventions.md` R4 "不'先实现，再问'" + 配套 phase0-ledger entry 实证

---

### Gap 3 · **TVU Topbar 是公共组件，我改了它**

**实证**：Plan B Vue 起手我把 persona / admin pill 直接塞进 TVU Topbar 右侧 cluster — 看起来很合理（顶栏右侧 = 用户身份）。用户纠正："**TVU Topbar 是公共组件，左右两侧 cluster 固定不可改 — Admin/persona pill 下沉到 sub-header 内**"。

修复：persona/admin pill 从 topbar 拆出，重建 sub-header 容器，按"固定内容（AutoRefresh）外侧锚点 + 变化内容（New Session）内侧"原则重排。

**返工成本**：Topbar slot 重构 + sub-header 新建容器 + 元素 reorder

**原因**：AI 对"公共组件 = 跨产品共享 = 不能改"这件事**没默认意识**。看到 topbar 有空间，就直接塞。需要"组件分级（公共 / 产品级 / 页面级）"这件事写进 code-conventions。

**✅ 解决方案**：
- **当下修复**：persona / admin pill 从 TVU Topbar 拆出 → 新建 sub-header 容器接管产品级状态 cluster；sub-header 排序原则定型："**固定内容（AutoRefresh）外侧锚点 + 变化内容（New Session）内侧**"
- **长期防护**：消费产品代码起手必须识别"组件层级"三分：**公共组件**（TVU 库提供，cluster 结构不可改 — Topbar / Footer / Modal）/ **产品级组件**（本产品自建跨页复用 — Sidebar / Sub-header）/ **页面级组件**（单页专属）；动公共组件 cluster 前必须 user 确认
- **真源落地**：✅ 本产品 spec 已落 [`docs/specs/2026-05-13-plan-b-spec.md`](../specs/2026-05-13-plan-b-spec.md) §Topbar；⏳ 待累积 2+ 产品例后写入 TVU `code-conventions.md` 新规则段"公共组件 cluster 结构不可修改"

---

### Gap 4 · **Empty state 用 + icon 看起来像可点 — 图标语义三分**

**实证**：Plan A / 早期 Plan B 我用 + icon 做 Empty state 视觉（"empty + Add new"）。用户指出 + icon 看起来像可点 button，误导性强。修复：图标语义三分：
- `i-empty-tray`（被动空状态：列表为空）
- `i-search`（搜索 / 过滤无结果空状态）
- `i-add`（**仅在 action button 内**，不做空状态视觉）

**返工成本**：所有 Empty state icon 替换 + button 文字去 `+` 重复（"+ Create new" → "Create new"）

**原因**：AI 默认拿 "+ icon" 当 empty state 万金油，没区分"被动空 vs 过滤空 vs 创建动作"三种语义。这是图标 affordance 设计的基础问题。

**✅ 解决方案**：
- **当下修复**：所有 Empty state 视觉重做 — `i-empty-tray`（被动空状态，圆形 icon 背景）/ `i-search`（搜索过滤无结果）/ `i-add`（**仅** action button 内使用）；按钮文字去除 `+` 前缀避免与 icon 重复（"+ Create new" → "Create new"）
- **长期防护**：图标语义按 affordance 三分：被动状态用"空容器"语义（empty-tray / empty-folder） / 过滤态用 search / 创建动作用 add — 三者不能互换；按钮内已有 add icon 就不在文字加 +
- **真源落地**：✅ 本产品 spec 已落 [`docs/specs/2026-05-13-plan-b-spec.md`](../specs/2026-05-13-plan-b-spec.md) "Empty State Icon 语义三分" 段；⏳ 待累积 2+ 产品例后上 TVU 真源 `code-conventions.md` 视觉语义段

---

### Gap 5 · **列排序：Phase 优先级判断错**

**实证**：mockup 文档把列排序标为 Phase 2 deferred（"等基础功能稳定再做"）。Plan A 我跟 mockup 走没做。Plan B user 反馈："**列排序得加，监控场景刚需**" — 监控页面用户一定要按 State / Start time 排序找最近 active session。

修复：5 列 asc/desc/clear 3 状态循环 + 双三角箭头视觉指示器 + aria-sort 无障碍属性。

**返工成本**：~1 轮新建 sort logic（中等工作量），但**理念上是产品决策错位**：列排序不是"高级功能"，是监控页 P0。

**原因**：Phase 优先级在 mockup 阶段定的，没考虑"page type vs feature priority"耦合 — 监控页和编辑页对同一功能的优先级是不同的。

**✅ 解决方案**：
- **当下修复**：Plan B 实现 5 列可排序（Event Name / Object ID / Input URL / Output URL / State），3 状态循环 asc/desc/clear + 双三角箭头视觉指示器 + `aria-sort` 无障碍属性；Event Owner / Company / Actions 按 spec 不可排序
- **长期防护**：mockup → code 交接时，PRD / task prompt 必须显式标 **page type 元数据**（监控页 / 编辑页 / viewer / 设置页）；监控页所有支持"找到目标 session"的功能（列排序 / 实时刷新 / Filter / 状态聚合）默认 P0，不接受 Phase 2 deferred
- **真源落地**：✅ 本产品 spec 已落 [`docs/specs/2026-05-13-plan-b-spec.md`](../specs/2026-05-13-plan-b-spec.md) 18 节含列排序规则表；⏳ 元规则"Phase 优先级按 page type 区分"待累积 3+ session 例后上 `design-process.md`

---

## 4 · 高效对话 5 条建议（按 ROI 排序）

### 给 UX / PM（提需求方）

**(1) 起手交付 TVU library 真源路径** — 不让 AI 凭"看起来对"造图标。
- ❌ 反例："做个 MC + MS HTML demo"
- ✅ 正例："做个 MC + MS HTML demo，**所有图标 source from `tvu-design-system/dist/icons/svg/`，禁止 inline 重画**"

**(2) Page type 元数据要前置** — 监控页 / 编辑页 / viewer 对功能优先级判断不同。
- ❌ 反例：让 AI 跟 mockup Phase 优先级走
- ✅ 正例："**这是监控页**，列排序 / 实时刷新 / Filter / 状态聚合都是 P0，不接受 Phase 2 deferred"

---

### 给 AI 协作流程

**(3) `@TVU code` skill 起手 Phase 0 强制 read code-conventions** — 不允许写一行 code 前没读 R1-R5。

**(4) 结构问题（哪页有 / 没有 X）必须 probe Figma 真值** — 不允许凭"我记得 mockup 是 X" 写代码。R4 "不'先实现，再问'" 反模式必须强 enforce。

---

### 给 PM / Stakeholder（review 方）

**(5) Demo 验收必跑 4 项 checklist**：
1. 图标是不是全从 TVU library？(grep `<svg>` 看 source）
2. 公共组件（Topbar / Sidebar）有没有被改 cluster 结构？
3. Empty state 用哪种语义图标？（被动 / 过滤 / 创建）
4. P0 监控功能（列排序 / 实时刷新 / 状态聚合）是否全到位？

---

## 5 · 规则回流清单

### ✅ 已落回流（本 session 写入真源）

| 规则 | 真源文件 | 简述 |
|---|---|---|
| R1 图标必须 source from TVU library | `tvu-design-system/docs/internal/code-conventions.md` | 禁止 inline 重画 SVG |
| R2-R3 字体 / 颜色 / 间距 token-only | `tvu-design-system/docs/internal/code-conventions.md` | 配套 R1 全套约束 |
| R4 不"先实现再问" | `tvu-design-system/docs/internal/code-conventions.md` | 结构 / 数值问题必 probe |
| R5 Session Handoff Convention | `tvu-design-system/docs/multi-session-collaboration-rules.md` | handoff 何时写 / 落哪 / 必含段 |
| 图标必从 TVU library（user pref）| `~/.claude/.../memory/feedback_tvu-icons-mandatory.md` | 全局生效 |
| Empty state 图标语义三分 | `MicroApps/docs/specs/2026-05-13-plan-b-spec.md` | 产品 spec，待累积上 TVU |

### ⏳ 待回流（下 session 完成 / 等触发条件）

| 规则 | 目标真源 | 触发条件 |
|---|---|---|
| 公共组件不可修改 cluster 结构 | `code-conventions.md` 新增段 | 累积 2+ 产品例（本 session 第 1 例）|
| Empty state icon 语义三分 | `code-conventions.md` 视觉语义段 | 累积 2+ 产品例 |
| Phase 优先级按 page type 区分 | `design-process.md` | 累积 3+ session 例 |

---

## 6 · Model 选型实证

| 模型 | 适合场景 | 本 session 起作用时刻 |
|---|---|---|
| **Opus 4.7** | 主对话 / 架构推理 / 跨文件回流 / 规则工程化 | code-conventions.md R1-R5 诞生那一轮（一次扫多个图标实证 + 抽象出规则 + 配套 handoff 协议）；Plan A → Plan B 架构 pivot 决策 |
| **Sonnet 4.6** | batch 改动 / icon swap / 重构 | 17 个 inline symbol → TVU source swap、5 列 sort logic 实现、Sidebar 折叠态 CSS |
| **Haiku 4.5** | 简单 probe | 不适合主对话；可用于 "grep TVU dist 下有没有 X icon" 这种轻 probe |

**Hybrid 推荐**：Opus 做 plan owner（架构 pivot + 规则抽象 + 验收 review） + Sonnet subagent 做 executor（icon batch swap、sort logic 实现、CSS 调整）。本 session 全 Opus 跑，估算 Hybrid 可省 30-40% Opus token。

**纯 Sonnet 推算**：纯 Sonnet 大概率会：(1) 完成 Plan A HTML demo 没问题；(2) 但**不会主动抽象出 code-conventions R1-R5**（Sonnet 倾向于"修这一个 case"而不是"上升到规则"）；(3) 不会主动设计 Session Handoff Protocol。规则工程化级的工作必须 Opus 做。

---

## 7 · 给团队的 3 个 Action Items

**1. `@TVU code` skill 起手强制 read code-conventions R1-R5**
> 不允许写一行 code 前没读规则文件。skill SKILL.md 加 Phase 0 step。

**2. Demo 验收 4 项 checklist 上墙**
> PM / UX review demo 时先过 4 问（图标来源 / 公共组件 cluster / Empty 语义 / P0 监控功能），不依赖事后发现。

**3. Page type 元数据写进任务 prompt**
> 每个 code task 第一句话标明"监控页 / 编辑页 / viewer / 设置页"，让 AI 据此判断 Phase 优先级，不闭眼跟 mockup。

---

## 附录 A · 改动统计

| 改动类型 | 次数 / 量 |
|---|---|
| Plan A HTML 行数 | ~2300 行单文件 |
| Plan A icon swap (inline → TVU source) | 17 个 symbol |
| Plan B Vue 组件 | ~25+ component（Sidebar / Topbar / FilterBar / Table / EmptyState / Sort / Tooltip 等）|
| Plan B dist 大小 | 241KB / gzip 71KB |
| code-conventions 新规则 | R1-R5 共 5 条核心 + 配套子条 |
| 5 列 sort logic | asc/desc/clear 3 状态 + aria-sort + 双三角 |
| Empty state icon 语义 | 3 分（empty-tray / search / add） |

## 附录 B · 关联文档

- [MicroApps Console Figma Mockup 复盘 — 2026-05-09](2026-05-09-microapps-console-figma-mockup-retrospect-internal-share.md) — 配对的 Figma session
- [`docs/handoffs/2026-05-11-handoff.md`](../handoffs/2026-05-11-handoff.md) — 第一份按协议产出的 handoff
- [`docs/specs/2026-05-13-plan-b-spec.md`](../specs/2026-05-13-plan-b-spec.md) — Plan B 18 节设计规范
- [`docs/specs/2026-05-13-plan-b-figma-prompt.md`](../specs/2026-05-13-plan-b-figma-prompt.md) — 喂 Figma mockup 创建 prompt
- [`tvu-design-system/docs/internal/code-conventions.md`](../../../tvu-design-system/docs/internal/code-conventions.md) — R1-R5 真源
- [Video Sync 多 session 复盘 — 2026-05-20](2026-05-20-video-sync-mockup-retrospect-internal-share.md) — 同模式的"AI 不 probe 凭印象"教训第 2 例

---

> **复盘人**：Claude Opus 4.7 (1M context) + nancyzeng (UX)
> **复盘时间**：2026-05-21
> **目标受众**：TVU 内部 — UX team + Dev + AI 协作流程改进
> **联系**：真源文件全部在 `tvu-design-system` repo 内可查
