$ProgressPreference = "SilentlyContinue" $ErrorActionPreference = "Stop" Write-Host "=== 1. Get captcha and parse code ===" -ForegroundColor Cyan $captchaResp = Invoke-RestMethod -Uri "http://localhost:5000/api/auth/captcha" -Method Get $captchaId = $captchaResp.data.captchaId $svg = $captchaResp.data.svg Write-Host "CaptchaId: $captchaId" $matches = [regex]::Matches($svg, ']*>([^<])') $code = -join ($matches | ForEach-Object { $_.Groups[1].Value }) Write-Host "Parsed code: $code" Write-Host "" Write-Host "=== 2. Login admin ===" -ForegroundColor Cyan $loginBody = @{ username = "admin"; password = "admin123"; captchaId = $captchaId; captchaCode = $code } | ConvertTo-Json $loginResp = Invoke-RestMethod -Uri "http://localhost:5000/api/auth/login" -Method Post -ContentType "application/json" -Body $loginBody $token = $loginResp.data.token if (-not $token) { Write-Host "[FAIL] Login failed: $($loginResp | ConvertTo-Json -Depth 3)" -ForegroundColor Red; exit 1 } Write-Host "Token: $($token.Substring(0,30))..." $headers = @{ Authorization = "Bearer $token" } Write-Host "" Write-Host "=== 3. Get project list ===" -ForegroundColor Cyan $projResp = Invoke-RestMethod -Uri "http://localhost:5000/api/projects?pageIndex=1&pageSize=10" -Headers $headers -Method Get $projects = $projResp.data.items Write-Host "Project count: $($projects.Count)" if ($projects.Count -eq 0) { Write-Host "[FAIL] No projects to test" -ForegroundColor Red; exit 1 } $projects | Select-Object id, name, status, platforms | Format-Table -AutoSize $firstProj = $projects[0] Write-Host "" Write-Host "=== 4. Get project detail (id=$($firstProj.id)) ===" -ForegroundColor Cyan $detailResp = Invoke-RestMethod -Uri "http://localhost:5000/api/projects/$($firstProj.id)" -Headers $headers -Method Get $detail = $detailResp.data Write-Host "name: $($detail.name)" Write-Host "categoryId: $($detail.categoryId)" Write-Host "coverImage: $($detail.coverImage)" Write-Host "videoUrl: $($detail.videoUrl)" Write-Host "platforms: $($detail.platforms)" Write-Host "status: $($detail.status)" Write-Host "tags: $($detail.tags -join ', ')" Write-Host "" Write-Host "=== 5. PUT /api/projects/$($firstProj.id) to reproduce save ===" -ForegroundColor Cyan $payload = @{ name = $detail.name categoryId = $detail.categoryId coverImage = $detail.coverImage videoUrl = $detail.videoUrl description = $detail.description content = $detail.content platforms = $detail.platforms status = $detail.status tagIds = @() packages = @() } | ConvertTo-Json -Depth 5 Write-Host "Payload: $payload" Write-Host "" try { $updateResp = Invoke-RestMethod -Uri "http://localhost:5000/api/projects/$($firstProj.id)" -Headers $headers -Method Put -ContentType "application/json" -Body $payload Write-Host "[OK] Save succeeded" -ForegroundColor Green Write-Host "Response: $($updateResp | ConvertTo-Json -Depth 3)" } catch { Write-Host "[FAIL] Save failed" -ForegroundColor Red Write-Host "StatusCode: $($_.Exception.Response.StatusCode.value__)" Write-Host "StatusDescription: $($_.Exception.Response.StatusDescription)" try { $reader = New-Object System.IO.StreamReader($_.Exception.Response.GetResponseStream()) $errBody = $reader.ReadToEnd() Write-Host "Error Body: $errBody" } catch { Write-Host "(cannot read response body)" } }