# UI 还原自动化完整指南

本文档说明 sdd-flow-kit v1.7.41+ 的 UI 还原自动化机制，包括三大核心改进：

## 1. 交互合约 DSL（Interaction Contract DSL）

**目标**：建立"演示 → 生产"的交互合约机械描述，供门禁、测试生成、保真复查使用。

### 核心概念

- **TriggerMode**（触发方式）：`click` | `dblclick` | `hover` | `auto` | `submit`
- **ShellType**（交互壳层）：`inline` | `modal` | `drawer` | `tab` | `toast` | `page`
- **StructurePattern**（结构模式）：`steps` | `tabs` | `table-preview` | `form` | `grid`

### 使用场景

#### 在 design.md 映射表中声明

```markdown
| 演示模块 | 演示文件/组件 | 生产组件路径 | 关键交互信号 | 触发方式 | 壳层类型 | E2E 点击绑定 |
|---------|--------------|-------------|-------------|---------|---------|--------------|
| BD预估编辑 | ProjectDetail.vue | BdEstimateSection.vue | 编辑预估、保存 | click | inline | getByRole('button', { name: '编辑预估' }) |
| 导入管理 | ImportManagement.vue | ImportDialog.vue | 上传预览、确认覆盖 | click | modal | getByText('导入数据').click() |
```

#### propose 时自动生成交互合约 JSON

`runPropose` 会自动解析映射表并生成 `.interaction-contracts.json`：

```json
{
  "version": "1.0",
  "runId": "ADI_V2.3.4_20260314",
  "pages": [{
    "pageName": "财务管理",
    "interactions": [{
      "moduleId": "module-1",
      "moduleName": "BD预估编辑",
      "demoFile": "ProjectDetail.vue",
      "prodFile": "BdEstimateSection.vue",
      "triggerMode": "click",
      "shellType": "inline",
      "interactionSignals": ["编辑预估", "保存"],
      "e2eBinding": "getByRole('button', { name: '编辑预估' })"
    }]
  }]
}
```

#### 门禁验证

`gate prd-coverage` 会检查生产代码是否遵循交互合约：

- 交互信号是否出现在生产代码中
- 壳层类型是否匹配（通过组件名推断：`n-modal` / `n-drawer` / `inline-edit`）
- 触发方式是否正确（E2E 测试验证）

---

## 2. propose 时自动预生成布局合约草稿

**目标**：AI 读取 PRD + 04-技术文档（演示参照）后，自动生成 `16-演示布局合约.md` 草稿。

### 执行时机

在 `npx sdd-flow-kit propose` 时自动触发，无需额外命令。

### 生成内容

1. **元信息**
   - 从 `04-技术文档.md` 提取：演示代码根路径、技术栈
   - 从 `.ui-style-inferred.json` 推断：生产 UI 库（Naive/Ant/Element）

2. **截图清单占位**
   ```markdown
   | 页面/状态 | 截图路径 | 状态 |
   |-----------|----------|------|
   | 财务管理列表 | `visual-baseline/demo/finance-list.png` | 待截取 |
   | 详情-BD预估 | `visual-baseline/demo/detail-bd-estimate.png` | 待截取 |
   ```

3. **区块树模板**（从映射表推断）
   ```markdown
   ### 页面：财务管理
   - **操作栏**
     - 左：拉取欢聚最新数据
     - 右：导入数据、列配置
   - **表格默认可见列**：项目ID、项目名称、BD预估金额…
   - **详情抽屉**：右侧滑出，包含 Tab「项目信息、财务明细」
   ```

4. **组件映射表**（从映射表生成）
   ```markdown
   | 演示组件/模式 | 生产组件（仓库 UI 库） | 备注 |
   |--------------|----------------------|------|
   | ProjectDetail.vue | DetailDrawer.vue | drawer 壳层，click 触发 |
   | BdEstimate.vue | BdEstimateSection.vue | inline 壳层，dblclick 触发 |
   ```

5. **样式基线占位**
   ```markdown
   | 度量 | 演示基线（px） | 生产实现 |
   |------|--------------|----------|
   | 页面内边距 | 16 | `{{PLACEHOLDER}}` |
   | 表格行高 | 40 | `{{PLACEHOLDER}}` |
   ```

