完成50%

This commit is contained in:
2026-07-23 08:23:59 +08:00
parent 9b0ad62df4
commit f1edc6b533
218 changed files with 24318 additions and 5514 deletions
+57 -8
View File
@@ -1,4 +1,4 @@
$ErrorActionPreference = 'Stop'
$ErrorActionPreference = 'Stop'
$root = Split-Path -Parent $PSScriptRoot
$requiredFiles = @('utils/config.js', 'utils/session.js', 'utils/genealogy-context.js', 'utils/api.js', 'pages/genealogy/g03-create-genealogy.vue', 'pages/family/f04-article-list.vue', 'pages/family/f02-publish-feed.vue')
@@ -23,7 +23,7 @@ foreach ($method in @('getCurrentGenealogyId', 'setCurrentGenealogyId', 'clearCu
}
$api = Get-Content -Raw -Encoding UTF8 (Join-Path $root 'utils/api.js')
foreach ($method in @('unwrapResponse', 'sendSmsCode', 'loginWithPassword', 'loginWithSms')) {
foreach ($method in @('unwrapResponse', 'getCaptchaRequirement', 'sendSmsCode', 'loginWithPassword', 'loginWithSms', 'registerWithPassword', 'resetPassword')) {
if ($api -notmatch [regex]::Escape($method)) {
throw "Missing auth API method: $method"
}
@@ -53,11 +53,46 @@ if ($pages -match 'pages/genealogy/g04-first-ancestor') {
throw 'G04 first-person route must be merged into G03'
}
$createFlow = Get-Content -Raw -Encoding UTF8 (Join-Path $root 'pages/genealogy/g03-create-genealogy.vue')
foreach ($token in @('step=ancestor', 'submitAncestor', 'genealogyId')) {
foreach ($token in @('currentStep.value = "ancestor"', 'submitAncestor', 'genealogyId')) {
if ($createFlow -notmatch [regex]::Escape($token)) {
throw "Missing G03 first-person flow: $token"
}
}
if ($config -notmatch "mode:\s*'mock'" -or $config -notmatch "baseUrl:\s*'https://backend-api\.ddxcjp\.cn'") {
throw 'Runtime config must retain mock isolation while owning the new HTTPS backend base URL'
}
if ($config -match '182\.61\.18\.23|http://backend-api\.ddxcjp\.cn|https://backend-api\.ddxcjp\.cn/') {
throw 'Runtime config retains an obsolete, insecure or trailing-slash backend URL'
}
if (-not $api.Contains('loginResult?.access_token') -or $api -match 'loginResult\?\.(token|accessToken|tokenValue)') {
throw 'Session adapter must consume only the current AppLoginVo.access_token contract'
}
if ($api -match 'mock-session-token|mockResult') { throw '认证链路不得生成本地伪会话或伪票据' }
if (([regex]::Matches($api, "return saveLogin\(result\)")).Count -ne 3) {
throw '密码登录、短信登录与注册必须共用唯一 AppLoginVo 会话适配器'
}
if ($api -notmatch 'import \{ hasRemoteConfig, resolveRuntimeMode, runtimeConfig \}' -or ([regex]::Matches($api, 'requireRemoteAuth\(\)')).Count -ne 6) {
throw '六个认证传输必须通过共享运行模式解析器失败关闭'
}
if ($api -match 'if \(isMockMode\(\)\)') {
throw 'Auth transports must not treat every non-mock mode as remote'
}
foreach ($token in @(
'async auditApplication(genealogyId, applicationId, { status, auditRemark = '''' })',
'data: { status, auditRemark }',
'payload.relationDesc',
'payload.applyReason'
)) {
if (-not $api.Contains($token)) { throw "G-series API adapter contract missing: $token" }
}
if ($api.Contains('data: { approved }') -or $api.Contains('payload.message')) {
throw 'G-series API adapter retains the deleted approved/message payload contract'
}
if ($api -notmatch '!/\^\[12\]\$/\.test\(status\)' -or $api -notmatch 'Array\.from\(auditRemark\)\.length > 500') {
throw 'G-series audit adapter does not enforce the OpenAPI status pattern or remark length'
}
if ($createFlow -match 'step=ancestor|query\?\.step') { throw 'G03 first-person flow must not restore the retired route step contract' }
if ($createFlow -match 'createPerson') { throw 'G03 must not retain the removed createPerson entrypoint' }
foreach ($route in @('pages/family/f04-article-list', 'pages/family/f02-publish-feed')) {
if ($pages -notmatch [regex]::Escape($route)) {
@@ -74,8 +109,18 @@ foreach ($pageFile in @('pages/genealogy/g05-genealogy-overview.vue', 'pages/tre
if ($page -notmatch 'const\s+genealogyId\s*=\s*ref\(["'']["'']\)' -or $page -notmatch 'query\.genealogyId') {
throw 'G05 must own its explicit genealogyId route context'
}
} elseif ($page -notmatch 'genealogyContext') {
throw "Missing genealogy context in $pageFile"
} elseif ($pageFile -eq 'pages/tree/t01-tree-overview.vue') {
if ($page -notmatch 'genealogyContext') {
throw 'T01 must retain the selected genealogy fallback until its domain-data phase'
}
} else {
if ($page -notmatch 'const\s+genealogyId\s*=\s*ref\(["'']["'']\)' -or
$page -notmatch 'const\s+personId\s*=\s*ref\(["'']["'']\)' -or
$page -notmatch 'query\.genealogyId' -or
$page -notmatch 'query\.personId' -or
$page -match 'genealogyContext') {
throw 'T03 must use its validated genealogyId/personId route identity without mutable global fallback'
}
}
}
@@ -93,9 +138,12 @@ foreach ($pageFile in @('pages/genealogy/g10-application-review.vue', 'pages/not
}
$applications = Get-Content -Raw -Encoding UTF8 (Join-Path $root 'pages/genealogy/g10-application-review.vue')
if ($applications -notmatch 'genealogyContext') {
throw 'Missing genealogy context in applications page'
foreach ($token in @('const genealogyId = ref("")', 'genealogyId.value = String(query.genealogyId || "")', 'getGenealogyFixtureAccess(genealogyId.value)')) {
if ($applications -notmatch [regex]::Escape($token)) {
throw "Applications page must use its explicit fail-closed route context: $token"
}
}
if ($applications -match 'genealogyContext') { throw 'Applications page must not bypass its explicit route context through global genealogy context' }
$notifications = Get-Content -Raw -Encoding UTF8 (Join-Path $root 'pages/notification/n01-message-center.vue')
foreach ($method in @('openNotice', 'markAllRead', 'notice-state--list')) {
@@ -104,11 +152,12 @@ foreach ($method in @('openNotice', 'markAllRead', 'notice-state--list')) {
if ($notifications -match "@/utils/api\.js|\bappApi\b") { throw 'Notification design page must not connect the API layer' }
$family = Get-Content -Raw -Encoding UTF8 (Join-Path $root 'pages/family/f01-family-feed.vue')
foreach ($token in @('genealogyContext', 'openSection', 'pages/family/f04-article-list', 'pages/family/f07-album-list', 'pages/records/r05-ritual-list', 'pages/records/r10-memo-list', 'pages/family/f02-publish-feed')) {
foreach ($token in @('genealogyContext', 'openSection', 'articles: "F04"', 'albums: "F07"', 'rituals: "R05"', 'memos: "R10"', 'openPage("F02"')) {
if ($family -notmatch [regex]::Escape($token)) {
throw "Missing family content flow: $token"
}
}
if ($family -match '/pages/') { throw 'F01 family content flow must use the unique navigation registry' }
$profile = Get-Content -Raw -Encoding UTF8 (Join-Path $root 'pages/profile/m01-profile-home.vue')
foreach ($token in @('profile-state--ready', 'menuItems', 'toProfile')) {