# TVU Business Domain Rules

> TVU 产品特有的业务规则，**适用于两条 path**（Path A Figma mockup + Path B 代码生成）。
> 来源：TVU 行业背景（广播 / 直播 / 媒体处理）+ 产品特性积累。
>
> 通用 process 规则 → [`design-process.md`](./design-process.md)
> Figma 工具 quirks → [`figma-technical-reference.md`](./figma-technical-reference.md)
> Path 专属细节 → [`mockup-conventions.md`](./mockup-conventions.md) / [`code-conventions.md`](./code-conventions.md)

---

## TVU SaaS 产品默认 Persona 列表

> 适用于 TVU Usage Service / SaaS Dashboard / 管理后台类产品。F2 persona simulation 无需手动提供，默认读此表。
> 监控台 / operator console 类产品另有 persona（重度运营 / SRE），在具体产品 brief 中定义。

| Persona | 角色 | 核心关注点 | 看 dashboard 核心目标 |
|---|---|---|---|
| **CFO / Business Owner** | 财务负责人 / 高管 | 盈利健康、成本趋势、ROI、Savings | 3 秒内获取 margin % + 趋势方向 + 是否改善 |
| **PM（产品经理）** | 产品负责人 | 功能 PRD scope 边界、user story 覆盖、无 scope creep | 确认交付边界，功能不越界也不遗漏 |
| **SRE / DevOps** | 基础设施 / 可靠性 | 数据管道健康、延迟、告警、数据新鲜度 | 数据是否实时、有无 pipeline 故障信号 |

---

## M3 — Status 色绑定遵循广播行业 ON AIR 惯例

TVU 产品 session / stream 状态色：