6. **交互合约引用**
   ```markdown
   已从 04 映射表生成 5 个交互合约，详见 `.interaction-contracts.json`
   ```

### 后续人工步骤

1. 将演示截图放入 `visual-baseline/demo/`
2. 执行 `demo-layout-analyze`（AI 填充区块树细节）
3. 执行 `demo-styles-extract`（自动从截图提取精确数值）
4. 标记「布局合约状态：已闭合」
5. 通过 `gate layout-contract-ready` 门禁

---

## 3. 视觉回归测试（Visual Regression Compare）

**目标**：像素级对比演示截图 vs 生产页面，输出差异报告。

### 使用方式

在 `validate` 阶段后执行：

```bash
npx sdd-flow-kit visual-compare \
  --project-root . \
  --run-id ADI_V2.3.4_20260314 \
  --change finance-v234 \
  --dev-server-url http://localhost:3000
```

### 工作流程

1. **读取布局合约**：从 `16-演示布局合约.md` 提取页面清单与截图路径
2. **启动页面截图**：使用 Playwright 访问生产页面并截图（当前占位，待实现）
3. **像素级对比**：
   - 优先使用 `pixelmatch`（需安装 `pixelmatch` + `pngjs`）
   - 退化使用 ImageMagick `compare`
4. **生成差异图**：保存到 `visual-baseline/diffs/*-diff.png`
5. **输出报告**：写入 `18-视觉回归对比报告.md`

### 报告示例

