Files
jiapuapp/docs/superpowers/plans/2026-07-21-whole-product-enrichment-implementation.md
T

8.6 KiB

全项目第二轮体验与代码优化实施计划

For agentic workers: 按任务顺序执行;每个任务都先写失败契约、再做最小实现、最后在 MuMu 验证。用户禁止任何 Git 操作。

Goal: 在保持已验收视觉与业务合同的前提下,完成 Android 原生路由、共享弹窗、关键交互语义、密码策略和世系树恢复定位优化。

Architecture: 活动页面的 onLoad(query) 是原生路由唯一所有者;共享弹窗和共享点击表面只在组件层持有跨页规则;账户密码策略由一个纯函数模块持有;T01 的恢复定位只属于树页本身。

Tech Stack: UniApp、Vue 3 <script setup>、SCSS、PowerShell 静态契约、MuMu Android WebView/CDP 只读检查。

全局约束

  • 不使用浏览器做视觉审核,不启动或关闭 MuMu。
  • 不执行 Git add、commit、push、restore、checkout。
  • 不修改 G01~G10 视觉,除非修复已证明的 Android/共享缺陷。
  • 页面示例提示使用“某某某”;fixture 数据不处理。
  • 内容自然增高;弹窗只允许视口 max-height 和内部滚动。
  • 不在 Vue 中新增 100% 100% no-repeatborder-image-slice

Task 1: 原生活动页路由参数

Files:

  • Create: tests/native-route-query-contract.ps1
  • Modify: pages/genealogy/g01-my-genealogies.vue
  • Modify: pages/genealogy/g03-create-genealogy.vue
  • Modify: pages/genealogy/g06-search-genealogies.vue
  • Modify: affected G01/G03/G06 route contracts and runtime-smoke assumptions only when they assert hash ownership

Interfaces:

  • G01 onLoad(query) consumes state?: default|empty|loading|error and genealogyId?: string.

  • G03 onLoad(query) consumes step?: create|ancestor and genealogyId?: string.

  • G06 onLoad(query) consumes mode?: search|invite and state?: loading|initial.

  • Add a failing contract forbidding location.hash, URLSearchParams and hashchange in active pages and requiring the three onLoad(query) entrypoints.

  • Run powershell -ExecutionPolicy Bypass -File tests/native-route-query-contract.ps1; expect failure on current G01/G03/G06.

  • Replace global URL reads with page-owned normalized query refs; delete obsolete listeners and fallback branches.

  • Update only stale tests that still make H5 hash the production contract.

  • Run focused G01/G03/G06 tests and the four project baselines.

  • In MuMu verify G05→G03 ancestor, G01→G06 invite, and re-entry without stale state; save screenshots under tmp/project-optimization/native-route/.

Task 2: AppDialog 高度预算

Files:

  • Modify: tests/app-dialog-responsive-content-contract.ps1
  • Modify: components/AppDialog.vue
  • Modify: styles/global.scss only if a shared safe-area variable is required

Interfaces:

  • .app-dialog-layer owns viewport safe padding.

  • .app-dialog owns the only dialog max-height budget.

  • .app-dialog__body remains the internal scrolling region.

  • Tighten the dialog contract to require safe top/bottom and one closed height formula; keep existing internal-scroll assertions.

  • Run the contract and observe the expected failure.

  • Implement the smallest CSS-only budget change without changing markup or assets.

  • Run the focused contract and four baselines.

  • In MuMu verify G10 approve/reject, R04 delete, R08 long top/bottom, M10 agreement/logout and F07 create; save evidence under tmp/project-optimization/dialog-safe-area/.

Task 3: AppTabbar 与 GenealogyCard 交互语义

Files:

  • Modify: tests/shared-interaction-accessibility-contract.ps1
  • Modify: components/AppTabbar.vue
  • Modify: components/GenealogyCard.vue

Interfaces:

  • Tabbar root exposes tablist; each item exposes tab, dynamic aria-selected, accessible label and a no-layout-shift pressed class.

  • GenealogyCard exposes one button semantic surface with a computed accessible label and pressed class.

  • Add failing assertions for role/name/current state/pressed feedback.

  • Run the accessibility contract and confirm failure.

  • Add semantic attributes and hover-class while retaining existing DOM geometry and assets.

  • Run focused component, responsive and compile contracts.

  • In MuMu verify F01/M01 tab switching and G01 current/non-current cards, including press feedback and unchanged layout; save evidence under tmp/project-optimization/shared-pressable/.

