# 演示代码强制迁移工作流（SDD / OpenSpec 通用）

> 适用于 **Vue / React / 其他** 演示仓库。验收标准不是「技术栈一致」，而是 **交互与功能与演示代码等价**。

## 原则

1. **演示代码是 UI/交互 SSOT**（高于 PRD 文字摘要、高于 AI 自拟骨架）。
2. **禁止** 用「一个 FinanceDetailDrawer 读接口」代替「按演示拆分的多子模块」。
3. **禁止** 在 08 报告用 `index.vue:1` 或注释登记冒充实现。
4. 演示可为 React、生产为 Vue（或反之）——须在映射表注明技术栈，迁移的是 **模块边界 + 交互信号**，不是复制粘贴 DOM 库。

## 阶段 B — 04 技术文档

在 `04-技术文档草稿.md` 增加 **§2.4 演示代码参照**（propose 时迁入 `design.md`）：

```markdown
## 2.4 演示代码参照

- 演示代码根路径：`/path/to/demo` 或相对路径
- 技术栈：vue | react | 其他
- 说明：（可选）Element Plus 演示 → 生产 Naive UI

| 演示模块 | 演示文件/组件 | 计划生产组件路径 | 关键交互信号 |
|---------|--------------|-----------------|-------------|
| BD预估 | ProjectDetail.vue §BD预估 | src/views/.../BdEstimateSection.vue | 编辑预估、BD预计开票日期、距今天数 |
| 红票及其他 | ProjectDetail.vue §红票 | src/views/.../RedInvoiceSection.vue | 红票及其他、添加记录、红票 |
```

纯后端 / 无 UI 演示时，在 `design.md` 首行写：`DEMO_REFERENCE_EXEMPT: <原因>`

## 阶段 C — Propose

`design.md` **必须**含 `## 演示代码参照` 与上表（可从 04 复制并细化路径）。

`tasks.md` **必须**含：

```markdown
## 演示模块迁移（强制，对齐 design 映射表）

### Red
- [ ] D.1 为每个映射行编写失败测试（组件存在 / 交互文案 / API mock）
### Green
- [ ] D.2 按演示结构实现生产组件（禁止合并为单文件只读骨架）
```

**门禁**：`gate propose-ready` / `gate ac-ready` 执行 `checkDemoReferenceArtifacts`。

## 阶段 C′ — 演示截图与布局合约（实现前强制）

1. `npx sdd-flow-kit demo-layout-capture --demo-url <演示站>` → 创建 `visual-baseline/demo/`
2. 人工/浏览器截取列表、详情等关键屏到该目录
3. `npx sdd-flow-kit demo-layout-analyze` → 执行 `16-演示布局分析提示词.md`
4. `npx sdd-flow-kit demo-styles-extract` → 从截图生成 `visual-baseline/demo/demo-styles.json` 样式基线（间距/字号/圆角/色值等数值 SSOT）
5. 填写并闭合 `16-演示布局合约.md`（**结构跟演示，控件跟仓库 UI 库**）
6. `gate --expect layout-contract-ready` 通过后才允许 `phase --to impl`

---

## 阶段 D — Apply

实现顺序：

0. **先 Read 演示截图 + 样式基线**（视觉 SSOT，禁止只看文字合约）：
   - 打开 `visual-baseline/demo/` 中与当前页面/区块对应的截图（多模态看图）
   - 读 `visual-baseline/demo/demo-styles.json`：间距、字号、行高、圆角、色值以数值为准
   - 交互结构看截图；控件选型仍以 `.ui-style-inferred.json` 为准
1. **读演示文件对应段落**（无关技术栈）
2. **提取演示交互合约**（强制，禁止跳过）：
   - 读取 design.md 映射表中每行的「演示文件/组件」
   - 从演示代码提取：触发方式（@dblclick/@click）、交互壳层（inline/modal/tab/drawer）、结构模式（步骤指示器/Tab/表格预览）
   - 记录为「演示交互合约」，实现时必须 1:1 遵循
3. **拆分为生产 `components/*.vue`**（或 tsx），**严格遵循演示交互合约**
4. 接已有 API（`config/api/modules`）
5. 每完成一行映射：
   - 勾选 tasks 并跑该行单测
   - **验证交互合约**：触发方式、壳层、结构模式是否与演示一致
   - 不一致则立即修复，禁止遗留

### 禁止的替换（gate 强制）

| 演示交互合约 | 禁止的生产实现 |
|------------|-------------|
| 行内编辑 (dblclick+editingId) | 改为弹窗编辑 (n-modal/el-dialog) |
| Tab 结构 (n-tabs+activeTab) | 改为垂直布局 (多个 Section 纵向排列) |
| 步骤指示器 (n-steps) | 去掉步骤指示器直接展示表单 |
| 表格预览 (n-data-table) | 改为 JSON 文本 `<pre>` 展示 |
| 抽屉详情 (n-drawer) | 改为独立路由页 |
| "双击编辑"提示文案 | 省略提示文案 |

