chore: establish local platform baseline

This commit is contained in:
Codex Local
2026-08-26 06:41:54 +08:00
commit 29bdf4900f
575 changed files with 95644 additions and 0 deletions
+42
View File
@@ -0,0 +1,42 @@
$ErrorActionPreference='Stop'
$PSNativeCommandUseErrorActionPreference=$true
$root=Split-Path -Parent $PSScriptRoot;Set-Location -LiteralPath $root
$api='http://localhost:58080';$tokenUrl='http://localhost:58180/realms/voice-local/protocol/openid-connect/token';$tenant='10000000-0000-0000-0000-000000000010';$device='10000000-0000-0000-0000-000000000511';$deviceSecret=[Text.Encoding]::UTF8.GetBytes('local-simulated-device-secret-32-bytes-minimum')
$conversation=$null;$refreshCommand=$null;$diagnosticDeviceInternal=[Guid]::NewGuid().ToString();$diagnosticDevice=[Guid]::NewGuid().ToString();$diagnosticJobInternal=[Guid]::NewGuid().ToString();$diagnosticJobAggregate=[Guid]::NewGuid().ToString();$createKey='diagnostic-create-'+[Guid]::NewGuid().ToString('N');$requestID='diagnostic-smoke-'+[Guid]::NewGuid().ToString('N')
$serialDigest=[Convert]::ToHexString([Security.Cryptography.SHA256]::HashData([Text.Encoding]::UTF8.GetBytes($diagnosticDevice))).ToLowerInvariant()
function Token([string]$name){(Invoke-RestMethod -Method Post -Uri $tokenUrl -ContentType 'application/x-www-form-urlencoded' -Body @{grant_type='password';client_id='voice-platform-web';username=$name;password='LocalOnly123!';scope='openid'}).access_token}
function SignedPost([string]$path,[string]$body,[string]$key){$bytes=[Text.Encoding]::UTF8.GetBytes($body);$digest=[Convert]::ToHexString([Security.Cryptography.SHA256]::HashData($bytes)).ToLowerInvariant();$timestamp=[DateTime]::UtcNow.ToString('yyyy-MM-ddTHH:mm:ssZ');$nonce=[Guid]::NewGuid().ToString('N');$canonical="POST`n$path`n$timestamp`n$nonce`n$digest";$hmac=[Security.Cryptography.HMACSHA256]::new($deviceSecret);try{$signature=[Convert]::ToBase64String($hmac.ComputeHash([Text.Encoding]::UTF8.GetBytes($canonical))).TrimEnd('=').Replace('+','-').Replace('/','_')}finally{$hmac.Dispose()};Invoke-WebRequest -UseBasicParsing -Method Post -Uri ($api+$path) -ContentType 'application/json' -Body $body -Headers @{'X-Device-Id'=$device;'X-Device-Timestamp'=$timestamp;'X-Device-Nonce'=$nonce;'X-Device-Content-SHA256'=$digest;'X-Device-Signature'=$signature;'Idempotency-Key'=$key}}
function Search([string]$field,[string]$value,[string]$token){((Invoke-WebRequest -UseBasicParsing -Uri "$api/api/v1/ops/diagnostics/search?field=$field&value=$([Uri]::EscapeDataString($value))" -Headers @{Authorization="Bearer $token";'X-Tenant-Id'=$tenant}).Content|ConvertFrom-Json).data.items}
function Action([string]$path,[string]$reason,[string]$key,[string]$token){Invoke-WebRequest -UseBasicParsing -Method Post -Uri ($api+$path) -Headers @{Authorization="Bearer $token";'X-Tenant-Id'=$tenant;'Idempotency-Key'=$key;'X-Request-Id'=$requestID} -ContentType 'application/json' -Body (@{reason=$reason}|ConvertTo-Json -Compress)}
try{
$owner=Token 'owner';$outsider=Token 'outsider'
try{Invoke-WebRequest -UseBasicParsing -Uri "$api/api/v1/ops/diagnostics/search?field=device_id&value=$device" -Headers @{Authorization="Bearer $outsider";'X-Tenant-Id'='20000000-0000-0000-0000-000000000010'}|Out-Null;throw '跨客户组织联调检索不应成功'}catch{if($null-eq$_.Exception.Response-or[int]$_.Exception.Response.StatusCode-ne403){throw}}
docker compose exec -T postgres psql -U voice -d voice_platform -v ON_ERROR_STOP=1 -c "INSERT INTO device(id,public_id,tenant_id,serial_digest,model,status,credential_ref) VALUES('$diagnosticDeviceInternal'::uuid,'$diagnosticDevice'::uuid,'10000000-0000-0000-0000-000000000001'::uuid,'$serialDigest','diagnostic-smoke','registered','local://diagnostic-smoke'); INSERT INTO device_twin(device_id,tenant_id,desired_revision) VALUES('$diagnosticDeviceInternal'::uuid,'10000000-0000-0000-0000-000000000001'::uuid,1); INSERT INTO outbox_event(id,tenant_id,aggregate_type,aggregate_id,event_type,payload,status,attempt_count,last_error_code,dead_at,payload_hash) VALUES('$diagnosticJobInternal'::uuid,'10000000-0000-0000-0000-000000000001'::uuid,'platform','$diagnosticJobAggregate'::uuid,'platform.noop','{}'::jsonb,'dead',8,'TEMPORARY_DEPENDENCY_FAILURE',now(),repeat('0',64));"|Out-Null
$jobPublic=(docker compose exec -T postgres psql -U voice -d voice_platform -t -A -c "SELECT public_id FROM outbox_event WHERE id='$diagnosticJobInternal'::uuid"|Out-String).Trim()
$jobs=((Invoke-WebRequest -UseBasicParsing -Uri "$api/api/v1/ops/diagnostics/jobs" -Headers @{Authorization="Bearer $owner";'X-Tenant-Id'=$tenant}).Content|ConvertFrom-Json).data.items
if(@($jobs|Where-Object{$_.id-eq$jobPublic-and$_.last_error_code-eq'TEMPORARY_DEPENDENCY_FAILURE'}).Count-ne1){throw '死信任务脱敏列表不正确'}
$retryKey='diagnostic-retry-'+[Guid]::NewGuid().ToString('N');$retry=(Action "/api/v1/ops/diagnostics/jobs/$jobPublic/retry" '依赖已恢复,执行一次受控人工重试' $retryKey $owner).Content|ConvertFrom-Json
if(-not $retry.data.queued-or$retry.data.manual_retry_count-ne1){throw '死信任务未按规则重置为待执行'}
$createBody=@{device_time=[DateTime]::UtcNow.ToString('o');monotonic_ms=24680;capabilities=@{rtc=$true;audio_tracks=@('near','far');upload_resume=$true};network=@{type='wifi'};requested_goal='open_conversation'}|ConvertTo-Json -Compress -Depth 8
$conversation=[string](((SignedPost '/device/v2/conversations' $createBody $createKey).Content|ConvertFrom-Json).data.conversation_id)
$refs=(docker compose exec -T postgres psql -U voice -d voice_platform -t -A -c "SELECT rt.room_id||'|'||rt.provider_task_ref FROM rtc_task rt JOIN conversation c ON c.id=rt.conversation_id WHERE c.public_id='$conversation'::uuid"|Out-String).Trim().Split('|');$room=$refs[0];$task=$refs[1]
foreach($pair in @(@('device_id',$device),@('conversation_id',$conversation),@('room_id',$room),@('provider_task_ref',$task))){$items=@(Search $pair[0] $pair[1] $owner);$matched=@($items|Where-Object{$_.device_id-eq$device-and$_.conversation_id-eq$conversation});if($matched.Count-ne1){throw "检索字段$($pair[0])结果不正确"}}
$reconcileKey='diagnostic-reconcile-'+[Guid]::NewGuid().ToString('N');$reconcile=(Action "/api/v1/ops/diagnostics/conversations/$conversation/reconcile" '确认房间已下发状态无需供应商对账' $reconcileKey $owner).Content|ConvertFrom-Json;if($reconcile.data.queued-ne$false){throw '稳定状态对账不应错误排队'}
$refreshKey='diagnostic-refresh-'+[Guid]::NewGuid().ToString('N');$refresh=Action "/api/v1/ops/diagnostics/devices/$device/config-refresh" '要求测试设备重新应用当前配置' $refreshKey $owner;$refreshData=($refresh.Content|ConvertFrom-Json).data;$refreshCommand=[string]$refreshData.command_id;if($refresh.StatusCode-ne201-or -not $refreshData.queued){throw '配置刷新命令未排队'}
$stopKey='diagnostic-stop-'+[Guid]::NewGuid().ToString('N');$stop=Action "/api/v1/ops/diagnostics/conversations/$conversation/stop" '联调完成,释放尚未启动的房间' $stopKey $owner;$stopData=($stop.Content|ConvertFrom-Json).data;if($stopData.conversation_status-ne'EXPIRED'-or$stopData.queued-ne$false){throw '未启动通话没有安全收敛'}
$byRequest=@(Search 'request_id' $requestID $owner);if($byRequest.Count-ne1-or$byRequest[0].conversation_id-ne$conversation){throw '请求关联编号无法回查通话'}
$bundleKey='diagnostic-bundle-'+[Guid]::NewGuid().ToString('N');$bundleResponse=Invoke-WebRequest -UseBasicParsing -Method Post -Uri "$api/api/v1/ops/diagnostics/bundles" -Headers @{Authorization="Bearer $owner";'X-Tenant-Id'=$tenant;'Idempotency-Key'=$bundleKey;'X-Request-Id'=$requestID} -ContentType 'application/json' -Body (@{field='conversation_id';value=$conversation;reason='导出脱敏联调证据'}|ConvertTo-Json -Compress);$bundleData=($bundleResponse.Content|ConvertFrom-Json).data
if($bundleResponse.StatusCode-ne201-or$bundleData.redaction_policy-ne'ops-diagnostic-minimal-v1'-or@($bundleData.items).Count-ne1){throw '脱敏诊断包生成不正确'}
if($bundleResponse.Content-match'(?i)transcript|audio_url|rtc_token|credential_ref|payload'){throw '诊断包包含禁止导出的敏感字段'}
$revokeKey='diagnostic-revoke-'+[Guid]::NewGuid().ToString('N');$revoke=(Action "/api/v1/ops/diagnostics/devices/$diagnosticDevice/revoke" '吊销仅用于烟测的合成设备' $revokeKey $owner).Content|ConvertFrom-Json
if($revoke.data.action-ne'revoke_device'-or$revoke.data.queued-ne$false){throw '合成设备未完成管理员吊销'}
$revokedState=(docker compose exec -T postgres psql -U voice -d voice_platform -t -A -c "SELECT status||'|'||(revoked_at IS NOT NULL)::text FROM device WHERE id='$diagnosticDeviceInternal'::uuid"|Out-String).Trim();if($revokedState-ne'revoked|true'){throw "设备吊销落库不正确:$revokedState"}
Write-Host '联调诊断烟测通过:五种精确检索、跨租户拒绝、安全停止、状态对账、配置刷新、死信重试、脱敏诊断包、设备吊销和审计关联均正确。'
}finally{
if($conversation-match'^[0-9a-fA-F-]{36}$'){docker compose exec -T postgres psql -U voice -d voice_platform -v ON_ERROR_STOP=1 -c "BEGIN; CREATE TEMP TABLE diag_conv AS SELECT id,context_snapshot_id,consent_snapshot_id FROM conversation WHERE public_id='$conversation'::uuid; DELETE FROM conversation_state_history WHERE conversation_id IN(SELECT id FROM diag_conv); DELETE FROM rtc_task WHERE conversation_id IN(SELECT id FROM diag_conv); DELETE FROM outbox_event WHERE aggregate_id IN(SELECT id FROM diag_conv); DELETE FROM audit_event WHERE request_id='$requestID' OR resource_id IN(SELECT id FROM diag_conv); DELETE FROM conversation WHERE id IN(SELECT id FROM diag_conv); DELETE FROM context_snapshot WHERE id IN(SELECT context_snapshot_id FROM diag_conv); DELETE FROM consent_snapshot WHERE id IN(SELECT consent_snapshot_id FROM diag_conv); COMMIT;"|Out-Null}
if($refreshCommand-match'^[0-9a-fA-F-]{36}$'){docker compose exec -T postgres psql -U voice -d voice_platform -v ON_ERROR_STOP=1 -c "DELETE FROM device_command WHERE public_id='$refreshCommand'::uuid;"|Out-Null}
docker compose exec -T postgres psql -U voice -d voice_platform -v ON_ERROR_STOP=1 -c "DELETE FROM outbox_event WHERE id='$diagnosticJobInternal'::uuid; DELETE FROM device_twin WHERE device_id='$diagnosticDeviceInternal'::uuid; DELETE FROM device WHERE id='$diagnosticDeviceInternal'::uuid;"|Out-Null
docker compose exec -T postgres psql -U voice -d voice_platform -v ON_ERROR_STOP=1 -c "DELETE FROM idempotency_record WHERE actor_key='ops:10000000-0000-0000-0000-000000000111' AND scope LIKE 'POST /api/v1/ops/diagnostics/%';"|Out-Null
docker compose exec -T postgres psql -U voice -d voice_platform -v ON_ERROR_STOP=1 -c "DELETE FROM idempotency_record WHERE actor_key='device:$device' AND idempotency_key='$createKey';"|Out-Null
Write-Host '已清理联调诊断合成通话、命令、审计和幂等记录。'
}