21 lines
1.9 KiB
PowerShell
21 lines
1.9 KiB
PowerShell
$ErrorActionPreference = 'Stop'
|
|
function Read-Utf8([string]$Path) { [System.IO.File]::ReadAllText((Join-Path (Join-Path $PSScriptRoot '..') $Path), [System.Text.Encoding]::UTF8) }
|
|
function Assert-Contains([string]$Content,[string]$Expected) { if (-not $Content.Contains($Expected)) { throw "R02 contract missing: $Expected" } }
|
|
$page = Read-Utf8 'pages/records/r02-person-detail.vue'
|
|
$catalog = Read-Utf8 'data/page-catalog.js'
|
|
foreach ($expected in @(
|
|
'class="person-detail-page"','person-detail-state--','class="person-identity-card"',
|
|
'class="person-edit-action"','class="person-save-action"','class="person-cancel-action"',
|
|
'shortFields','longFields','person-field__label','person-long-field__label','const enterEdit = () =>','const savePerson = () =>',
|
|
'const returnToPeople = () =>','r01-person-name-card.png','module-content-frame.png','module-field-frame.png',
|
|
'class="person-card-skin"','pointer-events: none','ModulePageBackground','PageHeader','AppButton','AppLoading','AppToast'
|
|
)) { Assert-Contains $page $expected }
|
|
foreach ($forbidden in @('<ModulePage page-id="r02"','import ModulePage from')) { if ($page.Contains($forbidden)) { throw "R02 retains forbidden dependency: $forbidden" } }
|
|
if ($catalog -match '(?m)^\s*r02\s*:') { throw 'R02 obsolete page-catalog owner must be removed' }
|
|
if ($page -notmatch '(?s)\.person-card-skin\s*\{[^}]*position\s*:\s*absolute\s*;') { throw 'R02 decorative skin must use a local absolute layer' }
|
|
foreach ($selector in @('.person-identity-card__copy','.person-field__label','.person-field input','.person-field-error','.person-long-field__label','.person-long-field textarea','.person-state-action')) {
|
|
$escaped = [regex]::Escape($selector)
|
|
if ($page -match "(?s)$escaped\s*\{[^}]*position\s*:\s*(absolute|fixed|sticky)\s*;") { throw "R02 normal content selector uses positioning: $selector" }
|
|
}
|
|
Write-Output 'R02-PERSON-DETAIL-CONTRACT PASS'
|