$ErrorActionPreference = 'Stop' function Read-Page([string]$RelativePath) { return [System.IO.File]::ReadAllText( (Join-Path (Split-Path -Parent $PSScriptRoot) $RelativePath), [System.Text.Encoding]::UTF8 ) } function Assert-Contains([string]$Content, [string]$Expected, [string]$Message) { if (-not $Content.Contains($Expected)) { throw $Message } } $t03 = Read-Page 'pages/tree/t03-member-profile.vue' $t04 = Read-Page 'pages/tree/t04-add-relative.vue' $t05 = Read-Page 'pages/tree/t05-edit-member.vue' $t06 = Read-Page 'pages/tree/t06-edit-relationship.vue' $t08 = Read-Page 'pages/tree/t08-member-states.vue' foreach ($entry in @( @{ Name = 'T04'; Content = $t04 }, @{ Name = 'T05'; Content = $t05 }, @{ Name = 'T06'; Content = $t06 } )) { if ($entry.Content -match ')|import\s+TreeMemberForm') { throw "$($entry.Name) must own its business workflow instead of rendering TreeMemberForm" } foreach ($nativeUi in @('uni.showToast', 'uni.showModal', 'uni.showLoading', 'uni.showActionSheet')) { if ($entry.Content.Contains($nativeUi)) { throw "$($entry.Name) must not use $nativeUi" } } } foreach ($required in @( 'const addState = ref("form")', 'const addForm = reactive({', 'const relationOptions = [', 'const genderOptions = [', 'const isFirstMember = computed(', 'query.personId', 'query.mode === "first"', 'fieldErrors.name', 'fieldErrors.relation', 'add-state--form', 'add-state--success', 'add-state--error', 'class="add-relative-form"', '', 'query.personId', 'relationship-state--form', 'relationship-state--success', 'relationship-state--conflict', 'relationship-state--error', 'class="relationship-form"', '', '/pages/tree/t08-member-states?genealogyId=', '&personId=', '&state=' )) { Assert-Contains $t03 $required "T03 missing semantic member-state entry: $required" } Write-Output 'T03-T08-BUSINESS-SPECIALIZATION-CONTRACT PASS'