diff --git a/.gitignore b/.gitignore index d42b7b8..febdb18 100644 --- a/.gitignore +++ b/.gitignore @@ -58,6 +58,4 @@ sitemap.xml /unpackage/ /.vite/ /design-pipeline/generated/ -/docs/design/screens/runtime/ -/docs/superpowers/specs/design/ /tmp-g01-icon-audit.png diff --git a/.superpowers/sdd/progress.md b/.superpowers/sdd/progress.md deleted file mode 100644 index d6e52a9..0000000 --- a/.superpowers/sdd/progress.md +++ /dev/null @@ -1,9 +0,0 @@ -# SDD Progress - -Plan: docs/superpowers/plans/2026-07-21-page-header-safe-area-g03.md -Branch: fix/page-header-safe-area -Base: 779a442 - -Task 1: complete (commits 779a442..2f22df6, review clean) -Task 2: complete (commits 2f22df6..a0d19f4, review clean after strict-regex fix) -Task 3: complete (verification only at a0d19f4, review clean; 8 contracts + 2 H5 smokes pass) diff --git a/.superpowers/sdd/review-task-1-779a442..2f22df6.diff b/.superpowers/sdd/review-task-1-779a442..2f22df6.diff deleted file mode 100644 index 086e293..0000000 --- a/.superpowers/sdd/review-task-1-779a442..2f22df6.diff +++ /dev/null @@ -1,143 +0,0 @@ -# Review package: 779a442..2f22df6 - -## Commits -2f22df6 fix: adapt shared page header to safe area - -## Files changed - components/PageHeader.vue | 12 ++++++++++-- - tests/shared-component-document-flow-contract.ps1 | 4 ++++ - tests/shared-interaction-accessibility-contract.ps1 | 10 ++++++++++ - 3 files changed, 24 insertions(+), 2 deletions(-) - -## Diff -diff --git a/components/PageHeader.vue b/components/PageHeader.vue -index 5ef28dd..17ab7ef 100644 ---- a/components/PageHeader.vue -+++ b/components/PageHeader.vue -@@ -67,52 +67,60 @@ - - - - - - ').Groups[1].Value - $positions = [regex]::Matches([regex]::Replace($style, '(?s)/\*.*?\*/', ''), '(?m)\bposition\s*:\s*([^;]+);') - if ($positions.Count -ne 1 -or $positions[0].Groups[1].Value.Trim() -ne 'fixed') { - throw "G03 must retain only its combined fixed dialog layer rule; found $($positions.Count) position declarations" - } - foreach ($required in @( -- 'background: url("/static/assets/foundation/opaque/root-header-cinnabar.jpg")', - 'background: url("/static/assets/modules/genealogy/transparent/g01-empty-panel-frame.png")', - 'background: url("/static/assets/modules/auth/transparent/a01-scroll-dialog-v3.png")', - 'background: url("/static/assets/foundation/transparent/a01-scroll-primary-v3.png")' - )) { if ($page -notmatch [regex]::Escape($required)) { throw "G03 is missing real asset background: $required" } } -+foreach ($forbidden in @('flow-header', 'root-header-cinnabar.jpg')) { -+ if ($page -match [regex]::Escape($forbidden)) { throw "G03 must not retain private header token: $forbidden" } -+} - Write-Output 'G03-DOCUMENT-FLOW-CONTRACT PASS' -diff --git a/tests/g03-visual-states-contract.ps1 b/tests/g03-visual-states-contract.ps1 -index 5342acb..cfb7911 100644 ---- a/tests/g03-visual-states-contract.ps1 -+++ b/tests/g03-visual-states-contract.ps1 -@@ -2,22 +2,22 @@ $ErrorActionPreference = 'Stop' - - $root = Split-Path -Parent $PSScriptRoot - $g03 = Get-Content -LiteralPath (Join-Path $root 'pages/genealogy/g03-create-genealogy.vue') -Raw -Encoding utf8 - - function Assert-Match { - param([string]$Content, [string]$Pattern, [string]$Message) - if ($Content -notmatch $Pattern) { throw $Message } - } - - if ($g03 -match '返回') { throw 'G03 header must use only the approved image back arrow' } --Assert-Match -Content $g03 -Pattern '(?s)\.flow-header__back,\s*\.flow-header__side\s*\{[^}]*width:\s*72rpx;' -Message 'G03 header side slots must preserve centered title after removing back text' --Assert-Match -Content $g03 -Pattern '(?s)\.flow-header__back-icon\s*\{[^}]*width:\s*34rpx;[^}]*height:\s*34rpx;' -Message 'G03 back arrow must use the approved visible size' -+Assert-Match -Content $g03 -Pattern '(?s)' -Message 'G03 must use PageHeader with its dynamic title and custom back handler' -+if ($g03 -match 'flow-header|flow-header__back|flow-header__title') { throw 'G03 must not retain a private header implementation' } - Assert-Match -Content $g03 -Pattern '(?s)\.flow-note,\s*\.flow-rule__note\s*\{[^}]*font-size:\s*25rpx;' -Message 'G03 guidance copy must use the approved readable size' - Assert-Match -Content $g03 -Pattern '(?s)\.flow-rule__option\s*\{[^}]*font-size:\s*23rpx;' -Message 'G03 visibility options must use the approved readable size' - Assert-Match -Content $g03 -Pattern '(?s)\.field-error\s*\{[^}]*font-size:\s*24rpx;[^}]*line-height:\s*34rpx;' -Message 'G03 field errors must use the approved readable size' - Assert-Match -Content $g03 -Pattern '(?s)\.flow-error\s*\{[^}]*font-size:\s*25rpx;[^}]*line-height:\s*36rpx;' -Message 'G03 submit errors must use the approved readable size' - - foreach ($asset in @('a01-scroll-dialog-v3.png', 'a01-scroll-primary-v3.png', 'a01-scroll-secondary-v3.png')) { - if ($g03 -notmatch [regex]::Escape($asset)) { throw "G03 must retain approved shared asset: $asset" } - } - - Write-Output 'G03-VISUAL-STATES-CONTRACT PASS' diff --git a/.superpowers/sdd/review-task-2-rereview-2f22df6..a0d19f4.diff b/.superpowers/sdd/review-task-2-rereview-2f22df6..a0d19f4.diff deleted file mode 100644 index 82c65d9..0000000 --- a/.superpowers/sdd/review-task-2-rereview-2f22df6..a0d19f4.diff +++ /dev/null @@ -1,230 +0,0 @@ -# Review package: 2f22df6..a0d19f4 - -## Commits -a0d19f4 test: tighten G03 shared header contract -9362c47 refactor: reuse shared header on G03 - -## Files changed - pages/genealogy/g03-create-genealogy.vue | 62 ++++---------------------------- - tests/g03-create-flow-contract.ps1 | 9 +++-- - tests/g03-document-flow-contract.ps1 | 4 ++- - tests/g03-visual-states-contract.ps1 | 4 +-- - 4 files changed, 17 insertions(+), 62 deletions(-) - -## Diff -diff --git a/pages/genealogy/g03-create-genealogy.vue b/pages/genealogy/g03-create-genealogy.vue -index 2bc757d..f37cadc 100644 ---- a/pages/genealogy/g03-create-genealogy.vue -+++ b/pages/genealogy/g03-create-genealogy.vue -@@ -1,30 +1,20 @@ - - - - - - ').Groups[1].Value - $positions = [regex]::Matches([regex]::Replace($style, '(?s)/\*.*?\*/', ''), '(?m)\bposition\s*:\s*([^;]+);') - if ($positions.Count -ne 1 -or $positions[0].Groups[1].Value.Trim() -ne 'fixed') { - throw "G03 must retain only its combined fixed dialog layer rule; found $($positions.Count) position declarations" - } - foreach ($required in @( -- 'background: url("/static/assets/foundation/opaque/root-header-cinnabar.jpg")', - 'background: url("/static/assets/modules/genealogy/transparent/g01-empty-panel-frame.png")', - 'background: url("/static/assets/modules/auth/transparent/a01-scroll-dialog-v3.png")', - 'background: url("/static/assets/foundation/transparent/a01-scroll-primary-v3.png")' - )) { if ($page -notmatch [regex]::Escape($required)) { throw "G03 is missing real asset background: $required" } } -+foreach ($forbidden in @('flow-header', 'root-header-cinnabar.jpg')) { -+ if ($page -match [regex]::Escape($forbidden)) { throw "G03 must not retain private header token: $forbidden" } -+} - Write-Output 'G03-DOCUMENT-FLOW-CONTRACT PASS' -diff --git a/tests/g03-visual-states-contract.ps1 b/tests/g03-visual-states-contract.ps1 -index 5342acb..d539bc5 100644 ---- a/tests/g03-visual-states-contract.ps1 -+++ b/tests/g03-visual-states-contract.ps1 -@@ -2,22 +2,22 @@ $ErrorActionPreference = 'Stop' - - $root = Split-Path -Parent $PSScriptRoot - $g03 = Get-Content -LiteralPath (Join-Path $root 'pages/genealogy/g03-create-genealogy.vue') -Raw -Encoding utf8 - - function Assert-Match { - param([string]$Content, [string]$Pattern, [string]$Message) - if ($Content -notmatch $Pattern) { throw $Message } - } - - if ($g03 -match '返回') { throw 'G03 header must use only the approved image back arrow' } --Assert-Match -Content $g03 -Pattern '(?s)\.flow-header__back,\s*\.flow-header__side\s*\{[^}]*width:\s*72rpx;' -Message 'G03 header side slots must preserve centered title after removing back text' --Assert-Match -Content $g03 -Pattern '(?s)\.flow-header__back-icon\s*\{[^}]*width:\s*34rpx;[^}]*height:\s*34rpx;' -Message 'G03 back arrow must use the approved visible size' -+Assert-Match -Content $g03 -Pattern '(?s)' -Message 'G03 must use PageHeader with its dynamic title and custom back handler' -+if ($g03 -match 'flow-header|flow-header__back|flow-header__title') { throw 'G03 must not retain a private header implementation' } - Assert-Match -Content $g03 -Pattern '(?s)\.flow-note,\s*\.flow-rule__note\s*\{[^}]*font-size:\s*25rpx;' -Message 'G03 guidance copy must use the approved readable size' - Assert-Match -Content $g03 -Pattern '(?s)\.flow-rule__option\s*\{[^}]*font-size:\s*23rpx;' -Message 'G03 visibility options must use the approved readable size' - Assert-Match -Content $g03 -Pattern '(?s)\.field-error\s*\{[^}]*font-size:\s*24rpx;[^}]*line-height:\s*34rpx;' -Message 'G03 field errors must use the approved readable size' - Assert-Match -Content $g03 -Pattern '(?s)\.flow-error\s*\{[^}]*font-size:\s*25rpx;[^}]*line-height:\s*36rpx;' -Message 'G03 submit errors must use the approved readable size' - - foreach ($asset in @('a01-scroll-dialog-v3.png', 'a01-scroll-primary-v3.png', 'a01-scroll-secondary-v3.png')) { - if ($g03 -notmatch [regex]::Escape($asset)) { throw "G03 must retain approved shared asset: $asset" } - } - - Write-Output 'G03-VISUAL-STATES-CONTRACT PASS' diff --git a/.superpowers/sdd/review-task-3-a0d19f4..a0d19f4.diff b/.superpowers/sdd/review-task-3-a0d19f4..a0d19f4.diff deleted file mode 100644 index bbdf4e1..0000000 --- a/.superpowers/sdd/review-task-3-a0d19f4..a0d19f4.diff +++ /dev/null @@ -1,7 +0,0 @@ -# Review package: a0d19f4..a0d19f4 - -## Commits - -## Files changed - -## Diff diff --git a/.superpowers/sdd/task-1-brief.md b/.superpowers/sdd/task-1-brief.md deleted file mode 100644 index 1c5e4e4..0000000 --- a/.superpowers/sdd/task-1-brief.md +++ /dev/null @@ -1,116 +0,0 @@ -### Task 1: 为公共 PageHeader 建立安全区与返回契约 - -**Files:** -- Modify: `tests/shared-component-document-flow-contract.ps1` -- Modify: `tests/shared-interaction-accessibility-contract.ps1` -- Modify: `components/PageHeader.vue` - -**Interfaces:** -- Consumes: uni-app 提供的 `var(--status-bar-height, 0px)`、`getCurrentPages()`、`uni.navigateBack()`、`uni.reLaunch()`。 -- Produces: `customBack: Boolean = false` 属性和 `back` 事件;普通页头及占位槽均使用安全区总高度。 - -- [ ] **Step 1: 写入普通页头安全区的失败契约** - -在 `tests/shared-component-document-flow-contract.ps1` 的 PageHeader 断言中加入: - -```powershell -Assert-Match $header '(?s)\.page-header-slot\s*\{[^}]*height:\s*calc\(104rpx \+ var\(--status-bar-height, 0px\)\);' 'PageHeader secondary slot must reserve status bar plus 104rpx content height' -Assert-Match $header '(?s)\.page-header\s*\{[^}]*height:\s*calc\(104rpx \+ var\(--status-bar-height, 0px\)\);[^}]*padding-top:\s*var\(--status-bar-height, 0px\);' 'PageHeader secondary header must place its 104rpx content below the status bar' -Assert-Match $header '(?s)\.page-header-slot--root\s*\{[^}]*height:\s*calc\(124rpx \+ var\(--status-bar-height, 0px\)\);' 'PageHeader root slot height must remain unchanged' -Assert-Match $header '(?s)\.page-header--root\s*\{[^}]*height:\s*calc\(124rpx \+ var\(--status-bar-height, 0px\)\);' 'PageHeader root height must remain unchanged' -``` - -- [ ] **Step 2: 写入自定义返回的失败契约** - -在 `tests/shared-interaction-accessibility-contract.ps1` 的 PageHeader 检查中加入: - -```powershell -foreach ($token in @( - 'customBack: { type: Boolean, default: false }', - 'const emit = defineEmits(["brand", "notice", "action", "back"]);', - 'if (props.customBack) {', - 'emit("back");', - 'uni.navigateBack();', - 'uni.reLaunch({ url: props.fallbackUrl });' -)) { - if (-not $header.Contains($token)) { throw "PageHeader back contract missing: $token" } -} -``` - -- [ ] **Step 3: 运行聚焦契约并确认 RED** - -Run: - -```powershell -& powershell -ExecutionPolicy Bypass -File tests/shared-component-document-flow-contract.ps1 -& powershell -ExecutionPolicy Bypass -File tests/shared-interaction-accessibility-contract.ps1 -``` - -Expected: 两项均 FAIL,分别指出普通页头仍为固定 `104rpx`、`customBack` 合同不存在。 - -- [ ] **Step 4: 实现最小公共组件改动** - -在 `components/PageHeader.vue` 中补充属性和事件: - -```js -const props = defineProps({ - title: { type: String, required: true }, - action: { type: String, default: "" }, - root: { type: Boolean, default: false }, - unreadCount: { type: Number, default: 0 }, - fallbackUrl: { type: String, default: "/pages/genealogy/g01-my-genealogies" }, - customBack: { type: Boolean, default: false }, -}); - -const emit = defineEmits(["brand", "notice", "action", "back"]); - -const goBack = () => { - if (props.customBack) { - emit("back"); - return; - } - const stack = getCurrentPages(); - if (stack.length > 1) { - uni.navigateBack(); - return; - } - uni.reLaunch({ url: props.fallbackUrl }); -}; -``` - -把普通变体的尺寸改为: - -```scss -.page-header-slot { - height: calc(104rpx + var(--status-bar-height, 0px)); - flex: none; -} - -.page-header { - height: calc(104rpx + var(--status-bar-height, 0px)); - padding: 0 24rpx; - padding-top: var(--status-bar-height, 0px); -} -``` - -保留 `.page-header-slot--root` 与 `.page-header--root` 的现有 `124rpx` 规则不变。 - -- [ ] **Step 5: 运行聚焦契约并确认 GREEN** - -Run: - -```powershell -& powershell -ExecutionPolicy Bypass -File tests/shared-component-document-flow-contract.ps1 -& powershell -ExecutionPolicy Bypass -File tests/shared-interaction-accessibility-contract.ps1 -git diff --check -``` - -Expected: 两项输出 `PASS`,`git diff --check` 退出码为 0。 - -- [ ] **Step 6: 提交公共组件改动** - -```powershell -git add components/PageHeader.vue tests/shared-component-document-flow-contract.ps1 tests/shared-interaction-accessibility-contract.ps1 -git commit -m "fix: adapt shared page header to safe area" -``` - diff --git a/.superpowers/sdd/task-1-report.md b/.superpowers/sdd/task-1-report.md deleted file mode 100644 index 3af5a92..0000000 --- a/.superpowers/sdd/task-1-report.md +++ /dev/null @@ -1,56 +0,0 @@ -# Task 1 Report - -Status: DONE - -## Changed files - -- `components/PageHeader.vue` -- `tests/shared-component-document-flow-contract.ps1` -- `tests/shared-interaction-accessibility-contract.ps1` - -## RED - -Command: - -```powershell -& powershell -ExecutionPolicy Bypass -File tests/shared-component-document-flow-contract.ps1 -& powershell -ExecutionPolicy Bypass -File tests/shared-interaction-accessibility-contract.ps1 -``` - -Failure evidence: - -- `PageHeader secondary slot must reserve status bar plus 104rpx content height` -- `PageHeader back contract missing: customBack: { type: Boolean, default: false }` - -Both contract scripts exited with code `1`, for the expected missing behavior. - -## GREEN - -Command: - -```powershell -& powershell -ExecutionPolicy Bypass -File tests/shared-component-document-flow-contract.ps1 -& powershell -ExecutionPolicy Bypass -File tests/shared-interaction-accessibility-contract.ps1 -git diff --check -``` - -Result summary: - -- `SHARED-COMPONENT-DOCUMENT-FLOW-CONTRACT PASS` -- `SHARED-INTERACTION-ACCESSIBILITY-CONTRACT PASS` -- `git diff --check` exited `0` - -## Commit - -`2f22df6 fix: adapt shared page header to safe area` - -## Self-review - -- Normal PageHeader slot and header use `calc(104rpx + var(--status-bar-height, 0px))`; the header applies status-bar top padding. -- Root slot and header retain their `calc(124rpx + var(--status-bar-height, 0px))` rules. -- `customBack` emits `back` and returns before navigation; normal navigation retains stack-aware back and fallback relaunch behavior. -- The added contract tests cover the required exact public interface and layout declarations. - -## Concerns - -None. Git emitted existing line-ending conversion warnings during checks and commit, but all required checks passed. diff --git a/.superpowers/sdd/task-2-brief.md b/.superpowers/sdd/task-2-brief.md deleted file mode 100644 index 05fdf23..0000000 --- a/.superpowers/sdd/task-2-brief.md +++ /dev/null @@ -1,98 +0,0 @@ -### Task 2: 用公共 PageHeader 替换 G03 自建页头 - -**Files:** -- Modify: `tests/g03-visual-states-contract.ps1` -- Modify: `tests/g03-create-flow-contract.ps1` -- Modify: `tests/g03-document-flow-contract.ps1` -- Modify: `pages/genealogy/g03-create-genealogy.vue` - -**Interfaces:** -- Consumes: Task 1 的 ``。 -- Produces: G03 动态标题 `isAncestorStep ? "录入首代人物" : "创建家谱"`,以及现有 `goBack()` 对第一、第二步的业务分流。 - -- [ ] **Step 1: 将 G03 契约改成公共页头要求** - -在 `tests/g03-visual-states-contract.ps1` 删除 `.flow-header__back`、`.flow-header__side` 和 `.flow-header__back-icon` 尺寸断言,改为: - -```powershell -Assert-Match -Content $g03 -Pattern '(?s)' -Message 'G03 must use PageHeader with its dynamic title and custom back handler' -if ($g03 -match 'flow-header|flow-header__back|flow-header__title') { throw 'G03 must not retain a private header implementation' } -``` - -在 `tests/g03-create-flow-contract.ps1` 的 required 项中加入: - -```powershell -'import PageHeader from "@/components/PageHeader.vue";', -' -``` - -在 ` -``` - -本任务阶段不得引入 `appApi`、`calcMD5`、真实登录、真实微信授权或不存在的 A-02/A-03 路由;跨页跳转在 Task 5 的执行门槛满足后替换。 - -- [ ] **Step 3: 写入页面主体,保持三种入口与显式复选框** - -```vue - -``` - -- [ ] **Step 4: 完成最小 SCSS 外观** - -要求:用 `background-image` 组合 `header-cinnabar-texture-v2.jpg`、`paper-rice-texture-v2.jpg`;红头可见祠堂线描;纸面底部可见但低对比的 `footer-mountain-bamboo.png`;按钮高度至少 `88rpx`;不使用 CSS Grid、`gap`、`clip-path`、滤镜或外部 URL。协议区域不得使用“登录即表示同意”文案,未选中复选框只显示古金圆圈,选中后显示朱砂对勾。 - -- [ ] **Step 5: 运行合同测试,确认通过** - -Run: `powershell -ExecutionPolicy Bypass -File tests\a01-login-guide-contract.ps1` -Expected: `PASS A-01 login guide contract`. - -- [ ] **Step 6: 做一次静态构建健康检查** - -Run: `powershell -ExecutionPolicy Bypass -File tests\compile-audit.ps1` -Expected: `PASS compile audit`. - -- [ ] **Step 7: 提交独立 A-01 页面** - -```powershell -git add pages/auth/entry.vue pages.json tests/a01-login-guide-contract.ps1 -git commit -m "feat: add A01 login guide" -``` - -### Task 4: 视觉验收与设计状态记录 - -**Files:** -- Modify: `docs/规划.md` -- Test: `tests/a01-login-guide-contract.ps1`, HBuilderX Android 小屏预览 - -**Interfaces:** -- Consumes: Task 3 完成的页面与合同 -- Produces: D2 阶段下 A-01 的真实设计状态 - -- [ ] **Step 1: 在 HBuilderX 中预览 `pages/auth/entry` 的 `360 × 800dp` 画面** - -检查:红头、标题、三个按钮和未勾选协议同时可见;账号密码为唯一红色主操作;宣纸与山水不压住协议;没有底部 Tab。 - -- [ ] **Step 2: 手动验证两种协议状态** - -1. 初始未勾选,分别点击三个入口,均显示“请先阅读并同意相关协议”,且不跳转。 -2. 勾选后复选框显示朱砂对勾;三个入口只显示本地确认提示,不请求网络。 - -- [ ] **Step 3: 仅在上述视觉和手动检查通过后更新 `docs/规划.md`** - -将 `A-01 启动 / 登录引导页` 改为“视觉完成(已验收)”;D2 保持“进行中”,因为 A-02 至 A-06 尚未完成。 - -- [ ] **Step 4: 重跑最终验证** - -Run: - -```powershell -powershell -ExecutionPolicy Bypass -File tests\a01-login-guide-contract.ps1 -powershell -ExecutionPolicy Bypass -File tests\compile-audit.ps1 -powershell -ExecutionPolicy Bypass -File tests\uni-scss-injection.ps1 -``` - -Expected: 三条命令均输出 `PASS`. - -- [ ] **Step 5: 提交验收记录** - -```powershell -git add docs/规划.md -git commit -m "docs: mark A01 visual review" -``` - -### Task 5: D2 跨页设计完成后的路由接通(执行门槛任务) - -**Precondition:** A-02 与 A-03 的设计说明、页面文件和 `pages.json` 路由均已通过各自视觉验收;否则此任务不得开始。 - -**Files:** -- Modify: `pages/auth/entry.vue` -- Test: `tests/a01-login-guide-contract.ps1`(扩展路由断言) - -**Interfaces:** -- Consumes: A-02 的已验收密码页路由;A-03 的已验收验证码/微信回跳页路由 -- Produces: `entryRoutes`,键固定为 `password`、`phone`、`wechat` - -- [ ] **Step 1: 扩展合同,要求所有目标路由已在 `pages.json` 注册** - -```powershell -foreach ($route in @('pages/auth/password-login', 'pages/auth/phone-login')) { - if ($route -notin $paths) { throw "Missing approved auth target route: $route" } -} -``` - -- [ ] **Step 2: 将 Task 3 的本地确认提示替换为唯一的目标映射** - -```js -const entryRoutes = { - password: '/pages/auth/password-login', - phone: '/pages/auth/phone-login', - wechat: '/pages/auth/phone-login?source=wechat' -} - -const enterLogin = (entry) => { - if (!consented.value) { - uni.showToast({ title: '请先阅读并同意相关协议', icon: 'none' }) - return - } - uni.navigateTo({ url: entryRoutes[entry] }) -} -``` - -模板调用固定为 `enterLogin('password')`、`enterLogin('phone')`、`enterLogin('wechat')`。不得在 A-01 增加任何接口调用或注册入口。 - -- [ ] **Step 3: 运行合同和 A-02/A-03 各自的视觉合同** - -Run: `powershell -ExecutionPolicy Bypass -File tests\a01-login-guide-contract.ps1` -Expected: `PASS A-01 login guide contract`. - -- [ ] **Step 4: 提交跨页接通** - -```powershell -git add pages/auth/entry.vue tests/a01-login-guide-contract.ps1 -git commit -m "feat: connect A01 auth routes" -``` - -## Self-Review - -- **规格覆盖:** Task 1 和 Task 3 覆盖三入口、主次层级、本地资产、无接口和显式协议;Task 4 覆盖小屏视觉与两种协议状态;Task 5 覆盖 A-02/A-03 的跳转契约且被 D2 设计完成门槛锁住。 -- **占位检查:** 没有未落实的实现步骤。Task 2 的来源 URL 是执行时取得的审计事实;没有可验证来源即停止该任务,不得提交资产。 -- **命名一致性:** 页面状态固定为 `consented`,守卫固定为 `enterLogin`,跨页唯一映射固定为 `entryRoutes`;Task 1 与 Task 5 的测试和实现使用同一命名。 -# 已失效历史记录(2026-07-13) - -> 本计划在未完成设计归档与验收前被错误建立,现禁止执行。唯一有效的 A-01 归档为 `docs/design/A01_启动登录引导_设计记录.md`;当前工作仍以 `docs/交接记录.md` 的 G-01 验收为准。 diff --git a/docs/superpowers/plans/2026-07-13-a01-reference-asset-rebuild.md b/docs/superpowers/plans/2026-07-13-a01-reference-asset-rebuild.md deleted file mode 100644 index 4a497d8..0000000 --- a/docs/superpowers/plans/2026-07-13-a01-reference-asset-rebuild.md +++ /dev/null @@ -1,150 +0,0 @@ -# A01 Reference Asset Rebuild Implementation Plan - -> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. - -**Goal:** Rebuild A01's visible red header, paper scene, title lockup, divider knots, and button frames from the approved 412 × 915 reference while preserving real DOM interactions. - -**Architecture:** `pages/auth/entry.vue` remains the only interactive owner. Reference-derived raster assets own decorative visual details, while DOM owns button labels, icons, agreement state, and navigation. A small local asset-preparation command reads only the approved source screen, exports composited header/body layers and alpha PNG foreground assets, then leaves no runtime dependency on that command. - -**Tech Stack:** Uni-app Vue 3, scoped SCSS, PowerShell/System.Drawing asset preparation, existing PowerShell contract and alpha audits. - -## Global Constraints - -- Visual truth is `docs/design/screens/A01-启动登录引导-栅格验收-412x915.png` at 412 × 915. -- Do not render the whole reference image as page content; header, body scene, title lockup, divider knot, and button frames are distinct assets. -- Preserve A01 agreement gating and `'/pages/auth/login?agreed=1'` navigation. -- Do not modify `components/GenealogyCard.vue` or `unpackage/dist/cache/.vite/deps/*`. -- New v2 frame/title/knot assets must have transparent outer corners; remove A01's unused v1 generated ornaments. - ---- - -### Task 1: Encode the v2 reference-asset contract - -**Files:** -- Modify: `tests/a01-a02-ui-contract.ps1` -- Modify: `tests/a01-asset-alpha-audit.ps1` - -**Interfaces:** -- Consumes: current `pages/auth/entry.vue` and existing v1 A01 assets. -- Produces: a failing contract requiring `auth-header-reference-v2.png`, `auth-body-scene-v2.png`, `auth-brand-lockup-v2.png`, `auth-divider-knot-v2.png`, `auth-primary-frame-v2.png`, and `auth-secondary-frame-v2.png`. - -- [ ] **Step 1: Write the failing test** - -Add these required paths to the A01 entry contract: - -```powershell -foreach ($asset in @( - 'auth-header-reference-v2.png', 'auth-body-scene-v2.png', - 'auth-brand-lockup-v2.png', 'auth-divider-knot-v2.png', - 'auth-primary-frame-v2.png', 'auth-secondary-frame-v2.png' -)) { - Assert-Contains -Content $entry -Expected $asset -Message "Missing A01 reference asset: $asset" -} -Assert-NotContains -Content $entry -Unexpected 'auth-button-corner-v1.png' -Message 'A01 must not retain the rejected generated corner asset' -``` - -Replace the alpha-audit icon list with the four transparent v2 foreground assets and assert their source dimensions: brand lockup `240 × 110`, divider knot `80 × 48`, primary frame `291 × 65`, secondary frame `291 × 65`. Assert header `412 × 139` and body scene `412 × 776` exist as opaque scene layers. - -- [ ] **Step 2: Run test to verify it fails** - -Run: `powershell -ExecutionPolicy Bypass -File tests\a01-a02-ui-contract.ps1; powershell -ExecutionPolicy Bypass -File tests\a01-asset-alpha-audit.ps1` - -Expected: FAIL because the six `v2` paths are not referenced or do not exist. - -- [ ] **Step 3: Commit the contract only after Task 2 passes** - -Do not commit an intentionally failing contract. It is staged with the asset and page changes in Task 3. - -### Task 2: Prepare exact reference-derived v2 assets - -**Files:** -- Create: `static/assets/backgrounds/auth-header-reference-v2.png` -- Create: `static/assets/backgrounds/auth-body-scene-v2.png` -- Create: `static/assets/icons/auth/auth-brand-lockup-v2.png` -- Create: `static/assets/icons/auth/auth-divider-knot-v2.png` -- Create: `static/assets/icons/auth/auth-primary-frame-v2.png` -- Create: `static/assets/icons/auth/auth-secondary-frame-v2.png` -- Delete: `static/assets/icons/auth/auth-button-corner-v1.png` -- Delete: `static/assets/icons/auth/auth-divider-knot-v1.png` -- Delete: `static/assets/icons/auth/auth-title-cloud-v1.png` - -**Interfaces:** -- Consumes: `docs/design/screens/A01-启动登录引导-栅格验收-412x915.png`. -- Produces: fixed-pixel v2 assets used by `entry.vue`; no asset contains a clickable control or agreement copy. - -- [ ] **Step 1: Export the visual layers from the approved source** - -Use System.Drawing to read the 412 × 915 source. Crop rows `0..138` to `auth-header-reference-v2.png`. Crop rows `139..914` to `auth-body-scene-v2.png`, replacing the title, divider, button, register and agreement foreground rectangles with sampled rice-paper pixels before saving. The retained side architecture, bamboo, and lower mountain must stay in their original reference positions. - -- [ ] **Step 2: Export alpha foregrounds** - -Use the same source to create: a `240 × 110` brand lockup (dark title plus both gold clouds), an `80 × 48` divider knot, and two `291 × 65` button frame images. For the foregrounds, make the paper/background pixels transparent, preserve the exact colored ornament pixels, and for each frame clear its center rectangle while retaining the double rule and all four reference corner curls. - -- [ ] **Step 3: Inspect and audit the assets** - -Open the three frame/title/knot PNGs and confirm their outer corners are transparent and their visible artwork has no green matte. Run: `powershell -ExecutionPolicy Bypass -File tests\a01-asset-alpha-audit.ps1`. - -Expected: PASS once the Task 1 audit rules are in place. - -### Task 3: Replace the A01 decorative layer implementation - -**Files:** -- Modify: `pages/auth/entry.vue` -- Modify: `docs/design/A01_启动登录引导_设计记录.md` -- Modify: `design-qa.md` -- Modify: `tests/a01-a02-ui-contract.ps1` -- Modify: `tests/a01-asset-alpha-audit.ps1` - -**Interfaces:** -- Consumes: all six v2 assets from Task 2. -- Produces: reference-derived visuals with unchanged `toggleAgreement`, `openLogin`, `prepareWechatLogin`, `prepareRegister`, and `prepareAgreement` functions. - -- [ ] **Step 1: Update page asset ownership** - -Replace the generated header plus `header-seal` overlay with `auth-header-reference-v2.png`. Replace the current paper/scenery pair with the prepared body scene layer. Replace the text/cloud title group with `auth-brand-lockup-v2.png`; retain its wrapper only for layout. Keep CSS gold rules but replace each v1 divider ornament with `auth-divider-knot-v2.png`. - -For both button types, remove all four `.button-corner-asset` images. Add one absolute `.entry-button__frame` image that uses the matching primary or secondary frame asset. Keep the DOM icon/text group above the frame and preserve existing click handlers. - -- [ ] **Step 2: Update visual calibration values and records** - -Set the lockup and divider image dimensions to their source ratios, keep the validated vertical anchors, and remove stale v1 asset statements from the A01 design record. Update `design-qa.md` to list the latest screenshot as pending visual confirmation rather than passed. - -- [ ] **Step 3: Run the focused tests** - -Run: `powershell -ExecutionPolicy Bypass -File tests\a01-a02-ui-contract.ps1; powershell -ExecutionPolicy Bypass -File tests\a01-asset-alpha-audit.ps1; powershell -ExecutionPolicy Bypass -File tests\a01-design-record-audit.ps1; powershell -ExecutionPolicy Bypass -File tests\compile-audit.ps1` - -Expected: all four scripts print `PASS` with exit code 0. - -- [ ] **Step 4: Run full regression verification** - -Run: `Get-ChildItem -LiteralPath tests -Filter *.ps1 | Sort-Object Name | ForEach-Object { & powershell -ExecutionPolicy Bypass -File $_.FullName; if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } }; git diff --check` - -Expected: every test script passes and `git diff --check` reports no errors. - -- [ ] **Step 5: Commit the reference rebuild** - -```powershell -git add -- pages/auth/entry.vue tests/a01-a02-ui-contract.ps1 tests/a01-asset-alpha-audit.ps1 docs/design/A01_启动登录引导_设计记录.md design-qa.md static/assets/backgrounds/auth-header-reference-v2.png static/assets/backgrounds/auth-body-scene-v2.png static/assets/icons/auth/auth-brand-lockup-v2.png static/assets/icons/auth/auth-divider-knot-v2.png static/assets/icons/auth/auth-primary-frame-v2.png static/assets/icons/auth/auth-secondary-frame-v2.png static/assets/icons/auth/auth-button-corner-v1.png static/assets/icons/auth/auth-divider-knot-v1.png static/assets/icons/auth/auth-title-cloud-v1.png -git commit -m "fix: rebuild A01 reference visual assets" -``` - -### Task 4: Obtain runtime evidence - -**Files:** -- Modify: `design-qa.md` after receiving user-provided HBuilderX/Android screenshots. - -**Interfaces:** -- Consumes: rendered unchecked A01 screenshots at 412 × 915 and 320 × 568. -- Produces: a visual QA verdict grounded in those screenshots. - -- [ ] **Step 1: Compare the two same-state screenshots** - -At 412 × 915, verify: header bottom gold band and seal, side architecture/bamboo/lower mountain placements, brand lockup scale, both frame corner curls, divider knots, and agreement baseline. - -- [ ] **Step 2: Check narrow-screen safety** - -At 320 × 568, scroll to the agreement row and verify that the checkbox and all copy remain visible above the system navigation area. - -- [ ] **Step 3: Record evidence status** - -Set `design-qa.md` to `final result: passed` only if both screenshots satisfy the checks; otherwise document the remaining pixel difference and keep it pending. diff --git a/docs/superpowers/plans/2026-07-13-a01-runtime-visual-calibration.md b/docs/superpowers/plans/2026-07-13-a01-runtime-visual-calibration.md deleted file mode 100644 index 890f55e..0000000 --- a/docs/superpowers/plans/2026-07-13-a01-runtime-visual-calibration.md +++ /dev/null @@ -1,273 +0,0 @@ -# A-01 Runtime Visual Calibration Implementation Plan - -> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. - -**Goal:** Make the A-01 unchecked entry page's real DOM match the approved 412 x 915 visual reference for its header, title, dividers, buttons, registration entry, and agreement row. - -**Architecture:** `docs/design/A01_启动登录引导_设计记录.md` owns the calibrated A-01 layout contract. `pages/auth/entry.vue` consumes that contract through local scoped styles and named A-01 elements; it retains the existing local interaction handlers. `tests/a01-a02-ui-contract.ps1` guards the layout anchors and blocks the rejected registration side lines and button-corner construction. - -**Tech Stack:** uni-app Vue 3, scoped SCSS, local PNG assets, PowerShell contract scripts. - -## Global Constraints - -- Use `docs/design/screens/A01-启动登录引导-栅格验收-412x915.png` as the sole visual reference for the unchecked state. -- Keep real DOM, local-only interaction, the existing route to A-02, and explicit agreement gating. -- Do not use the whole reference image as page content, call APIs, modify A-02, or alter the existing authentication backgrounds in this task. -- Preserve vertical scrolling and `env(safe-area-inset-bottom)` for 320 x 568. -- Use local transparent PNG assets for title cloud imagery; do not use text glyphs or emoji as ornaments. - ---- - -### Task 1: Make the A-01 record the sole measured-layout owner and add a red visual contract - -**Files:** -- Modify: `docs/design/A01_启动登录引导_设计记录.md:30-33` -- Modify: `docs/superpowers/specs/2026-07-13-a01-runtime-visual-calibration-design.md:7-31` -- Modify: `docs/superpowers/specs/2026-07-13-a01-a02-static-ui-implementation-design.md:19` -- Modify: `tests/a01-a02-ui-contract.ps1:74-87` - -**Interfaces:** -- Consumes: approved `A01-启动登录引导-栅格验收-412x915.png` and the current local route/interaction contract. -- Produces: one permanent 750rpx coordinate table and a contract that rejects the old visual construction. - -- [ ] **Step 1: Replace the old prose layout values in the A-01 design record with the calibrated table** - - Replace the current fixed-layout bullets with this table. It is the only owner of these values: - - ```markdown - | 元素 | 412 × 915 像素基准 | 750rpx 实现基准 | - | --- | --- | --- | - | 朱砂家祠头图 | 高 139px | 高 253rpx | - | 标题区起点 | 红头后约 82px | `padding-top: 150rpx` | - | 标题分隔饰线 | 宽约 234px | 宽 426rpx;上、下间距独立 | - | 两个按钮 | x=60px,宽约 291px,高约 65px | `margin: 95rpx 110rpx 0`,高 118rpx | - | 两按钮间距 | 约 28px | `margin-top: 51rpx` | - | 注册入口 | 微信按钮后约 56px;无左右短线 | `margin-top: 98rpx` | - | 协议行 | 注册入口后约 70px | `margin-top: 128rpx` 加安全区 | - ``` - -- [ ] **Step 2: Remove the superseded dimensions from the static UI implementation contract** - - In `2026-07-13-a01-runtime-visual-calibration-design.md`, replace its numeric coordinate table with this ownership statement so the design record remains the only permanent coordinate source: - - ```markdown - ## Contract ownership - - `docs/design/A01_启动登录引导_设计记录.md` owns the calibrated 412 × 915 coordinate table and acceptance thresholds. This implementation specification records scope and component strategy only; it does not define duplicate layout values. - ``` - - Then replace the static UI implementation contract's layout sentence with: - - ```markdown - - A-01 的运行时布局唯一遵循 `docs/design/A01_启动登录引导_设计记录.md` 中的“412 × 915 运行时校准表”;本文件不再重复或定义按钮与间距数值。 - ``` - -- [ ] **Step 3: Extend the PowerShell contract before changing the page** - - Add these assertions immediately after the existing A-01 DOM-structure assertions: - - ```powershell - foreach ($requiredVisualAnchor in @( - 'brand-divider--top', - 'brand-divider--bottom', - 'entry-button--primary', - 'entry-button--secondary', - 'height: 253rpx', - 'padding: 150rpx 56rpx 0', - 'width: 426rpx', - 'margin: 95rpx 110rpx 0', - 'height: 118rpx', - 'margin-top: 51rpx', - 'margin-top: 98rpx', - 'margin-top: 128rpx' - )) { - Assert-Contains -Content $entry -Expected $requiredVisualAnchor -Message "Missing A-01 calibrated visual anchor: $requiredVisualAnchor" - } - foreach ($rejectedVisualConstruction in @('link-line', 'button-corner', 'class="auth-button primary-button"')) { - Assert-NotContains -Content $entry -Unexpected $rejectedVisualConstruction -Message "A-01 retains rejected visual construction: $rejectedVisualConstruction" - } - ``` - -- [ ] **Step 4: Run the focused contract to prove it is red** - - Run: `powershell -ExecutionPolicy Bypass -File tests\a01-a02-ui-contract.ps1` - - Expected: failure mentioning `Missing A-01 calibrated visual anchor` or `A-01 retains rejected visual construction`. - -### Task 2: Rebuild A-01's measured DOM layout without changing its interaction contract - -**Files:** -- Modify: `pages/auth/entry.vue:11-65,145-324` -- Test: `tests/a01-a02-ui-contract.ps1` - -**Interfaces:** -- Consumes: the measured A-01 table from the design record and existing `openLogin`, `prepareWechatLogin`, `prepareRegister`, and `toggleAgreement` handlers. -- Produces: `brand-divider--top`, `brand-divider--bottom`, `entry-button--primary`, and `entry-button--secondary` rendered from real DOM. - -- [ ] **Step 1: Replace the entry markup that creates the rejected decorations** - - Keep the existing cloud `image` source, but split the dividers by purpose, remove the registration side lines, remove the four corner views, and use A-01-specific button classes: - - ```vue - - - - - - - - - - 登录 - - - - 微信登录 - - - 还没有账号?注册账号 - - - ``` - - Render the second divider after `brand-subtitle` with the same child structure and class `brand-divider--bottom`. - -- [ ] **Step 2: Replace the old generic layout selectors with these calibrated scoped rules** - - Keep the existing background and script blocks unchanged. Replace `.auth-header` through `.link-hover` with the following A-01 rules: - - ```scss - .auth-header { position: relative; height: 253rpx; overflow: hidden; } - - .brand-intro { - display: flex; - flex-direction: column; - align-items: center; - padding: 150rpx 56rpx 0; - color: #3f2c1d; - } - - .brand-divider { - display: flex; - align-items: center; - justify-content: center; - width: 426rpx; - } - .brand-divider--top { margin: 47rpx 0 21rpx; } - .brand-divider--bottom { margin: 34rpx 0 30rpx; } - .brand-divider__line { flex: 1; height: 1rpx; background: #d5a34f; } - .brand-divider__ornament { width: 44rpx; height: 24rpx; margin: 0 14rpx; } - - .entry-actions { margin: 95rpx 110rpx 0; } - .entry-button { - position: relative; - display: flex; - align-items: center; - justify-content: center; - box-sizing: border-box; - width: 100%; - height: 118rpx; - border: 2rpx solid #d8ad63; - border-radius: 6rpx; - font-family: STKaiti, KaiTi, serif; - font-size: 38rpx; - letter-spacing: 4rpx; - } - .entry-button::after { - position: absolute; - inset: 10rpx; - border: 1rpx solid rgba(225, 180, 105, 0.92); - border-radius: 2rpx; - content: ''; - pointer-events: none; - } - .entry-button--primary { - border-color: #9e170e; - background: #b7170d; - color: #fffaf0; - } - .entry-button--primary::after { border-color: #edc67c; } - .entry-button--secondary { - margin-top: 51rpx; - background: rgba(255, 252, 245, 0.82); - color: #60442f; - } - .entry-button__icon { width: 46rpx; height: 46rpx; margin-right: 18rpx; } - .entry-button__icon--wechat { width: 52rpx; } - .entry-button--primary .entry-button__icon { filter: brightness(0) invert(1); } - .entry-button > text { position: relative; z-index: 1; } - .entry-button--pressed { opacity: 0.84; } - - .register-link { - display: flex; - align-items: center; - justify-content: center; - margin-top: 98rpx; - color: #60442f; - font-family: STKaiti, KaiTi, serif; - font-size: 30rpx; - letter-spacing: 2rpx; - white-space: nowrap; - } - .agreement-row { margin-top: 128rpx; } - ``` - - Delete `.gold-divider`, `.divider-line`, `.divider-ornament`, `.auth-button`, `.primary-button`, `.secondary-button`, `.button-icon`, `.wechat-icon`, `.button-hover`, `.button-corner`, all `.corner-*` selectors, and `.link-line`. Do not change any handler or copy. - -- [ ] **Step 3: Run the focused contract and relevant compilation audits** - - Run: - - ```powershell - powershell -ExecutionPolicy Bypass -File tests\a01-a02-ui-contract.ps1 - powershell -ExecutionPolicy Bypass -File tests\vue3-entry.ps1 - powershell -ExecutionPolicy Bypass -File tests\compile-audit.ps1 - ``` - - Expected: all three scripts print `PASS`; the focused contract prints `A01-A02-UI-CONTRACT PASS`. - -### Task 3: Record the completed static change and request runtime evidence - -**Files:** -- Modify: `docs/design/A01_启动登录引导_设计记录.md:51-57` -- Modify: `design-qa.md:1-31` -- Test: `tests/a01-a02-ui-contract.ps1`, `tests/vue3-entry.ps1`, `tests/compile-audit.ps1` - -**Interfaces:** -- Consumes: passing static contract and a page that still needs HBuilderX/Android visual evidence. -- Produces: an honest handoff that separates static verification from runtime screenshot acceptance. - -- [ ] **Step 1: Update the design record's verification state** - - Add this sentence under the runtime-verification gap: - - ```markdown - - 2026-07-13 已按 412 × 915 参考图重新校准真实 DOM 的标题区、分隔饰线、双按钮、注册入口与协议行;静态合同通过,但仍须由同尺寸 HBuilderX 或 Android 截图叠图确认,未确认前不得标记 A-01 完成。 - ``` - -- [ ] **Step 2: Replace the stale QA finding with the exact next capture** - - Set `design-qa.md` to state that the source remains `A01-启动登录引导-栅格验收-412x915.png`, static calibration has passed, and the sole remaining evidence is an unchecked `412 x 915` HBuilderX/Android capture without browser chrome plus a `320 x 568` safety/scroll capture. - -- [ ] **Step 3: Run the final static verification and inspect the scoped diff** - - Run: - - ```powershell - powershell -ExecutionPolicy Bypass -File tests\a01-a02-ui-contract.ps1 - powershell -ExecutionPolicy Bypass -File tests\vue3-entry.ps1 - powershell -ExecutionPolicy Bypass -File tests\compile-audit.ps1 - git diff --check - git diff -- pages/auth/entry.vue tests/a01-a02-ui-contract.ps1 docs/design/A01_启动登录引导_设计记录.md docs/superpowers/specs/2026-07-13-a01-runtime-visual-calibration-design.md docs/superpowers/specs/2026-07-13-a01-a02-static-ui-implementation-design.md design-qa.md - ``` - - Expected: all scripts pass, `git diff --check` is silent, and no interaction, route, or API code is changed. - -- [ ] **Step 4: Commit only the A-01 calibration work** - - ```powershell - git add -- pages/auth/entry.vue tests/a01-a02-ui-contract.ps1 docs/design/A01_启动登录引导_设计记录.md docs/superpowers/specs/2026-07-13-a01-runtime-visual-calibration-design.md docs/superpowers/specs/2026-07-13-a01-a02-static-ui-implementation-design.md design-qa.md - git commit -m "fix: calibrate A01 entry visual layout" - ``` - - Expected: the commit includes only the listed A-01 files; it must not include `components/GenealogyCard.vue` or Vite cache files. diff --git a/docs/superpowers/plans/2026-07-13-a01-text-registration-evidence.md b/docs/superpowers/plans/2026-07-13-a01-text-registration-evidence.md deleted file mode 100644 index 884fb83..0000000 --- a/docs/superpowers/plans/2026-07-13-a01-text-registration-evidence.md +++ /dev/null @@ -1,312 +0,0 @@ -# A-01 Text Registration Entry Design Evidence Implementation Plan - -> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. - -**Goal:** 完成 A-01“登录 + 微信登录 + 文字注册入口”的可归档设计证据与 Android 固定栅格验收口径,不修改 uni-app 页面、接口或打包。 - -**Architecture:** `docs/design/A01_启动登录引导_设计记录.md` 是 A-01 当前规则的唯一所有者。PowerShell 审计脚本只验证该记录、归档效果稿和项目内静态资产;四个尺寸的效果稿是静态设计验证,不冒充 uni-app 运行时验收。 - -**Tech Stack:** Markdown、PNG/JPG 静态资产、PowerShell 5.1、内置图像生成工具、HBuilderX Web 浏览器(仅在页面实现阶段用于运行时验收)。 - -## Global Constraints - -- 只做 `D2 / A-01` 的设计证据;不改 `.vue`、路由、接口、真实登录、Android 打包或依赖。 -- 当前设计唯一所有者是 `docs/design/A01_启动登录引导_设计记录.md`;本计划和所有审计脚本不得重复定义入口规则。 -- A-01 只有朱砂红“登录”主按钮、古金描边“微信登录”按钮和“还没有账号?注册账号”文字入口。 -- 登录进入 A-02;A-02 承接“账号密码登录 / 手机验证码登录”双标签;微信授权属于 A-03,注册属于 A-04,忘记密码属于 A-05。 -- 协议复选框默认未勾选。任何进入操作都不能默认视为用户同意协议;未勾选仅提示用户先确认协议。 -- 使用 Android `rpx + flex` 设计口径,不使用 CSS Grid 或 `gap`;底部安全区规则必须使用 `env(safe-area-inset-bottom)`。 -- 登录欢迎页的头图、宣纸和山水必须是 A-01 独立资产,不复用 G-01 的 `footer-mountain-bamboo.png`。 -- 功能图标必须为项目内 `96 × 96px` RGBA 透明 PNG;微信标志只使用官方或许可来源的原色透明 PNG,不重绘或改色。 -- 效果稿 v1、v2 是历史证据,保留但不可作为当前入口结构依据;当前整页效果稿 v3 也不能充当真实背景或图标资产。 - -## File Structure - -| 文件 | 职责 | -| --- | --- | -| `docs/design/A01_启动登录引导_设计记录.md` | A-01 当前入口、栅格、状态、资产清单与静态验收结论的唯一设计来源。 | -| `tests/a01-design-record-audit.ps1` | 验证当前入口、路由归属、栅格约束和 v3 效果稿的归档存在。 | -| `static/assets/backgrounds/auth-ancestral-header-v1.png` | A-01 独立朱砂家祠头图,`750 × 196px`。 | -| `static/assets/backgrounds/auth-rice-paper-v1.jpg` | A-01 独立暖宣纸纹理,`750 × 1334px`。 | -| `static/assets/backgrounds/auth-ink-scenery-v1.png` | A-01 独立淡墨建筑、竹影与山水叠层,`750 × 1334px`。 | -| `static/assets/icons/auth/login-outline-v1.png` | 登录按钮使用的 `96 × 96px` 透明 PNG。 | -| `static/assets/icons/auth/wechat-licensed-v1.png` | 微信按钮使用的 `96 × 96px` 许可来源、原色透明 PNG。 | -| `tests/a01-asset-alpha-audit.ps1` | 验证 A-01 图标的尺寸、透明角和可见像素,以及 A-01 独立背景文件。 | -| `docs/design/screens/A01-启动登录引导-栅格验收-320x568.png` | 320 × 568 静态设计效果稿。 | -| `docs/design/screens/A01-启动登录引导-栅格验收-360x640.png` | 360 × 640 静态设计效果稿。 | -| `docs/design/screens/A01-启动登录引导-栅格验收-360x800.png` | 360 × 800 静态设计效果稿。 | -| `docs/design/screens/A01-启动登录引导-栅格验收-412x915.png` | 412 × 915 静态设计效果稿。 | - ---- - -### Task 1: 锁定当前入口与固定栅格的审计关口 - -**Files:** - -- Modify: `tests/a01-design-record-audit.ps1` -- Test: `tests/a01-design-record-audit.ps1` - -**Interfaces:** - -- Consumes: UTF-8 Base64 文本解码函数 `ConvertFrom-Utf8Base64`、A-01 设计记录和效果稿 v3。 -- Produces: 退出码 `0` 与 `A01-DESIGN-RECORD-AUDIT PASS`;缺少任何规则或效果稿时抛出明确错误。 - -- [x] **Step 1: 写入会失败的栅格规则断言** - - 在现有 `$rules` 数组后增加以下代码;这些规则在本任务开始时尚未写入设计记录,因此审计应失败。 - - ```powershell - $layoutRules = @( - (ConvertFrom-Utf8Base64 '5YaF5a655a695bqmIDYzOHJweA=='), - (ConvertFrom-Utf8Base64 '5Li75oyJ6ZKu6auY5bqmIDEwOHJweA=='), - (ConvertFrom-Utf8Base64 'ZW52KHNhZmUtYXJlYS1pbnNldC1ib3R0b20p'), - (ConvertFrom-Utf8Base64 '6LSm5Y+35a+G56CB55m75b2VIC8g5omL5py66aqM6K+B56CB55m75b2V') - ) - - foreach ($rule in $layoutRules) { - if ($record -notmatch [regex]::Escape($rule)) { - throw "Missing A01 layout rule: $rule" - } - } - - $currentStructure = [regex]::Match($record, '(?s)## 2\\..*?(?=## 3\\.)').Value - $currentStructureRule = ConvertFrom-Utf8Base64 '5Lik5Liq5aSn5oyJ6ZKu5ZKM5LiA5Liq5paH5a2X5YWl5Y+j' - if ($currentStructure -notmatch [regex]::Escape($currentStructureRule)) { - throw "Missing current A01 structure rule: $currentStructureRule" - } - ``` - -- [x] **Step 2: 运行审计并确认它先失败** - - Run: - - ```powershell - powershell -NoProfile -ExecutionPolicy Bypass -File tests/a01-design-record-audit.ps1 - ``` - - Expected: `Missing A01 layout rule: 内容宽度 638rpx`。 - -- [x] **Step 3: 保持红灯测试未提交并进入 Task 2** - - 红灯只用于证明固定栅格规则确实缺失。不要单独提交失败测试;在 Task 2 将设计记录补齐并转绿后,再与设计记录一起提交。 - -### Task 2: 写入 A-01 固定栅格与状态边界 - -**Files:** - -- Modify: `docs/design/A01_启动登录引导_设计记录.md` -- Test: `tests/a01-design-record-audit.ps1` - -**Interfaces:** - -- Consumes: Task 1 的 `$layoutRules` 与当前入口结构断言。 -- Produces: 以 750rpx 设计画布表达的固定栅格、四类进入状态和明确的非运行时验收边界。 - -- [x] **Step 1: 在第 3 节加入固定栅格** - - 在“固定布局与状态边界”中加入以下内容,保持现有的入口与协议规则不变: - - ```markdown - - 固定设计画布为 `750rpx` 宽;内容宽度 638rpx,左右各 56rpx。朱砂家祠头图高 196rpx;标题与副标题区域从头图下方开始,操作区首按钮顶边固定为 646rpx。 - - 主按钮高度 108rpx,微信按钮高度 108rpx,二者间距 30rpx;注册文字在微信按钮下方 56rpx,字号 28rpx,整行居中且不得换行。两个按钮文字字号 36rpx,均单行居中。 - - 协议行使用 26rpx 字号,页面最小底部内边距为 `calc(32rpx + env(safe-area-inset-bottom))`。320 × 568 时页面允许纵向滚动,协议行与任一入口均不得落入系统导航区。 - - 仅作静态设计验证,不代表 uni-app 运行时验收;页面实现后仍须在 Android 320 × 568、360 × 640、360 × 800、412 × 915 上重新验收。 - ``` - -- [x] **Step 2: 在第 3 节加入状态表** - - 紧接固定栅格条目,加入以下表格: - - ```markdown - | 状态 | 触发 | A-01 可见结果 | 去向 | - | --- | --- | --- | --- | - | 初始未勾选 | 首次进入 | 两个按钮、注册文字与空复选框 | 留在 A-01 | - | 未同意协议 | 点击登录、微信登录或注册账号 | 提示“请先阅读并同意相关协议”,不跳转、不改变勾选状态 | 留在 A-01 | - | 登录已确认协议 | 点击“登录” | 结束 A-01 引导 | A-02,默认账号密码登录标签 | - | 微信已确认协议 | 点击“微信登录” | 结束 A-01 引导 | A-03,显示授权中、取消或失败回跳 | - | 注册已确认协议 | 点击“注册账号”文字 | 结束 A-01 引导 | A-04 | - ``` - -- [x] **Step 3: 运行审计并确认通过** - - Run: - - ```powershell - powershell -NoProfile -ExecutionPolicy Bypass -File tests/a01-design-record-audit.ps1 - ``` - - Expected: `A01-DESIGN-RECORD-AUDIT PASS`。 - -- [x] **Step 4: 检查文档差异并提交** - - ```powershell - git diff --check - git add docs/design/A01_启动登录引导_设计记录.md tests/a01-design-record-audit.ps1 - git commit -m "docs: define A01 grid and entry states" - ``` - -### Task 3: 归档 A-01 独立背景和透明图标 - -**Files:** - -- Create: `static/assets/backgrounds/auth-ancestral-header-v1.png` -- Create: `static/assets/backgrounds/auth-rice-paper-v1.jpg` -- Create: `static/assets/backgrounds/auth-ink-scenery-v1.png` -- Create: `static/assets/icons/auth/login-outline-v1.png` -- Create: `static/assets/icons/auth/wechat-licensed-v1.png` -- Create: `tests/a01-asset-alpha-audit.ps1` -- Modify: `docs/design/A01_启动登录引导_设计记录.md` -- Test: `tests/a01-asset-alpha-audit.ps1` - -**Interfaces:** - -- Consumes: Task 2 的 A-01 独立美术方向和项目现有 `tests/g01-asset-alpha-audit.ps1` 的透明角审计方式。 -- Produces: 可由页面实现消费的独立背景与两个 `96 × 96px` RGBA 透明图标;设计记录中带来源、用途、路径、尺寸和 Alpha 验收结论的资产清单。 - -- [x] **Step 1: 创建先失败的资产审计脚本** - - 创建 `tests/a01-asset-alpha-audit.ps1`,内容如下: - - ```powershell - $ErrorActionPreference = 'Stop' - - $root = Split-Path -Parent $PSScriptRoot - Add-Type -AssemblyName System.Drawing - - $backgrounds = @( - 'static/assets/backgrounds/auth-ancestral-header-v1.png', - 'static/assets/backgrounds/auth-rice-paper-v1.jpg', - 'static/assets/backgrounds/auth-ink-scenery-v1.png' - ) - $icons = @( - 'static/assets/icons/auth/login-outline-v1.png', - 'static/assets/icons/auth/wechat-official-v1.png' - ) - - foreach ($asset in $backgrounds + $icons) { - if (-not (Test-Path -LiteralPath (Join-Path $root $asset))) { - throw "Missing A01 asset: $asset" - } - } - - foreach ($asset in $icons) { - $bitmap = [System.Drawing.Bitmap]::FromFile((Join-Path $root $asset)) - $width = [int]$bitmap.Width - $height = [int]$bitmap.Height - $corners = @( - $bitmap.GetPixel(0, 0).A, - $bitmap.GetPixel(($width - 1), 0).A, - $bitmap.GetPixel(0, ($height - 1)).A, - $bitmap.GetPixel(($width - 1), ($height - 1)).A - ) - $visiblePixels = 0 - for ($y = 0; $y -lt $height; $y++) { - for ($x = 0; $x -lt $width; $x++) { - if ($bitmap.GetPixel($x, $y).A -gt 24) { $visiblePixels++ } - } - } - $bitmap.Dispose() - - if ($width -ne 96 -or $height -ne 96) { throw "$asset must be 96 x 96px." } - if (($corners | Where-Object { $_ -ne 0 }).Count -ne 0) { throw "$asset has opaque outer corners." } - if ($visiblePixels -lt 80) { throw "$asset has no usable visible artwork." } - Write-Output "PASS $asset transparent corners and visible artwork" - } - - Write-Output 'A01-ASSET-ALPHA-AUDIT PASS' - ``` - -- [x] **Step 2: 运行资产审计并确认它先失败** - - Run: - - ```powershell - powershell -NoProfile -ExecutionPolicy Bypass -File tests/a01-asset-alpha-audit.ps1 - ``` - - Expected: `Missing A01 asset: static/assets/backgrounds/auth-ancestral-header-v1.png`。 - -- [x] **Step 3: 生成或下载并记录资产** - - 生成以下三张独立背景,不能裁切或复用 G-01 背景:朱砂家祠头图 `750 × 196px`、暖宣纸纹理 `750 × 1334px`、淡墨建筑竹影山水叠层 `750 × 1334px`。将它们存到本任务列出的精确路径。 - - 为登录按钮准备古金或白色线性人物图标,保存为 `login-outline-v1.png`;从官方或明确许可来源取得未经改色的微信图标,保存为 `wechat-licensed-v1.png`。两个文件均为 `96 × 96px` RGBA PNG,四个角完全透明。 - - 在 A-01 设计记录新增“资产清单”表格,并写入以下列:资产路径、用途、来源或生成提示、尺寸、透明验收。微信条目必须填入直接来源页面与获取日期;其余四项必须写入生成提示或公开许可证来源。 - -- [x] **Step 4: 运行资产审计并确认通过** - - Run: - - ```powershell - powershell -NoProfile -ExecutionPolicy Bypass -File tests/a01-asset-alpha-audit.ps1 - ``` - - Expected: 每个图标输出一行 `PASS`,最后输出 `A01-ASSET-ALPHA-AUDIT PASS`。 - -- [x] **Step 5: 提交可消费资产与审计** - - ```powershell - git add static/assets/backgrounds/auth-ancestral-header-v1.png static/assets/backgrounds/auth-rice-paper-v1.jpg static/assets/backgrounds/auth-ink-scenery-v1.png static/assets/icons/auth/login-outline-v1.png static/assets/icons/auth/wechat-licensed-v1.png tests/a01-asset-alpha-audit.ps1 docs/design/A01_启动登录引导_设计记录.md - git commit -m "assets: add A01 login design resources" - ``` - -### Task 4: 归档四个 Android 尺寸的静态设计验收稿 - -**Files:** - -- Create: `docs/design/screens/A01-启动登录引导-栅格验收-320x568.png` -- Create: `docs/design/screens/A01-启动登录引导-栅格验收-360x640.png` -- Create: `docs/design/screens/A01-启动登录引导-栅格验收-360x800.png` -- Create: `docs/design/screens/A01-启动登录引导-栅格验收-412x915.png` -- Modify: `docs/design/A01_启动登录引导_设计记录.md` -- Modify: `docs/规划.md` -- Modify: `docs/交接记录.md` -- Test: `tests/a01-design-record-audit.ps1` - -**Interfaces:** - -- Consumes: Task 2 的 750rpx 栅格、Task 3 的独立资产和当前 v3 的视觉方向。 -- Produces: 四张按目标尺寸生成的静态设计验收稿;设计记录明确区分静态验收与页面实现后的运行时验收。 - -- [x] **Step 1: 生成四张静态验收稿** - - 使用当前 v3 作为样式参考,为每个精确尺寸单独生成整页效果稿,不裁切同一张长图。每一张都必须显示:朱砂家祠头图、标题与副标题、两个大按钮、单行文字注册入口、未勾选协议和安全区留白。 - - 验收时逐项检查:320 × 568 的“还没有账号?注册账号”不换行;四个尺寸的两个按钮文字均单行;协议行完整可见;底部内容不进入 `env(safe-area-inset-bottom)` 预留区;没有账号密码或手机验证码的独立大按钮。 - -- [x] **Step 2: 在设计记录写入静态验收结论** - - 在第 4 节增加四个效果稿链接和以下结论: - - ```markdown - - 静态设计验收已覆盖 320 × 568、360 × 640、360 × 800、412 × 915;四个尺寸均保持两个大按钮与单行文字注册入口。 - - 此结论只验证设计稿与固定栅格,不替代 uni-app 页面实现后的 Android 运行时验收。 - ``` - -- [x] **Step 3: 运行设计记录审计并检查差异** - - Run: - - ```powershell - powershell -NoProfile -ExecutionPolicy Bypass -File tests/a01-design-record-audit.ps1 - git diff --check - ``` - - Expected: `A01-DESIGN-RECORD-AUDIT PASS`,且 `git diff --check` 没有错误输出。 - -- [x] **Step 4: 更新阶段状态并提交** - - 仅当四张静态验收稿和 Task 3 资产审计均通过时,将 `docs/规划.md` 与 `docs/交接记录.md` 更新为“A-01 静态设计证据已完成,等待页面实现阶段的运行时验收”;不得写成页面已实现、接口已接通或 Android 已打包。 - - ```powershell - git add docs/design/screens/A01-启动登录引导-栅格验收-320x568.png docs/design/screens/A01-启动登录引导-栅格验收-360x640.png docs/design/screens/A01-启动登录引导-栅格验收-360x800.png docs/design/screens/A01-启动登录引导-栅格验收-412x915.png docs/design/A01_启动登录引导_设计记录.md docs/规划.md docs/交接记录.md - git commit -m "docs: archive A01 static size evidence" - ``` - -## Plan Self-Review - -- 规格覆盖:入口层级由 Task 1 审计、Task 2 固定;协议、路由和状态由 Task 2 记录;独立背景、透明图标与微信来源由 Task 3 归档;四个 Android 尺寸由 Task 4 归档。 -- 范围检查:所有任务限于设计记录、静态资源、效果稿和审计;没有 Vue、接口、登录逻辑或打包步骤。 -- 一致性检查:A-02 只承接账号密码与手机验证码双标签;A-03 只承接微信授权;A-04 只承接注册;A-05 只承接忘记密码。 -- 验收边界:四张效果稿是静态设计验证,不能替代页面实现后的真实 Android 运行时验收。 diff --git a/docs/superpowers/plans/2026-07-13-a01-v3-visual-fidelity.md b/docs/superpowers/plans/2026-07-13-a01-v3-visual-fidelity.md deleted file mode 100644 index 3d09c4d..0000000 --- a/docs/superpowers/plans/2026-07-13-a01-v3-visual-fidelity.md +++ /dev/null @@ -1,165 +0,0 @@ -# A-01 V3 Visual Fidelity Implementation Plan - -> 状态:已失效。用户否决“整张效果图作为页面视觉层”的方案;当前 A-01 必须以真实 DOM 还原 v3,见 `docs/design/A01_启动登录引导_设计记录.md`。 - -> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. - -**Goal:** Make the running A-01 page reproduce the selected 412×915 visual baseline at mobile width while preserving its existing local-only interactions. - -**Architecture:** The accepted v3 image is a complete 852 × 1846 mobile visual, including typography, ornamental borders, header, ink scenery and the empty agreement circle. `pages/auth/entry.vue` renders it at a logical width of 750rpx and layers only transparent interaction regions above it. The existing `agreed` state and local-only toast/navigation functions remain the sole interaction owner. - -**Tech Stack:** uni-app Vue 3 ` - - -``` - -Set the root to `width: 750rpx; min-height: 1625rpx;` with no `overflow: hidden`, so 320 × 568 remains scrollable. - -- [ ] **Step 2: Add only invisible v3 hit regions** - -```vue -