完成50%
This commit is contained in:
@@ -0,0 +1,154 @@
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
$root = Split-Path -Parent $PSScriptRoot
|
||||
$issues = New-Object System.Collections.Generic.List[string]
|
||||
|
||||
function Add-Issue {
|
||||
param([string]$Message)
|
||||
$script:issues.Add($Message)
|
||||
}
|
||||
|
||||
function Read-RequiredFile {
|
||||
param([string]$RelativePath)
|
||||
$path = Join-Path $root $RelativePath
|
||||
if (-not (Test-Path -LiteralPath $path -PathType Leaf)) {
|
||||
Add-Issue "missing required client owner: $RelativePath"
|
||||
return ''
|
||||
}
|
||||
return Get-Content -Raw -Encoding UTF8 -LiteralPath $path
|
||||
}
|
||||
|
||||
function Assert-Contains {
|
||||
param([string]$Content, [string]$Label, [string]$Expected)
|
||||
if (-not $Content.Contains($Expected)) {
|
||||
Add-Issue "$Label missing production ownership marker: $Expected"
|
||||
}
|
||||
}
|
||||
|
||||
function Assert-DoesNotContain {
|
||||
param([string]$Content, [string]$Label, [string]$Forbidden)
|
||||
if ($Content.Contains($Forbidden)) {
|
||||
Add-Issue "$Label retains retired preview/legacy owner: $Forbidden"
|
||||
}
|
||||
}
|
||||
|
||||
$page = Read-RequiredFile 'pages/genealogy/g03-create-genealogy.vue'
|
||||
$api = Read-RequiredFile 'utils/api.js'
|
||||
$coordinator = Read-RequiredFile 'utils/genealogy-bootstrap.js'
|
||||
$accessContract = Read-RequiredFile 'utils/genealogy-contracts.js'
|
||||
$mock = Read-RequiredFile 'data/mock.js'
|
||||
$staticContract = Read-RequiredFile 'tests/g03-create-flow-contract.ps1'
|
||||
$legacyRuntimeSmoke = Read-RequiredFile 'tests/g03-create-flow-runtime-smoke.js'
|
||||
$runtimePath = Join-Path $root 'tests/g03-bootstrap-runtime-smoke.js'
|
||||
|
||||
# Keep only durable public ownership checks here. Internal helper names, cache strategy,
|
||||
# debounce timers, and test titles are intentionally left to executable behavior tests.
|
||||
Assert-Contains $page 'G03 page' '@/utils/genealogy-bootstrap.js'
|
||||
Assert-Contains $page 'G03 page' 'createGenealogyBootstrapCoordinator'
|
||||
Assert-Contains $api 'utils/api.js' '/genealogy/app/genealogies'
|
||||
Assert-Contains $api 'utils/api.js' '/genealogy/app/genealogy-bootstrap-operations/'
|
||||
Assert-Contains $api 'utils/api.js' '/genealogy/app/region/search'
|
||||
Assert-Contains $api 'utils/api.js' 'Idempotency-Key'
|
||||
Assert-Contains $coordinator 'utils/genealogy-bootstrap.js' 'createGenealogyBootstrapCoordinator'
|
||||
|
||||
foreach ($entry in @(
|
||||
[pscustomobject]@{ Content = $page; Label = 'G03 page' },
|
||||
[pscustomobject]@{ Content = $mock; Label = 'data/mock.js' },
|
||||
[pscustomobject]@{ Content = $staticContract; Label = 'G03 static flow contract' },
|
||||
[pscustomobject]@{ Content = $legacyRuntimeSmoke; Label = 'G03 legacy runtime smoke' }
|
||||
)) {
|
||||
foreach ($retiredOwner in @(
|
||||
'createLocalGenealogyPreview',
|
||||
'updateLocalGenealogyPreview',
|
||||
'updateLocalGenealogyPreviewAncestor',
|
||||
'removeLocalGenealogyPreview',
|
||||
'local-created-'
|
||||
)) {
|
||||
Assert-DoesNotContain $entry.Content $entry.Label $retiredOwner
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($retiredApiOwner in @('async createGenealogy(', 'genealogies.unshift(created)')) {
|
||||
Assert-DoesNotContain $api 'utils/api.js' $retiredApiOwner
|
||||
}
|
||||
foreach ($retiredAccessOwner in @(
|
||||
'visibility:',
|
||||
'joinMode:',
|
||||
'fromApiGenealogyAccess',
|
||||
'toApiGenealogyAccess'
|
||||
)) {
|
||||
Assert-DoesNotContain $accessContract 'utils/genealogy-contracts.js' $retiredAccessOwner
|
||||
}
|
||||
|
||||
# The release gate executes the dependency-injected state machine suite. The suite must
|
||||
# deep-compare the exact marker, use request/storage/cache/context/navigation spies, and
|
||||
# publish a machine-readable case ledger only after all assertions pass.
|
||||
$expectedCases = @(
|
||||
'ACCOUNT_EPOCH_ISOLATION',
|
||||
'CONTEXT_FAILURE_LOCAL_RETRY',
|
||||
'FAILED_CLEAR',
|
||||
'FATAL_EXPLICIT_ABANDON_CLEAR',
|
||||
'KEY_REUSED_QUARANTINE',
|
||||
'KNOWN_NO_COMMIT',
|
||||
'LOCAL_ZERO_DISPATCH',
|
||||
'MARKER_EXACT',
|
||||
'NAVIGATION_FAILURE_LOCAL_RETRY',
|
||||
'NO_MOCK_MUTATION',
|
||||
'NO_NEW_KEY',
|
||||
'NO_PII',
|
||||
'PENDING_RETRY_AFTER',
|
||||
'POST_408_UNKNOWN',
|
||||
'POST_CANCEL_UNKNOWN',
|
||||
'POST_UNEXPECTED_STATUS_UNKNOWN',
|
||||
'POST_UNKNOWN',
|
||||
'PRECLAIM_400',
|
||||
'PRECLAIM_401',
|
||||
'PRECLAIM_403',
|
||||
'PROCESS_RECOVERY_STATUS_ONLY',
|
||||
'REQUEST_BUILD_ZERO_DISPATCH',
|
||||
'RETRY_429',
|
||||
'STATUS_400_CLEAR',
|
||||
'STATUS_401_CLEAR_SESSION',
|
||||
'STATUS_404_KEEP',
|
||||
'STATUS_429_KEEP',
|
||||
'STATUS_500_KEEP',
|
||||
'STATUS_CANCEL_KEEP',
|
||||
'STATUS_MALFORMED_KEEP',
|
||||
'STATUS_NETWORK_KEEP',
|
||||
'STATUS_UNEXPECTED_STATUS_KEEP',
|
||||
'SUCCEEDED_ORDER'
|
||||
) | Sort-Object
|
||||
|
||||
if (-not (Test-Path -LiteralPath $runtimePath -PathType Leaf)) {
|
||||
Add-Issue 'missing executable state-machine suite: tests/g03-bootstrap-runtime-smoke.js'
|
||||
} else {
|
||||
$runtimeOutput = @(& node $runtimePath 2>&1)
|
||||
$runtimeExit = $LASTEXITCODE
|
||||
if ($runtimeExit -ne 0) {
|
||||
Add-Issue "G03 runtime state-machine suite failed: $($runtimeOutput -join ' | ')"
|
||||
} else {
|
||||
if ('G03-BOOTSTRAP-RUNTIME PASS' -notin $runtimeOutput) {
|
||||
Add-Issue 'G03 runtime state-machine suite did not emit its PASS marker'
|
||||
}
|
||||
$coverageLine = @($runtimeOutput | Where-Object { $_ -like 'G03-BOOTSTRAP-RUNTIME-COVERAGE *' })
|
||||
if ($coverageLine.Count -ne 1) {
|
||||
Add-Issue 'G03 runtime state-machine suite must emit exactly one coverage ledger'
|
||||
} else {
|
||||
$actualCases = @(($coverageLine[0] -replace '^G03-BOOTSTRAP-RUNTIME-COVERAGE\s+', '').Split(',') | Where-Object { $_ } | Sort-Object)
|
||||
if (($actualCases -join ',') -ne ($expectedCases -join ',')) {
|
||||
Add-Issue "G03 runtime coverage ledger drifted: $($actualCases -join ',')"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($issues.Count -gt 0) {
|
||||
$lines = New-Object System.Collections.Generic.List[string]
|
||||
$lines.Add('G03-BOOTSTRAP-CLIENT-RELEASE BLOCKED')
|
||||
foreach ($issue in $issues) { $lines.Add("- $issue") }
|
||||
$lines.Add('- Keep the honest local preview until backend, workspace, client, and MuMu release gates are green.')
|
||||
$lines.Add('- Migrate the coordinator, strict transport, marker/status recovery, context, fixtures, focused tests, and docs as one owner change.')
|
||||
throw ($lines -join [Environment]::NewLine)
|
||||
}
|
||||
|
||||
Write-Output 'G03-BOOTSTRAP-CLIENT-RELEASE PASS'
|
||||
Reference in New Issue
Block a user