$ErrorActionPreference = 'Stop' $root = Split-Path -Parent $PSScriptRoot $pages = Get-Content -LiteralPath (Join-Path $root 'pages.json') -Raw -Encoding utf8 | ConvertFrom-Json $paths = @($pages.pages.path) $g03 = Get-Content -LiteralPath (Join-Path $root 'pages/genealogy/g03-create-genealogy.vue') -Raw -Encoding utf8 $api = Get-Content -LiteralPath (Join-Path $root 'utils/api.js') -Raw -Encoding utf8 $g04 = Join-Path $root 'pages/genealogy/g04-first-ancestor.vue' if (-not ($paths -contains 'pages/genealogy/g03-create-genealogy')) { throw 'G03 route missing' } if ($paths -contains 'pages/genealogy/g04-first-ancestor') { throw 'G04 route must remain removed' } if (Test-Path -LiteralPath $g04) { throw 'G04 page file must remain removed' } foreach ($required in @( 'v-model="form.surname"', 'v-model="form.genealogyName"', 'getRegionChildren', 'selectedRegion', 'regionPickerOpen', 'picker-view', 'picker-view-column', 'handleRegionPickerChange', 'regionPickerIndicatorStyle', 'region-sheet__picker-view', 'confirmRegionSelection', 'regionPickerColumns', 'v-model="form.originPlace"', 'v-model="form.addressDetail"', 'v-model="form.intro"', 'pickAndUploadImage', 'toConsumerOssId', 'coverOssId.value', 'GENEALOGY_ACCESS_PRESET_OPTIONS', 'toApiGenealogyAccess', 'appApi.createGenealogy', 'finishPage("G01", {}, {', 'operation: "genealogy-created"', 'createRequestController()', 'createController.abort()' )) { if (-not $g03.Contains($required)) { throw "G03 real-create contract missing: $required" } } if ($g03 -match 'v-model="(?:form\.)?regionCode"') { throw 'G03 must not expose a raw region code input' } if ($g03 -match 'v-model="(?:form\.)?coverOssId"') { throw 'G03 must not expose a raw cover OSS ID input' } if ($g03.Contains('AppDialog')) { throw 'G03 region selector must not use the generic dialog card wall' } if ($g03.Contains('继续选择')) { throw 'G03 region selector must not repeat a continuation label on every option' } foreach ($forbidden in @( 'createLocalGenealogyPreview', 'updateLocalGenealogyPreview', 'removeLocalGenealogyPreview', 'local-created-', 'create-flow-panel', 'flow-success-dialog', '录入首代人物', 'Date.now()', 'goRegionParent', 'region-picker__back', 'region-picker-sheet' )) { if ($g03.Contains($forbidden)) { throw "G03 must not retain speculative flow code: $forbidden" } } foreach ($required in @( "url: '/genealogy/app/genealogies'", "method: 'POST'", 'normalizeGenealogyCreatePayload', 'normalizeCreatedGenealogy', 'coverOssId', 'REMOTE_WRITE_REQUIRED' )) { if (-not $api.Contains($required)) { throw "G03 API contract missing: $required" } } if ($api.Contains('genealogies.unshift(created)')) { throw 'G03 API must not create a local preview record' } Write-Output 'G03-CREATE-FLOW-CONTRACT PASS'