## 阶段 E — Validate / Deliver

- `assess-demo-implementation-coverage.mjs`：映射生产文件存在；**交互以行为证据 / triggerMode / shellType / 结构为准**（自由中文信号字面量仅警告，禁止隐藏 span 过关）
- `assess-anti-signal-anchor.mjs`：**禁止** SignalAnchor / `data-*-interaction-signals` / `*-sr-only` 隐藏信号墙 / 假 Modal 无条件挂载
- `assess-component-substance.mjs`（v1.7.22 A+C）：组件非空壳；可映射行为的信号须有事件/toast/壳层等证据（禁止 script/DEMO_INTERACTION_SIGNALS 过关）；Section/Modal 须被父组件 import
- `interactionSignalEvidence`（v1.7.22）：A 字面量降权 + C 行为证据优先
- `assess-ac-assertion-binding.mjs`（v1.7.7+）：P0 AC 的 05 验收标准字面量须出现在 test expect 中；**禁止** `expect(true)`；e2e AC 在无引号字面量时须有意义 DOM 断言；`[交互]` 须真实 click/fill
- `assess-e2e-assertion-depth.mjs`：E2E 须数据/交互断言；**可点击信号**须在 spec 中有 click/getByText（v1.3.19）
- 08 报告证据须指向 **具体组件文件 + 行号 + 交互文案**

## 05 验收清单

详情类 AC 验收标准须写清演示模块与壳层，例如：

- `壳层=右侧 Drawer；详情 Tab「财务明细」含金额与返点卡片、财务链路、红票及其他（对齐演示 ProjectDetail.vue）`
- `BD预估区含编辑预估按钮，保存 toast「BD预估已保存」`
- `导入：壳层=弹窗；内含 Tab「导入/导入历史」；历史支持查看详情（禁止做成独立路由页除非 03 确认）`

## 门禁（通用）

| 阶段 | 检查项 | 说明 |
|------|--------|------|
| docs-closed | ui-ac-criteria-quality | UI P0 须写壳层或交互原语 |
| docs-closed | visual-ac-priority | 有原型图时 visual 须 P0/P1 |
| docs-closed / propose | demo-signal-quality | 信号≥2 且非全弱词 |
| propose / ac-ready | design-demo-not-weaker | design 不得弱于 04 映射 |
| impl-allowed / delivery | propose-review-report | 须有通过态 `10-提案演示审查报告.md`；缺则自动 `propose-remediate` 续跑 |
| propose→impl | layout-contract-ready / demo-layout-contract | 须有闭合的 `16-演示布局合约.md`（截图+区块树+组件映射+样式基线）；结构跟演示、控件跟仓库；样式基线须有 `demo-styles.json` 且合约样式表已填 |
| validate→deliver | **demo-fidelity-ready** | 须有通过态 `17-演示保真复查报告.md`；`demo-fidelity-review --auto` 循环修至开放 P0/P1=0；**deliver 硬失败** |
| prd-coverage | ui-engineering-baseline | 可选项目配置列表组件 |
| prd-coverage | inferred-table-style | 无 baseline 且高置信时强制列表用推断组件 |
| prd-coverage | interaction-mode-consistency | triggerMode/shellType 与生产代码一致 |
| prd-coverage | demo-structure-consistency | 演示代码 Tab/步骤条/行内编辑/预览展示与生产代码一致 |
| prd-coverage | **anti-signal-anchor** | 禁止 SignalAnchor/demo-signal/离屏占位/假 Modal 无条件挂载 |
| prd-coverage | visual-layout-structure | 布局结构校验（不可被 VISUAL_REGRESSION_EXEMPT 豁免） |

环境变量（仅紧急）：`OPSX_SKIP_UI_INTERACTION_GATE=1`、`OPSX_SKIP_UI_BASELINE=1`、`OPSX_SKIP_DEMO_REFERENCE=1`、`OPSX_SKIP_ANTI_SIGNAL_ANCHOR=1`、`OPSX_SKIP_DEMO_FIDELITY=1`

## 豁免

| 场景 | 写法 |
|------|------|
| 纯 API/配置 | `DEMO_REFERENCE_EXEMPT: 无 UI` |
| 演示待补 | 禁止进入 impl；须先补演示或用户书面确认 |
| 视觉 toHaveScreenshot | `VISUAL_REGRESSION_EXEMPT: <≥12字且含用户确认/人工签收/无稳定字体等>`；**仍须有 P0/P1 visual AC**；**布局结构校验不可豁免** |
| 布局结构校验 | `LAYOUT_STRUCTURE_EXEMPT: <≥12字原因>`；仅当 CI 环境无法读取演示代码时使用；**仍须有 triggerMode/shellType 列** |
