# Semantic keyword full validation: 8 context scenarios + per-word catalog (6 categories). # Usage: # cd d:\ylrz_saas_new\java\scripts # .\lobster_semantic_context_validation.ps1 # .\lobster_semantic_context_validation.ps1 -Mode catalog param( [string]$ApiBase = "http://127.0.0.1:8006", [int]$CompanyId = 338, [int]$TenantId = 33, [string]$OpsSecret = "lobster-dev-ops", [ValidateSet("full", "catalog")] [string]$Mode = "full" ) $ErrorActionPreference = "Stop" try { [Console]::OutputEncoding = [System.Text.Encoding]::UTF8 $OutputEncoding = [System.Text.Encoding]::UTF8 } catch { } $utf8NoBom = New-Object System.Text.UTF8Encoding $false $reportDir = Join-Path $PSScriptRoot "reports" if (-not (Test-Path $reportDir)) { New-Item -ItemType Directory -Path $reportDir | Out-Null } $stamp = Get-Date -Format "yyyyMMdd-HHmmss" $reportFile = Join-Path $reportDir "lobster-semantic-context-validation-$stamp.json" Write-Host "=== Lobster Semantic Keyword Validation ($Mode) ===" -ForegroundColor Cyan Write-Host "ApiBase=$ApiBase CompanyId=$CompanyId TenantId=$TenantId" try { $pingHeaders = @{ "X-Lobster-Ops-Secret" = $OpsSecret } Invoke-RestMethod -Uri "$ApiBase/api/lobster/admin/phase2/verify/$CompanyId?tenantId=$TenantId" -Headers $pingHeaders -TimeoutSec 15 | Out-Null Write-Host "OK service reachable" -ForegroundColor Green } catch { Write-Host "FAIL service not reachable at $ApiBase" -ForegroundColor Red exit 1 } if ($Mode -eq "catalog") { $uri = "$($ApiBase.TrimEnd('/'))/api/lobster/admin/validation/semantic-catalog/${CompanyId}?tenantId=${TenantId}" } else { $uri = "$($ApiBase.TrimEnd('/'))/api/lobster/admin/validation/semantic-context/${CompanyId}?tenantId=${TenantId}&mode=full" } $headers = @{ "Content-Type" = "application/json" "X-Lobster-Ops-Secret" = $OpsSecret } Write-Host "POST $uri" try { $resp = Invoke-RestMethod -Uri $uri -Method Post -Headers $headers -TimeoutSec 600 $json = $resp | ConvertTo-Json -Depth 30 [System.IO.File]::WriteAllText($reportFile, $json, $utf8NoBom) Write-Host "Report saved: $reportFile" -ForegroundColor Green } catch { Write-Host "FAIL request error: $($_.Exception.Message)" -ForegroundColor Red exit 1 } Write-Host "" Write-Host "Duration: $($resp.durationMs)ms" Write-Host "Total cases: $($resp.totalCases) Passed: $($resp.passedCases)" -ForegroundColor $(if ($resp.passed) { "Green" } else { "Yellow" }) if ($resp.sections.catalogValidation.categories) { Write-Host "" Write-Host "Catalog by category:" -ForegroundColor Cyan $cats = $resp.sections.catalogValidation.categories foreach ($prop in $cats.PSObject.Properties) { $c = $prop.Value $color = if ($c.passed) { "Green" } else { "Red" } $label = $prop.Name Write-Host " $label : keywords=$($c.keywordCount) checks=$($c.totalCases)/$($c.passedCases) passed=$($c.passed)" -ForegroundColor $color if ($c.failures -and $c.failures.Count -gt 0) { $show = [Math]::Min(5, $c.failures.Count) for ($i = 0; $i -lt $show; $i++) { Write-Host " - $($c.failures[$i])" -ForegroundColor Red } if ($c.failures.Count -gt 5) { Write-Host " ... +$($c.failures.Count - 5) more" -ForegroundColor Red } } } } elseif ($resp.categories) { Write-Host "" Write-Host "Catalog by category:" -ForegroundColor Cyan foreach ($prop in $resp.categories.PSObject.Properties) { $c = $prop.Value $color = if ($c.passed) { "Green" } else { "Red" } Write-Host " $($prop.Name) : keywords=$($c.keywordCount) checks=$($c.totalCases)/$($c.passedCases)" -ForegroundColor $color } } if ($resp.contextCases) { Write-Host "" Write-Host "Context scenarios:" -ForegroundColor Cyan foreach ($c in $resp.contextCases) { $color = if ($c.passed) { "Green" } else { "Red" } Write-Host " [$($c.id)] $($c.input) -> $($c.passed)" -ForegroundColor $color } } if ($resp.failures -and $resp.failures.Count -gt 0) { Write-Host "" Write-Host "Failures:" -ForegroundColor Red foreach ($f in $resp.failures) { Write-Host " - $f" -ForegroundColor Red } } if ($resp.passed) { Write-Host "" Write-Host "RESULT: PASS" -ForegroundColor Green exit 0 } else { Write-Host "" Write-Host "RESULT: FAIL ($($resp.message))" -ForegroundColor Red exit 1 }