```markdown
# 18-视觉回归对比报告

视觉回归状态：未通过

## 汇总
- 总页面数：3
- 通过：2
- 未通过：1

## 详细对比
| 状态 | 页面 | 差异率 | 说明 |
|------|------|--------|------|
| ✓ | 财务管理列表 | 3.45% | 在阈值内 |
| ✗ | 详情-BD预估 | 15.23% | 超出阈值，检查间距 |
| ✓ | 导入管理 | 2.11% | 在阈值内 |

## 差异图位置
`visual-baseline/diffs/*-diff.png`
```

### 阈值说明

- **≤ 10%**：通过（视为可接受的渲染差异，如字体反锯齿、浏览器渲染差异）
- **> 10%**：未通过（需要人工审查差异图，判断是结构问题还是样式问题）

---

## 完整工作流集成

### 阶段 B → C'：文档闭合 + 布局合约生成

```bash
# 1. 闭合 PRD 文档
gate docs-closed
phase advance --to docs-done

# 2. propose 自动生成布局合约草稿
propose --change finance-v234

# 3. 补充演示截图
# 人工：将演示站截图放入 visual-baseline/demo/

# 4. AI 填充布局合约
demo-layout-analyze

# 5. 提取样式基线
demo-styles-extract

# 6. 标记已闭合并通过门禁
# 人工：在 16-演示布局合约.md 中改为「布局合约状态：已闭合」
gate --expect layout-contract-ready
```

### 阶段 C → D：提案 + 实现

```bash
# 提案演示审查
propose-remediate --change finance-v234
phase advance --to propose-done --change finance-v234

# 进入实现（Apply 前强制读布局合约）
phase advance --to impl --change finance-v234
gate --expect impl-allowed

# Apply（AI 必须先 Read 截图 + 样式基线）
/opsx-apply
```

### 阶段 E：验收 + 视觉回归

```bash
# 验收
validate --change finance-v234

# 视觉回归对比
visual-compare --change finance-v234 --dev-server-url http://localhost:3000

# 演示保真复查
demo-fidelity-review --auto --change finance-v234

# 签收与交付
gate --expect ac-signed
deliver --change finance-v234
```

---

## 门禁集成

| 门禁 | 检查项 | 说明 |
|------|--------|------|
| `layout-contract-ready` | 布局合约已闭合 | 截图清单、区块树、组件映射、样式基线已填写 |
| `propose-ready` | 交互合约 DSL | design.md 映射表已生成 `.interaction-contracts.json` |
| `prd-coverage` | 交互合约验证 | 生产代码遵循触发方式、壳层类型、交互信号 |
| `demo-fidelity-ready` | 演示保真复查通过 | P0/P1 差异已清零 |
| `visual-regression-pass`（可选） | 视觉回归通过 | 差异率 ≤ 10% |

---

## 依赖安装

### 视觉对比工具（二选一）

#### 方案 1：pixelmatch（推荐）

```bash
pnpm add -D pixelmatch pngjs
```

#### 方案 2：ImageMagick

```bash
# macOS
brew install imagemagick

# Ubuntu/Debian
sudo apt install imagemagick
```

### Playwright（用于生产页面截图）

```bash
pnpm add -D @playwright/test
npx playwright install chromium
```

---

## 配置文件

### .opsx/config.json

```json
{
  "deliveryPipeline": [
    "tdd-script",
    "openspec-superpowers-pipeline",
    "demo-fidelity-review",
    "visual-regression-compare"
  ]
}
```

### package.json

```json
{
  "scripts": {
    "opsx:visual-compare": "sdd-flow-kit visual-compare --dev-server-url http://localhost:3000"
  }
}
```

---

## 常见问题

### Q1：propose 时没有自动生成布局合约？

检查 `04-技术文档.md` 是否包含「演示代码参照」章节与映射表。

### Q2：visual-compare 报错"缺少图像对比工具"？

安装 `pixelmatch` + `pngjs` 或 ImageMagick。

### Q3：视觉回归一直显示 100% 差异？

- 检查演示截图是否存在
- 检查开发服务器是否运行
- 当前 Playwright 截图逻辑为占位，需补充实现

### Q4：如何豁免视觉回归？

在 `16-演示布局合约.md` 顶部添加：

```markdown
VISUAL_REGRESSION_EXEMPT: 演示站暂不可访问，已人工审查布局合约
```

---

## 迁移指南（v1.7.40 → v1.7.41+）

1. **更新依赖**
   ```bash
   pnpm update sdd-flow-kit
   pnpm add -D pixelmatch pngjs
   ```

2. **更新 AGENTS.md / .cursor/rules/**
   添加布局合约强制规则（见模板 `07-opsx-auto-chain.template.md`）

3. **首次使用**
   在下一个需求中，`propose` 后会自动生成布局合约草稿，按提示补充截图即可。

---

## 技术架构

### 核心模块

- `src/core/interactionContractDsl.ts`：交互合约 DSL 定义与解析
- `src/core/proposeLayoutDraft.ts`：布局合约草稿自动生成
- `src/core/visualRegressionCompare.ts`：视觉回归对比引擎
- `src/steps/runVisualCompare.ts`：视觉回归命令入口

### 数据流

```
04-技术文档.md (演示参照)
  ↓
runPropose (自动)
  ↓
16-演示布局合约.md (草稿)
  ↓
.interaction-contracts.json (交互合约 DSL)
  ↓
demo-layout-analyze (AI 填充)
  ↓
demo-styles-extract (机械提取)
  ↓
gate layout-contract-ready (门禁)
  ↓
impl (Apply 前强制读截图)
  ↓
validate + visual-compare (视觉回归)
  ↓
18-视觉回归对比报告.md
```

---

## 最佳实践

1. **演示截图质量**：使用统一浏览器窗口尺寸（推荐 1920x1080）
2. **截图命名规范**：`{页面名}-{状态}.png`，如 `finance-list.png`、`detail-bd-estimate.png`
3. **样式基线优先级**：`demo-styles.json` 数值 > 文字描述 > 设计师口头确认
4. **差异阈值调整**：根据项目实际情况调整（字体多的页面可放宽至 15%）
5. **结构 vs 样式**：结构差异（缺区块）必须修，样式差异（颜色略偏）可豁免

---

## 后续计划

- [ ] 补充 Playwright 自动截图逻辑（当前为占位）
- [ ] 集成无障碍树对比（检测 DOM 结构差异）
- [ ] 支持移动端视口对比
- [ ] 生成交互合约 DSL 的 TypeScript 类型定义（供前端代码导入）
- [ ] 集成到 CI/CD（视觉回归作为 PR 门禁）