| 状态 | 颜色 | Token (dark) |
|---|---|---|
| **Live** (output on air) | 🔴 红 | `--red` (#ea4233) → library var `UX/Red/Default` |
| **Previewing / Standby** | 🟢 绿 | `--brand` (#2fb54e) → library var `UX/Brand/Brand` |
| **Inactive** | ⚫ 灰 | library var `Color Type/Background/Disable Grey Button` |
| **N/A** (component 不支持) | ⚪ 浅灰斜杠 | `--text-disabled` |

**不要**按 SaaS 默认（绿=活跃、红=危险）配色。客户是广播 / 直播 / 媒体处理工程师，红=Live 是肌肉记忆。

Destructive 操作（Stop / Remove confirm）也用红，但出现在 modal 内部，与 Live badge（table 行）位置不重叠，不冲突。

---

## M4 — Monitoring / Operator console 类页面默认 dark theme only

监控类 / 运营操控台类产品 deliverable 默认**仅交付 dark mode**，除非用户显式要求。不画 / 生成 light mode 对比图。

**Why:** 广播控制台 industry default + 长时间盯屏视疲劳。

---

## M5 — 不在 dashboard / monitoring 页面创建 session

Monitoring 类产品（如 Session Dashboard）默认是 **readonly 监控 + 控制台**：

- ❌ 不暴露 `+ New Session` 或类似创建入口
- ✅ session 由后端 / MicroApp 自身创建后 push 到 dashboard
- ✅ dashboard 仅做：查看状态 / 启停 / 跳转 / 移除

---

## M7 — Control surface 视觉权重：actions > identifiers > status

监控 / operator console 类页面的视觉层级**必须**：

1. **Actions（操作按钮）最显眼** — 必须用正规尺寸 button，不允许自制 XS chip；column 不够宽就让 column 宽，不要缩按钮（违反 Fitts 定律）
2. **Identifiers（PID / Object ID 等）次要** — 文字层级中等，operator 偶尔需要复制 ID
3. **Status pills 最安静** — 短词（`Live` / `Preview` / `Inactive`），暗色块或低饱和 bg，小 padding；**绝不**用 solid 大色块抢 action 焦点

**反例**（2026-05-06 Session Dashboard 第一版）: Status pill 全饱和 solid 红/绿 + 白字（视觉权重最重）; Action 按钮自制 XS chip（视觉权重最轻）→ operator 一眼看到的是 status，找 action 要扫一遍，视觉层级完全反了。

**Why:** operator 看 dashboard 目标 90% 是操作（启停/跳转），10% 才是被动监控状态。视觉权重服务主任务。

---

## M8 — Dashboard 折叠卡片默认状态规则

所有按 entity 分组的 dashboard card 默认状态**必须**：

| 该 entity 状态 | 卡片默认 | Badge |
|---|---|---|
| 至少 1 个 active session | **expanded** | 🟢 `X active`（绿）|
| 全部 inactive | **collapsed** | ⚪ `X sessions`（灰）|

Chevron 图标方向反映展开/折叠状态。"所有 card 一律展开 + 一律绿 badge" → ❌ 把折叠功能做空，背离它存在的意义。

**Why:** dashboard 长 list 默认全展开噪音过大；折叠规则把"没在跑的 entity"压扁、"有活动的"暴露出来。badge 颜色变化（绿 active → 灰 sessions）本身就是 affordance。

---

## M9 — Operator console action label 用 literal 动词

行内 / 卡片内 action button label **必须**用动词短语，不允许用图标缩写、字符画、或动作的对象名替代动词：

| ✅ 正确 | ❌ 错误 |
|---|---|
| `Open GUI` | `Ctrl ↗` / `GUI` |
| `Stop In` | `■ In` / `In` |
| `Start Out` | `▶ Out` / `Out` |
| `Remove` | `✕` |

Icon 可以**配合**文字（button 支持 icon=left/right），但不能**替代**文字。

**Why:** 字符画在 dark theme 小字号下识别度低，broadcasting 软件标准（vMix / TriCaster / OBS）全用 literal verb，且 i18n（图标符号难翻译）和 a11y（screen reader 念不出 ↗）更友好。

---

## M10 — List row Inactive 状态至少分两子型（Idle vs NeverStarted）

监控 / operator console 类列表 row 的 "off / 未运行" 状态**至少**分两个子型，**不允许合并为单一 Inactive variant**：

| 子型 | 副标题内容 | 行内可见字段 | 用户心智 |
|---|---|---|---|
| **Inactive-Idle**（曾运行有 history） | `Last ran HH:MM → HH:MM · N min`（可附 last delta）| route + history meta | "停了可重启" |
| **Inactive-NeverStarted**（从未运行） | `Never started` + CTA `Set <资源 A> and <资源 B>` | 无 route / 无 delta，只 CTA prompt | "从未配置，先配再用" |

**Why:** 两子型 user mental model 完全不同。合并 → bootstrap 引导场景丢失，user 看 `Inactive` 不知该 click "重启" 还是 "去配置"。

**反例**（2026-05-26 Video Sync Phase B 初版）：原计划 8 variants (`state×selected×expanded = 2×2×2`)，把 `#3 TV2_Feed Last ran ...` 与 `#5 Test_Session Never started` 都画成同一 Inactive variant → 用户分不清是 stopped 还是 never-configured → 实际派生 12 variants (`state(3) × selected × expanded`)。

**Acceptance:**
- Component 设计：variant property `state` 至少包含 `{Active, Inactive-Idle, Inactive-NeverStarted}` 三值
- Mockup 设计：list 内同时出现两子型 row 时，副标题措辞必须区分（"Last ran X" vs "Never started"），不混用
- Bootstrap session 必为 NeverStarted 子型，对应 CTA 必为 literal verb（如 `Set Stream A and Stream B`）

---

## M11 — Trend visualization: icon + 数值颜色双层信号

Delta / latency / metric trend 可视化用 ↑↓ icon 时，**仅 icon 不够**——**数值本身也要染色**，icon + 数值色构成双层视觉信号：

| 状态 | Icon | 数值颜色 | Token (dark) |
|---|---|---|---|
| **Converging** (delta 收敛 / metric 改善) | ↓ | 绿 | `UX/Brand/Brand` (`--brand`) |
| **Diverging** (delta 发散 / metric 恶化) | ↑ | 橙红 | `Color/Text/Warning` (`--text-warning`) |
| **Stable** (变化在阈值内) | 无 icon | 中性色 | `Color/Text/Primary` |

**阈值规则示例**（不同 metric 取值）：Δ ≤ -2 ms 显 ↓ 绿；Δ ≥ +2 ms 显 ↑ 橙红；±2 ms 内无 icon 中性色。具体阈值由业务定，但**双层信号格式必须遵守**。

**Why:** icon 小（通常 16×16）+ dark theme 下易被忽略；数值大字号染色让 user 一眼 grasp 方向。仅 icon 漏掉 = monitoring console 高频信息密度场景下信号弱。

**任何 trend rule 必须同时描述：** (1) icon 触发阈值 (2) 数值颜色映射 (3) Token 引用。漏写颜色规则 = 不完整 spec。

**反例**（2026-05-26 Video Sync Phase B walkthrough）：Design Rules card 原 trend rule 仅描述 icon 阈值 `±2 ms`，漏数值颜色映射（mockup 中 84ms↓ 已用绿、320ms↑ 已用橙红，但规则未文档化）→ audit 时补。

**Acceptance:**
- Trend rule 文档必含三层信号映射表（icon + 数值色 + token）
- Mockup 中相同 trend 状态视觉一致（不同帧不允许颜色不一）
- 颜色必绑 TVU Variable，不写 raw hex（与 M-COLOR C1 / 原则 4 一致）
