199 lines
10 KiB
Markdown
199 lines
10 KiB
Markdown
# G01 无家谱状态合并实施计划
|
||
|
||
> **For agentic workers:** REQUIRED SUB-SKILL: Use `superpowers:executing-plans` to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||
|
||
**Goal:** 删除独立的 G02 页面路由,让“无家谱”成为 G01 在 `?state=empty` 下可复现、可验证的页面状态,同时保持 G01 默认已验收列表画面不变。
|
||
|
||
**Architecture:** `pages/genealogy/g01-my-genealogies.vue` 是“我的家谱”状态的唯一所有者:默认路由继续读取现有示例家谱数据,`state=empty` 只覆盖 `hasGenealogies` 的演示状态。G01 的空状态使用已生成的完整位图面板和现有按钮位图;G02 路由、专属实现、测试与已失效的专属交接材料删除。
|
||
|
||
**Tech Stack:** uni-app Vue 3、Vue Composition API、PowerShell 合约测试、Chrome DevTools 截图脚本、Node.js 运行时冒烟测试。
|
||
|
||
## Global Constraints
|
||
|
||
- 不修改 G01 默认“已有家谱”状态的可见效果,也不修改已验收的 A01、A02、A04、A05、A06。
|
||
- 可审计路由/视觉结构改动必须先有最小失败契约测试;行为验证必须覆盖默认与空状态。
|
||
- 空状态完整面板、按钮边框和装饰面使用位图资产,不以 CSS 伪造。
|
||
- 不执行 `git add`、`git commit`、`git push`、`git reset` 或 worktree 操作。
|
||
- 仅删除本项目此前为独立 G02 创建、且在迁移后无引用的文件;保留最终位图并改为 G01 所属名称。
|
||
|
||
---
|
||
|
||
### Task 1: 建立 G01 空状态与路由收敛契约
|
||
|
||
**Files:**
|
||
- Create: `tests/g01-empty-state-contract.ps1`
|
||
- Modify: `tests/full-page-visual-contract.ps1`
|
||
- Test: `tests/g01-empty-state-contract.ps1`
|
||
|
||
**Interfaces:**
|
||
- Consumes: `pages.json` 路由注册、`pages/genealogy/g01-my-genealogies.vue`、`static/assets/modules/genealogy/opaque/g01-empty-panel.png`。
|
||
- Produces: 证明 G01 是唯一入口、`state=empty` 是唯一空状态开关、并且 57 条已注册路由为新的页面契约的静态测试。
|
||
|
||
- [x] **Step 1: 写失败的合约测试**
|
||
|
||
在 `tests/g01-empty-state-contract.ps1` 断言:
|
||
|
||
```powershell
|
||
Assert-True ($pages.paths -contains 'pages/genealogy/g01-my-genealogies') 'G01 route missing'
|
||
Assert-True (-not ($pages.paths -contains 'pages/genealogy/g02-empty-genealogies')) 'G02 route must be removed'
|
||
Assert-Match $g01Source 'forceEmptyState' 'G01 must own the explicit empty state'
|
||
Assert-Match $g01Source 'state.*empty' 'G01 must parse state=empty'
|
||
Assert-Match $g01Source 'g01-empty-panel\.png' 'G01 must use its final raster empty panel'
|
||
Assert-Match $g01Source 'empty-create-action' 'G01 must expose create action in empty state'
|
||
Assert-Match $g01Source 'empty-search-action' 'G01 must expose search action in empty state'
|
||
Assert-NoCssSurface $g01Source 'empty-panel'
|
||
Assert-NoCssSurface $g01Source 'empty-create-action'
|
||
Assert-NoCssSurface $g01Source 'empty-search-action'
|
||
```
|
||
|
||
并在 `tests/full-page-visual-contract.ps1` 中把期望页面数和完整清单收敛为 57 条,移除 G02。
|
||
|
||
- [x] **Step 2: 运行测试确认失败**
|
||
|
||
Run: `powershell -ExecutionPolicy Bypass -File tests/g01-empty-state-contract.ps1`
|
||
|
||
Expected: FAIL,指出 G02 仍在路由表中,且 G01 尚未拥有 `forceEmptyState` 和最终 `g01-empty-panel.png`。
|
||
|
||
- [x] **Step 3: 记录失败原因**
|
||
|
||
失败不是视觉问题:现有 `pages.json` 将 G02 作为第二个页面注册,且现有 G01 空分支没有 URL 状态开关。这证明需要迁移所有权,而不是额外保留一个“空状态页面”。
|
||
|
||
### Task 2: 将空状态实现迁移到 G01
|
||
|
||
**Files:**
|
||
- Modify: `pages/genealogy/g01-my-genealogies.vue`
|
||
- Modify: `pages.json`
|
||
- Move: `static/assets/modules/genealogy/opaque/g02-empty-panel-v2.png` to `static/assets/modules/genealogy/opaque/g01-empty-panel.png`
|
||
- Test: `tests/g01-empty-state-contract.ps1`
|
||
|
||
**Interfaces:**
|
||
- Consumes: `state=empty` 路由参数和现有 G01 的 `createGenealogy()`、`applyToJoin()`。
|
||
- Produces: 默认 G01 保持有家谱;`/pages/genealogy/g01-my-genealogies?state=empty` 展示带“创建我的家谱”和“搜索并申请加入”动作的空状态。
|
||
|
||
- [x] **Step 1: 实现最小路由状态所有权**
|
||
|
||
在 G01 里引入 `forceEmptyState`,在 `onLoad` 和 `onShow` 中同步当前页面 `options.state`(H5 时从 hash 查询串读取)。只用它定义:
|
||
|
||
```js
|
||
const hasGenealogies = computed(() => !forceEmptyState.value && list.value.length > 0)
|
||
```
|
||
|
||
默认路由不携带 `state=empty`,因此继续走现有已验收列表分支。
|
||
|
||
- [x] **Step 2: 替换 G01 的旧 CSS 空状态表面**
|
||
|
||
仅替换 `v-else` 空状态内容为:
|
||
|
||
```vue
|
||
<view v-else class="genealogy-empty-state">
|
||
<view class="empty-panel">
|
||
<image class="empty-panel-skin" src="/static/assets/modules/genealogy/opaque/g01-empty-panel.png" mode="aspectFill" />
|
||
<view class="empty-panel-content">
|
||
<!-- 印章、标题、说明、分隔纹、创建与搜索动作 -->
|
||
</view>
|
||
</view>
|
||
</view>
|
||
```
|
||
|
||
按钮皮肤继续引用现有 `a01-primary-button.png` 与 `a01-secondary-button.png`。使用 `empty-create-action`、`empty-search-action` 等新类名,不能改动现有列表中 `.create-action` 的已验收样式;这两个动作分别继续调用 `createGenealogy()` 与 `applyToJoin()`。
|
||
|
||
- [x] **Step 3: 移除独立 G02 入口**
|
||
|
||
从 `pages.json` 删除 `pages/genealogy/g02-empty-genealogies`,删除 `pages/genealogy/g02-empty-genealogies.vue`,并将最终位图重命名为 `g01-empty-panel.png`。不保留 G02 兼容路由或重定向。
|
||
|
||
- [x] **Step 4: 运行静态契约确认通过**
|
||
|
||
Run: `powershell -ExecutionPolicy Bypass -File tests/g01-empty-state-contract.ps1`
|
||
|
||
Expected: PASS,且 `powershell -ExecutionPolicy Bypass -File tests/full-page-visual-contract.ps1` 输出 57 条路由清单通过。
|
||
|
||
### Task 3: 验证真实页面状态与动作
|
||
|
||
**Files:**
|
||
- Create: `tests/g01-empty-state-runtime-smoke.js`
|
||
- Test: `tests/g01-empty-state-runtime-smoke.js`
|
||
|
||
**Interfaces:**
|
||
- Consumes: Chrome DevTools `http://localhost:9222` 与开发服务器 `http://localhost:5173`。
|
||
- Produces: 默认 G01 列表、空状态、创建跳转和搜索跳转的运行时证据。
|
||
|
||
- [x] **Step 1: 写运行时测试**
|
||
|
||
测试在同一浏览器中依序验证:
|
||
|
||
```js
|
||
await open('/#/pages/genealogy/g01-my-genealogies?state=empty')
|
||
await waitFor('.genealogy-empty-state .empty-create-action')
|
||
await click('.empty-create-action')
|
||
assertPath('/pages/genealogy/g03-create-genealogy')
|
||
await open('/#/pages/genealogy/g01-my-genealogies?state=empty')
|
||
await click('.empty-search-action')
|
||
assertPath('/pages/genealogy/g06-search-genealogies')
|
||
await open('/#/pages/genealogy/g01-my-genealogies')
|
||
assertExists('.current-slip')
|
||
assertMissing('.genealogy-empty-state')
|
||
```
|
||
|
||
- [x] **Step 2: 运行运行时测试确认通过**
|
||
|
||
Run: `node tests/g01-empty-state-runtime-smoke.js http://localhost:5173`
|
||
|
||
Expected: PASS,证明两个空状态动作可用,且不带参数的 G01 仍为默认列表。
|
||
|
||
### Task 4: 截图审视、清理与交接同步
|
||
|
||
**Files:**
|
||
- Modify: `docs/交接记录.md`
|
||
- Modify: `docs/规划.md`
|
||
- Modify: `docs/design/P00_页面结构与资产清单.md`
|
||
- Modify: `docs/design/2026-07-14_页面与状态合并审计.md`
|
||
- Delete: `tests/g02-empty-genealogies-contract.ps1`
|
||
- Delete: `tests/g02-empty-genealogies-runtime-smoke.js`
|
||
- Delete: `docs/design/G02_无家谱空状态_设计记录.md`
|
||
- Delete: `docs/superpowers/specs/2026-07-14-g02-empty-genealogies-design.md`
|
||
- Delete: `docs/superpowers/plans/2026-07-14-g02-empty-genealogies.md`
|
||
- Delete: `docs/design/screens/runtime/2026-07-14/G02-before-360x800.png`
|
||
- Delete: `docs/design/screens/runtime/2026-07-14/G02-before-412x915.png`
|
||
- Delete: `docs/design/screens/runtime/2026-07-14/G02-after-360x800.png`
|
||
- Delete: `docs/design/screens/runtime/2026-07-14/G02-after-412x915.png`
|
||
- Delete: `docs/design/screens/runtime/2026-07-14/G01-G02-comparison-360x800.png`
|
||
- Create: `docs/design/screens/runtime/2026-07-14/G01-empty-after-360x800.png`
|
||
- Create: `docs/design/screens/runtime/2026-07-14/G01-empty-after-412x915.png`
|
||
- Create: `docs/design/screens/runtime/2026-07-14/G01-default-after-360x800.png`
|
||
- Create: `docs/design/screens/runtime/2026-07-14/G01-default-before-after-360x800.png`
|
||
|
||
**Interfaces:**
|
||
- Consumes: G01 的两种可达状态、迁移后的 57 路由契约、审计前的 `route-audit/G01-360x800.png`。
|
||
- Produces: 同一视口的默认态前后对比、空状态截图、无过期 G02 入口和准确的交接记录。
|
||
|
||
- [x] **Step 1: 截图并做同图对比审视**
|
||
|
||
在 360×800 截默认 G01 和 `state=empty`,在 412×915 截空状态;把迁移前 `route-audit/G01-360x800.png` 与迁移后默认图并排为一张对比图。使用图像查看确认默认态没有发生可见改动,并确认空状态不出现透明黑角、裁切或 CSS 伪造表面。
|
||
|
||
- [x] **Step 2: 清除过期 G02 资料**
|
||
|
||
在 `rg` 确认没有其余活跃引用后,删除仅属于独立 G02 的路由实现、测试、计划、设计记录和旧截图。保留路线审计里的总览截图,避免抹除先前审计证据。
|
||
|
||
- [x] **Step 3: 更新真实状态**
|
||
|
||
文档统一为:已注册路由 57 条;G01 默认列表仍已验收;G01 `state=empty` 已实现和截图验证、等待用户对新增状态的审美确认;下一项合并仍是 G04→G03,尚未开始。
|
||
|
||
- [x] **Step 4: 完成回归验证**
|
||
|
||
Run:
|
||
|
||
```powershell
|
||
powershell -ExecutionPolicy Bypass -File tests/g01-empty-state-contract.ps1
|
||
node tests/g01-empty-state-runtime-smoke.js http://localhost:5173
|
||
powershell -ExecutionPolicy Bypass -File tests/full-page-visual-contract.ps1
|
||
powershell -ExecutionPolicy Bypass -File tests/visual-asset-compliance.ps1
|
||
powershell -ExecutionPolicy Bypass -File tests/a01-landing-contract.ps1
|
||
powershell -ExecutionPolicy Bypass -File tests/a02-login-contract.ps1
|
||
powershell -ExecutionPolicy Bypass -File tests/a04-forgot-password-contract.ps1
|
||
powershell -ExecutionPolicy Bypass -File tests/a05-register-contract.ps1
|
||
powershell -ExecutionPolicy Bypass -File tests/a06-auth-status-contract.ps1
|
||
git diff --check
|
||
```
|
||
|
||
Expected: 全部通过;`git diff --check` 允许 CRLF 警告但无空白错误。
|