Task 4: G10 拒绝错误关联

Files:

  • Modify: tests/g10-document-flow-contract.ps1
  • Modify: tests/g09-g10-business-state-contract.ps1
  • Modify: pages/genealogy/g10-application-review.vue

Interfaces:

  • Reject textarea has stable id, aria-invalid, aria-describedby and an error element with role="alert".

  • Failed reject submission focuses the textarea after nextTick; valid input clears the error contract.

  • Add failing static assertions for field/error association and focus call.

  • Run focused tests and confirm failure.

  • Implement the semantic association and focus behavior without changing dialog layout.

  • Run all G10 tests and the four baselines.

  • In MuMu verify empty reject, correction, confirmation and long reason with keyboard/internal scroll; save evidence under tmp/project-optimization/g10-validation/.

Task 5: 单一密码策略

Files:

  • Create: utils/validation.js
  • Create: tests/password-policy-contract.ps1
  • Create: tests/password-policy-runtime-smoke.js as a Node-only pure-function test
  • Modify: pages/auth/a04-register.vue
  • Modify: pages/auth/a05-reset-password.vue
  • Modify: pages/profile/m04-change-password.vue

Interfaces:

  • validatePassword(value) returns { valid: boolean, message: string }.

  • PASSWORD_POLICY_MESSAGE is the single visible rule text.

  • M04 additionally rejects next === current in its page-specific validator.

  • Write static ownership assertions and pure-function cases for empty, 7-char, letters-only, digits-only, valid 8-char and 33-char values.

  • Run both tests and observe missing-module/ownership failure.

  • Implement the pure validation module and migrate all three pages, deleting local duplicated regex/messages.

  • Run A04/A05/M04 focused tests, pure runtime test and four baselines.

  • In MuMu submit the same invalid/valid samples on all three pages; verify identical rule feedback and natural error wrapping; save evidence under tmp/project-optimization/password-policy/.

Task 6: T01 回到当前成员

Files:

  • Modify: tests/t01-tree-state-contract.ps1
  • Modify: tests/t01-tree-state-runtime-smoke.js only to express the new state contract without browser-only visual claims
  • Modify: pages/tree/t01-tree-overview.vue

Interfaces:

  • Each member node has a stable DOM id derived from member id.

  • treeScrollLeft binds to scroll-left.

  • A user scroll sets treeHasDrifted; recenterSelectedMember() measures the selected node and visible scroll viewport, then centers the node and clears drift.

  • Add failing assertions for stable node id, drift state, conditional action and recenter function.

  • Run the focused test and confirm failure.

  • Add the conditional semantic action using the existing toolbar visual language; do not alter node/line geometry.

  • Run T01 focused tests and four baselines.

  • In MuMu pan left/right, recenter, change selection and recenter again; verify selected detail is unchanged and empty/loading/error omit the action; save evidence under tmp/project-optimization/t01-recenter/.

Task 7: 全项目闭环

Files:

  • Modify: docs/superpowers/plans/2026-07-21-project-wide-audit-and-expert-optimization.md

  • Verify: all tests/*.ps1, coverage/allowlist owners and affected MuMu evidence directories

  • Run every tests/*.ps1 and require all pass.

  • Run the Node-only password policy test.

  • Run the four user-required baseline commands again.

  • Compare actual Vue files to responsive-layout-coverage.json; require exact equality.

  • Require zero Vue matches for 100% 100% no-repeat and direct border-image-slice.

  • Confirm MuMu stays online at the user-selected configuration and inspect every affected screenshot.

  • Recheck accepted G10 and one representative F/R/N/M page after shared changes.

  • Record exact pass counts, modified files, evidence paths, remaining deferred debt and skipped browser-only smoke tests.

自检

  • 设计中的六个实施批次均有对应任务和独立验收。
  • 没有 TODO/TBD、兼容旧 hash 的双路径或未经授权的 API 接入。
  • 计划没有任何 Git 命令。
  • 页栈、短信、领域 repository 与全局文字系统明确暂缓,没有被悄悄塞入实现。