60%
This commit is contained in:
@@ -1,84 +1,76 @@
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
function Assert-Contains {
|
||||
param([string]$Content, [string]$Expected, [string]$Message)
|
||||
if ($Content -notmatch [regex]::Escape($Expected)) { throw $Message }
|
||||
}
|
||||
|
||||
function Assert-NoCssSurface {
|
||||
param([string]$Content, [string]$ClassName)
|
||||
foreach ($property in @('border', 'border-radius')) {
|
||||
$pattern = "(?s)\\.$ClassName\\s*\\{[^}]*\\b$property\\s*:"
|
||||
if ($Content -match $pattern) { throw "G03 must not construct .$ClassName with CSS $property" }
|
||||
}
|
||||
}
|
||||
|
||||
$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
|
||||
$profiles = Get-Content -LiteralPath (Join-Path $root 'styles/adaptive-frame-profiles.scss') -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'
|
||||
$panelPath = Join-Path $root 'static/assets/modules/genealogy/transparent/g01-empty-panel-frame.png'
|
||||
|
||||
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 be removed; first-ancestor is a G03 state' }
|
||||
if (Test-Path -LiteralPath $g04) { throw 'G04 page file must be deleted; first-ancestor is a G03 state' }
|
||||
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 @(
|
||||
'const currentStep = ref("create");',
|
||||
'const createState = ref("form");',
|
||||
'const ancestorState = ref("form");',
|
||||
'const fieldErrors = reactive({',
|
||||
'const duplicateReminderVisible = ref(false);',
|
||||
'class="duplicate-reminder-layer"',
|
||||
'if (isSubmitting.value) return;',
|
||||
'adaptive.adaptive-genealogy-state-panel',
|
||||
'a01-scroll-primary-v3.png',
|
||||
'create-flow-panel',
|
||||
'flow-primary-action',
|
||||
'import PageHeader from "@/components/PageHeader.vue";',
|
||||
'<PageHeader',
|
||||
'custom-back',
|
||||
'@back="requestBack"'
|
||||
'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()'
|
||||
)) {
|
||||
Assert-Contains -Content $g03 -Expected $required -Message "Missing G03 flow contract: $required"
|
||||
if (-not $g03.Contains($required)) { throw "G03 real-create contract missing: $required" }
|
||||
}
|
||||
foreach ($required in @(
|
||||
'GENEALOGY_ACCESS_PRESET',
|
||||
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',
|
||||
'updateLocalGenealogyPreviewAncestor'
|
||||
'removeLocalGenealogyPreview'
|
||||
'removeLocalGenealogyPreview',
|
||||
'local-created-',
|
||||
'create-flow-panel',
|
||||
'flow-success-dialog',
|
||||
'录入首代人物',
|
||||
'Date.now()',
|
||||
'goRegionParent',
|
||||
'region-picker__back',
|
||||
'region-picker-sheet'
|
||||
)) {
|
||||
Assert-Contains -Content $g03 -Expected $required -Message "G03 missing shared genealogy contract: $required"
|
||||
}
|
||||
foreach ($forbidden in @('GENEALOGY_VISIBILITY', 'createForm.visibility', 'SEARCHABLE')) {
|
||||
if ($g03.Contains($forbidden)) { throw "G03 must not retain the old or parallel access contract: $forbidden" }
|
||||
}
|
||||
Assert-Contains -Content $profiles -Expected 'g01-empty-panel-frame.png' -Message 'Adaptive genealogy panel profile must own the G03 panel asset'
|
||||
|
||||
foreach ($forbidden in @("from '@/utils/api.js'", 'appApi.', 'uni.showToast', 'uni.showModal', 'uni.showLoading', 'uni.showActionSheet', '/pages/tree/t01-tree-overview?genealogyId=', 'class="flow-header"', 'flow-header__back', 'root-header-cinnabar.jpg')) {
|
||||
if ($g03 -match [regex]::Escape($forbidden)) { throw "G03 retains forbidden implementation: $forbidden" }
|
||||
if ($g03.Contains($forbidden)) { throw "G03 must not retain speculative flow code: $forbidden" }
|
||||
}
|
||||
|
||||
foreach ($className in @('create-flow-panel', 'flow-primary-action')) {
|
||||
Assert-NoCssSurface -Content $g03 -ClassName $className
|
||||
}
|
||||
|
||||
if (-not (Test-Path -LiteralPath $panelPath)) { throw 'G03 requires the accepted genealogy paper panel bitmap' }
|
||||
Add-Type -AssemblyName System.Drawing
|
||||
$panel = [System.Drawing.Bitmap]::FromFile($panelPath)
|
||||
try {
|
||||
$corners = @(
|
||||
$panel.GetPixel(0, 0).A,
|
||||
$panel.GetPixel(($panel.Width - 1), 0).A,
|
||||
$panel.GetPixel(0, ($panel.Height - 1)).A,
|
||||
$panel.GetPixel(($panel.Width - 1), ($panel.Height - 1)).A
|
||||
)
|
||||
if (($corners | Where-Object { $_ -ne 0 }).Count -ne 0) { throw 'G03 paper panel outer corners must remain transparent' }
|
||||
} finally {
|
||||
$panel.Dispose()
|
||||
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'
|
||||
|
||||
Reference in New Issue
Block a user