完成70%

This commit is contained in:
2026-07-24 07:56:22 +08:00
parent bb6431b319
commit c7f278fe79
92 changed files with 4741 additions and 14440 deletions
+16 -10
View File
@@ -116,7 +116,7 @@ Assert-Matches -Content $a01 -Pattern '(?s)onBackPress\(\(event\) => \{\s*if \(!
Assert-Contains -Content $a04 -Expected 'import AppDialog from "@/components/AppDialog.vue";' -Message 'A04 必须使用项目对话框确认放弃表单'
Assert-Contains -Content $a04 -Expected 'import { createDiscardConfirmation } from "@/utils/discard-confirmation.js";' -Message 'A04 必须消费唯一放弃确认控制器'
Assert-Contains -Content $a04 -Expected 'const isDirty = computed(() =>' -Message 'A04 必须计算未保存表单状态'
Assert-Matches -Content $a04 -Pattern '(?s)const requestBack = \(\) =>\s*runBackGuard\(\{\s*transientOpen: tacVisible\.value \|\| discardVisible\.value,\s*submitting: submitting\.value \|\| sendingCode\.value,\s*dirty: isDirty\.value,\s*"close-transient": tacVisible\.value \? closeTac : cancelDiscard,\s*"block-submitting": \(\) => \{\s*cancelPendingRequest\(\);\s*return requestBack\(\);\s*\},\s*"confirm-discard": requestDiscardConfirmation,\s*\}\);' -Message 'A04 requestBack 必须优先关闭 TAC;请求中返回先中止网络,再恢复脏表单守卫'
Assert-Matches -Content $a04 -Pattern '(?s)const requestBack = \(\) =>\s*registrationCommitted\.value\s*\? enterAuthenticatedRoot\(\)\s*:\s*runBackGuard\(\{\s*transientOpen: tacVisible\.value \|\| discardVisible\.value,\s*submitting: submitting\.value \|\| sendingCode\.value,\s*dirty: isDirty\.value,\s*"close-transient": tacVisible\.value \? closeTac : cancelDiscard,\s*"block-submitting": \(\) => \{\s*cancelPendingRequest\(\);\s*return requestBack\(\);\s*\},\s*"confirm-discard": requestDiscardConfirmation,\s*\}\);' -Message 'A04 requestBack 必须先处理已提交状态、再优先关闭 TAC;请求中返回先中止网络,再恢复脏表单守卫'
Assert-Contains -Content $a04 -Expected 'discardConfirmation.dispose();' -Message 'A04 卸载时必须通过唯一控制器释放等待者'
Assert-Count -Content $a04 -Expected '@click="requestBack"' -Count 2 -Message 'A04 页头和已有账号入口必须共用 requestBack'
Assert-Count -Content $a04 -Expected '<AppDialog' -Count 1 -Message 'A04 只允许一个放弃确认框'
@@ -377,12 +377,14 @@ foreach ($entry in @(
foreach ($mapping in @(
'openPage("T03", { genealogyId: genealogyId.value, personId: String(selected.value.id) }, "T01")',
'openPage("T04", { genealogyId: genealogyId.value, personId: String(selected.value.id) }, "T01")',
'openPage("T06", { genealogyId: genealogyId.value, personId: String(selected.value.id) }, "T01")',
'openPage("T06", { genealogyId: genealogyId.value, personId: String(selected.value.id), mode: "rank" }, "T01")',
'openPage("T07", { genealogyId: genealogyId.value }, "T01")'
)) {
Assert-Contains -Content $t01 -Expected $mapping -Message "T01 缺少规范入口:$mapping"
}
foreach ($required in @('routeKey: "T04"', 'params.relationType = action.relationType;', 'return openPage(action.routeKey, params, "T01");')) {
Assert-Contains -Content $t01 -Expected $required -Message "T01 人物操作面板缺少 T04 关系入口:$required"
}
Assert-Contains -Content $t03 -Expected 'consumeNavigationResult("T03")' -Message 'T03 必须消费 single 页面激活请求'
Assert-Contains -Content $t03 -Expected 'internalTrail: trailIndex.value > 0' -Message 'T03 返回必须优先消费页内成员轨迹'
Assert-Contains -Content $t03 -Expected 'onBackPress((event) => handleBackPress(event, requestBack));' -Message 'T03 Android 返回必须复用页内轨迹守卫'
@@ -391,16 +393,20 @@ Assert-Contains -Content $t08 -Expected 'goRoot("G01")' -Message 'T08 权限失
Assert-Contains -Content $t08 -Expected 'goBack()' -Message 'T08 普通动作必须按真实栈返回'
foreach ($form in @(
@{ Key = 'T04'; Content = $t04; Return = 'returnTo("T01", { genealogyId: genealogyId.value })' },
@{ Key = 'T05'; Content = $t05; Return = 'return goBack();' },
@{ Key = 'T06'; Content = $t06; Return = 'returnTo("T01", { genealogyId: genealogyId.value })' }
@{ Key = 'T04'; Content = $t04; Return = 'returnTo("T01", { genealogyId: genealogyId.value })'; Write = 'appApi.createRelatedPerson(' },
@{ Key = 'T05'; Content = $t05; Return = 'return goBack();'; Write = 'appApi.updatePerson(' }
)) {
Assert-Contains -Content $form.Content -Expected '尚未提交服务器' -Message "$($form.Key) 必须明确本地预览没有写入服务器"
Assert-Contains -Content $form.Content -Expected $form.Return -Message "$($form.Key) 本地预览必须无结果返回规范目标"
foreach ($forbidden in @('finishPage(', 'relative-created', 'member-updated', 'relationship-updated')) {
Assert-Contains -Content $form.Content -Expected 'appApi.getPerson(' -Message "$($form.Key) 必须从真实后端读取当前成员"
Assert-Contains -Content $form.Content -Expected 'createRequestController' -Message "$($form.Key) 成员读取必须可取消"
Assert-Contains -Content $form.Content -Expected $form.Write -Message "$($form.Key) 必须使用已核对的远端写入 owner"
Assert-Contains -Content $form.Content -Expected $form.Return -Message "$($form.Key) 写入成功后必须保留规范返回目标"
foreach ($forbidden in @('finishPage(', 'relative-created', 'member-updated', 'relationship-updated', 'setTimeout(')) {
Assert-NotContains -Content $form.Content -Unexpected $forbidden -Message "$($form.Key) 不得在真实写入前伪造结果:$forbidden"
}
}
foreach ($required in @('appApi.getPerson(', 'createRequestController', '"unavailable"', 'goBack()')) {
Assert-Contains -Content $t06 -Expected $required -Message "T06 原子排行合同未收紧时必须显式关闭提交:$required"
}
Assert-Matches -Content $routes -Pattern '(?s)T01:\s*defineRoute\(\{(?:(?!resultOperations).)*?\}\),\s*T03:' -Message 'T01 当前不得预留 mutation 结果能力'
Assert-Matches -Content $routes -Pattern '(?s)T03:\s*defineRoute\(\{.*?resultOperations:\s*\["member-open-requested"\]' -Message 'T03 当前只能登记 single 激活结果'
@@ -669,6 +675,6 @@ foreach ($page in @(
Assert-Contains -Content $page.Content -Expected $token -Message "$($page.Key) 缺少浮层优先返回守卫:$token"
}
}
Assert-Matches -Content $m10 -Pattern '(?s)const confirmLogout = \(\) => \{\s*session\.clear\(\);\s*logoutVisible\.value = false;\s*return goRoot\("A01"\);\s*\};' -Message 'M10 退出必须依次清理唯一会话、关闭浮层并进入 A01 根语义'
Assert-Matches -Content $m10 -Pattern '(?s)const confirmLogout = async \(\) => \{.*?await appApi\.logout\(\{ requestController: logoutRequestController \}\);.*?finally \{\s*session\.clear\(\);\s*logoutVisible\.value = false;.*?\}\s*return goRoot\("A01"\);\s*\};' -Message 'M10 退出必须先尝试唯一远端 owner,再在所有结果下清理本机会话并进入 A01 根语义'
Write-Output 'NAVIGATION-FLOW-CONTRACT PASS AUTH G01-G12 T01-T08 F01-F10 R01-R11 N01-N02 M01-M10'