# Local MVP acceptance runner. No Docker, no real providers, no production DB/media. $ErrorActionPreference = "Stop" Set-StrictMode -Version Latest $root = Split-Path -Parent $PSScriptRoot $failed = $false $ran = 0 $passed = 0 $results = @() function Use-Utf8 { $env:PYTHONUTF8 = "1" $env:PYTHONIOENCODING = "utf-8" try { [Console]::OutputEncoding = [System.Text.Encoding]::UTF8 [Console]::InputEncoding = [System.Text.Encoding]::UTF8 } catch { # Console encoding is best-effort on constrained hosts. } chcp 65001 | Out-Null } function Resolve-Python { $venv = Join-Path $root "backend\.venv\Scripts\python.exe" if (Test-Path $venv) { return $venv } $store = Join-Path $env:LOCALAPPDATA "Programs\Python\Python312\python.exe" if (Test-Path $store) { return $store } return "python" } function New-IsolatedDirs { $stamp = Get-Date -Format "yyyyMMdd-HHmmss" $base = Join-Path $env:TEMP "kansho-mvp-test-$stamp-$PID" New-Item -ItemType Directory -Force -Path $base | Out-Null $media = Join-Path $base "media" New-Item -ItemType Directory -Force -Path $media | Out-Null return @{ Base = $base; Media = $media; Db = (Join-Path $base "fallback.sqlite") } } function Invoke-Step { param( [string]$Name, [scriptblock]$Action ) $script:ran++ Write-Host "" Write-Host "=== $Name ===" try { & $Action if ($LASTEXITCODE -ne 0 -and $null -ne $LASTEXITCODE) { throw "exit $LASTEXITCODE" } $script:passed++ $script:results += [pscustomobject]@{ Name = $Name; Status = "OK" } Write-Host "OK $Name" } catch { $script:failed = $true $script:results += [pscustomobject]@{ Name = $Name; Status = "FAIL"; Detail = $_.ToString() } Write-Host "FAIL $Name" Write-Host $_ throw } } Use-Utf8 $py = Resolve-Python $iso = New-IsolatedDirs Remove-Item Env:KANSHO_FAKE_PROVIDER -ErrorAction SilentlyContinue Remove-Item Env:KANSHO_FAKE_DETECT -ErrorAction SilentlyContinue $env:KANSHO_PROVIDER_KEY = "" $env:KANSHO_DETECT_PROVIDER_KEY = "" $env:KANSHO_MEDIA_ROOT = $iso.Media $env:KANSHO_DB_PATH = $iso.Db $env:KANSHO_DATA_DIR = $iso.Base Write-Host "Kansho local MVP tests" Write-Host "Python: $py" Write-Host "Isolation: $($iso.Base)" Write-Host "No live provider/detect calls. Production DB/media untouched." Write-Host "Fail-closed stays testable; suites that need a fake provider set it themselves." try { $backendTests = Get-ChildItem -Path (Join-Path $root "backend\tests") -Filter "test_*.py" | Sort-Object Name if (-not $backendTests) { throw "no backend/tests/test_*.py files found" } foreach ($test in $backendTests) { Invoke-Step -Name "backend $($test.Name)" -Action { & $py $test.FullName } } Invoke-Step -Name "frontend document.test.js" -Action { Push-Location (Join-Path $root "frontend") try { $node = Get-Command node -ErrorAction Stop & $node.Source --test "src/journal/document.test.js" } finally { Pop-Location } } Invoke-Step -Name "frontend api.error.test.js" -Action { Push-Location (Join-Path $root "frontend") try { $node = Get-Command node -ErrorAction Stop & $node.Source --test "src/api.error.test.js" } finally { Pop-Location } } Invoke-Step -Name "frontend production build" -Action { Push-Location (Join-Path $root "frontend") try { npm run build } finally { Pop-Location } } } catch { $failed = $true } finally { if (Test-Path $iso.Base) { Remove-Item -Recurse -Force $iso.Base -ErrorAction SilentlyContinue } } Write-Host "" Write-Host "=== Zusammenfassung ===" foreach ($row in $results) { Write-Host ("{0,-42} {1}" -f $row.Name, $row.Status) } Write-Host ("{0} von {1} Schritten erfolgreich." -f $passed, $ran) if ($failed) { exit 1 } Write-Host "MVP local acceptance: OK" exit 0