Files
group_xinghuo_jinrong/scripts/demo/run_demo_smoke.ps1
T

209 lines
9.0 KiB
PowerShell

#Requires -Version 5.1
<#
.SYNOPSIS
Run the backend functional-demo smoke flow.
.DESCRIPTION
This script exercises only existing demo APIs:
auth/RBAC, compliance/copy gate, market alert, KYC collection, and templates.
It uses development data and does not require Neo4j, Ollama, or DeepSeek.
#>
param(
[string]$BaseUrl = "http://127.0.0.1:8000"
)
$ErrorActionPreference = "Stop"
$BaseUrl = $BaseUrl.TrimEnd("/")
function Invoke-DemoJson {
param(
[string]$Method,
[string]$Path,
[hashtable]$Headers = @{},
[object]$Body = $null
)
$params = @{
Method = $Method
Uri = "$BaseUrl$Path"
Headers = $Headers
}
if ($null -ne $Body) {
$params.ContentType = "application/json"
$params.Body = $Body | ConvertTo-Json -Depth 10 -Compress
}
return Invoke-RestMethod @params
}
function New-TraceId {
param([string]$Name)
return "demo-$Name-$([guid]::NewGuid().ToString('N').Substring(0, 8))"
}
function Get-Sha256Hex {
param([string]$Text)
$bytes = [System.Text.Encoding]::UTF8.GetBytes($Text)
$hash = [System.Security.Cryptography.SHA256]::Create().ComputeHash($bytes)
return -join ($hash | ForEach-Object { $_.ToString("x2") })
}
function Assert-Equal {
param(
[object]$Actual,
[object]$Expected,
[string]$Message
)
if ($Actual -ne $Expected) {
throw "$Message. Expected '$Expected', got '$Actual'."
}
}
Write-Host "== JinRong Agent functional demo smoke =="
Write-Host "Base URL: $BaseUrl"
$health = Invoke-RestMethod "$BaseUrl/health"
Assert-Equal $health.status "ok" "Health check failed"
$login = Invoke-DemoJson -Method "POST" -Path "/api/v1/auth/login" -Body @{
username = "advisor_test"
password = "advisor_test"
}
Assert-Equal $login.code "00000" "Advisor login failed"
$advisorToken = $login.data.access_token
$advisorHeaders = @{ Authorization = "Bearer $advisorToken" }
$complianceLogin = Invoke-DemoJson -Method "POST" -Path "/api/v1/auth/login" -Body @{
username = "compliance_test"
password = "compliance_test"
}
Assert-Equal $complianceLogin.code "00000" "Compliance login failed"
$complianceHeaders = @{ Authorization = "Bearer $($complianceLogin.data.access_token)" }
Write-Host "[1/5] Compliance and copy gate"
$safeText = "请结合产品说明书、风险揭示和客户风险承受能力进行客观说明。"
$warnText = "该产品近期波动较大,错过再无机会。"
$blockText = "这款产品保证赚钱,绝对不会亏。"
$safeCheck = Invoke-DemoJson -Method "POST" -Path "/api/v1/compliance/check" `
-Headers @{ Authorization = "Bearer $advisorToken"; "X-Trace-Id" = (New-TraceId "compliance-safe") } `
-Body @{ text = $safeText; scene = "demo" }
$warnCheck = Invoke-DemoJson -Method "POST" -Path "/api/v1/compliance/check" `
-Headers @{ Authorization = "Bearer $advisorToken"; "X-Trace-Id" = (New-TraceId "compliance-warn") } `
-Body @{ text = $warnText; scene = "demo" }
$blockCheck = Invoke-DemoJson -Method "POST" -Path "/api/v1/compliance/check" `
-Headers @{ Authorization = "Bearer $advisorToken"; "X-Trace-Id" = (New-TraceId "compliance-block") } `
-Body @{ text = $blockText; scene = "demo" }
Assert-Equal $safeCheck.data.risk_level "INFO" "Safe text compliance result mismatch"
Assert-Equal $warnCheck.data.risk_level "WARN" "Warn text compliance result mismatch"
Assert-Equal $blockCheck.data.risk_level "BLOCK" "Block text compliance result mismatch"
$copy = Invoke-DemoJson -Method "POST" -Path "/api/v1/copy/track" `
-Headers @{ Authorization = "Bearer $advisorToken"; "X-Trace-Id" = (New-TraceId "copy-info") } `
-Body @{
content_type = "text"
content_summary = $safeText.Substring(0, 20)
content_hash = Get-Sha256Hex $safeText
source_type = "demo"
source_id = "safe"
compliance_check_id = $safeCheck.data.check_id
compliance_risk_level = "INFO"
}
Assert-Equal $copy.code "00000" "INFO copy gate failed"
$warnCopy = Invoke-DemoJson -Method "POST" -Path "/api/v1/copy/track" `
-Headers @{ Authorization = "Bearer $advisorToken"; "X-Trace-Id" = (New-TraceId "copy-warn") } `
-Body @{
content_type = "text"
content_summary = $warnText.Substring(0, 15)
content_hash = Get-Sha256Hex $warnText
source_type = "demo"
source_id = "warn"
compliance_check_id = $warnCheck.data.check_id
compliance_risk_level = "WARN"
warn_confirmed = $true
}
Assert-Equal $warnCopy.code "00000" "Confirmed WARN copy gate failed"
Write-Host "[2/5] Market data, alert, generation, feedback"
$quote = Invoke-DemoJson -Method "GET" -Path "/api/v1/market/fund/000001" -Headers $advisorHeaders
Assert-Equal $quote.data.data_source "jinrong_core" "Core market data source mismatch"
$scan = Invoke-DemoJson -Method "POST" -Path "/api/v1/market-alerts/scan" `
-Headers @{ Authorization = "Bearer $advisorToken"; "X-Trace-Id" = (New-TraceId "market-scan") } `
-Body @{ nav_date = "2026-09-04"; threshold_pct = 1.0 }
$alert = $scan.data.items | Where-Object { $_.fund_code -eq "161725" } | Select-Object -First 1
if ($null -eq $alert) {
$alerts = Invoke-DemoJson -Method "GET" -Path "/api/v1/market-alerts?date=2026-09-04" -Headers $advisorHeaders
$alert = $alerts.data.items | Where-Object { $_.fund_code -eq "161725" } | Select-Object -First 1
}
if ($null -eq $alert) {
throw "No demo market alert found for fund 161725."
}
$generated = Invoke-DemoJson -Method "POST" -Path "/api/v1/market-alerts/generate" `
-Headers @{ Authorization = "Bearer $advisorToken"; "X-Trace-Id" = (New-TraceId "market-generate") } `
-Body @{ fund_code = $alert.fund_code }
foreach ($section in @("【异动概述】", "【原因分析】", "【当前建议】", "【风险提示】")) {
if ($generated.data.generated_text -notlike "*$section*") {
throw "Generated market text is missing section: $section"
}
}
$feedback = Invoke-DemoJson -Method "PUT" -Path "/api/v1/market-alerts/$($generated.data.alert_id)/feedback" `
-Headers @{ Authorization = "Bearer $advisorToken"; "X-Trace-Id" = (New-TraceId "market-feedback") } `
-Body @{ action = "adopt" }
Assert-Equal $feedback.data.copied $true "Market alert adopt feedback did not copy"
Write-Host "[3/5] KYC collection"
$kyc = Invoke-DemoJson -Method "POST" -Path "/api/v1/kyc/sessions" `
-Headers @{ Authorization = "Bearer $advisorToken"; "X-Trace-Id" = (New-TraceId "kyc-create") } `
-Body @{
customer_id = "CUST-1001"
session_type = "new_customer"
customer_display_name = "客户·王**"
}
$sessionId = $kyc.data.session_id
$chat = Invoke-DemoJson -Method "POST" -Path "/api/v1/kyc/sessions/$sessionId/chat" `
-Headers @{ Authorization = "Bearer $advisorToken"; "X-Trace-Id" = (New-TraceId "kyc-chat") } `
-Body @{ customer_input = "客户今年28岁,女性,未婚,处于事业起步阶段" }
if ($chat.data.progress_pct -le 0) {
throw "KYC progress did not advance."
}
$back = Invoke-DemoJson -Method "POST" -Path "/api/v1/kyc/sessions/$sessionId/chat" `
-Headers @{ Authorization = "Bearer $advisorToken"; "X-Trace-Id" = (New-TraceId "kyc-back") } `
-Body @{ customer_input = "客户今年30岁"; skip_to = "basic_info" }
Assert-Equal $back.data.current_node "basic_info" "KYC retrograde node mismatch"
$completed = Invoke-DemoJson -Method "POST" -Path "/api/v1/kyc/sessions/$sessionId/complete" `
-Headers @{ Authorization = "Bearer $advisorToken"; "X-Trace-Id" = (New-TraceId "kyc-complete") }
Assert-Equal $completed.data.status "completed" "KYC completion status mismatch"
Write-Host "[4/5] Template approval, search, and use"
$seedTemplates = Invoke-DemoJson -Method "GET" -Path "/api/v1/templates?keyword=DEV-TOP&page_size=100" `
-Headers $complianceHeaders
$template = $seedTemplates.data.items | Where-Object { $_.created_by -eq "seed:template_test_data" } | Select-Object -First 1
if ($null -eq $template) {
throw "No DEV-TOP demo template found."
}
if (-not $template.is_approved) {
$approved = Invoke-DemoJson -Method "PUT" -Path "/api/v1/templates/$($template.id)" `
-Headers $complianceHeaders -Body @{ is_approved = $true }
Assert-Equal $approved.data.is_approved $true "Template approval failed"
}
$search = Invoke-DemoJson -Method "GET" `
-Path "/api/v1/templates/search?q=$([uri]::EscapeDataString($template.title))" `
-Headers $advisorHeaders
if ($search.data.items.Count -lt 1) {
throw "Approved demo template was not searchable."
}
$use = Invoke-DemoJson -Method "POST" -Path "/api/v1/templates/$($template.id)/use" `
-Headers @{ Authorization = "Bearer $advisorToken"; "X-Trace-Id" = (New-TraceId "template-use") } `
-Body @{
is_modified = $true
modified_content = "$($template.content) 请结合风险揭示文件自主决定。"
}
Assert-Equal $use.data.template_id $template.id "Template use returned wrong template"
Write-Host "[5/5] Demo smoke passed"
Write-Host "KYC session: $sessionId"
Write-Host "Market alert: $($generated.data.alert_id)"
Write-Host "Template use: $($use.data.use_id)"