Spaces:
Sleeping
Sleeping
| $ErrorActionPreference = "Stop" | |
| function Test-PortFree { | |
| param([int]$Port) | |
| # Use netstat because it reliably shows listeners from Session 0 services too. | |
| $pattern = ":$Port\\s" | |
| $hit = netstat -ano -p tcp | Select-String -Pattern "LISTENING" | Select-String -Pattern $pattern | |
| return (-not $hit) | |
| } | |
| function Test-ApApi { | |
| param([int]$Port) | |
| try { | |
| $res = Invoke-WebRequest -UseBasicParsing -TimeoutSec 1 -Uri "http://127.0.0.1:$Port/api/health" | |
| if ($res.StatusCode -ne 200) { return $false } | |
| # Only reuse the correct backend. Old/other uvicorn apps may also return {"ok":true}. | |
| # Our backend1 includes service/build fields. | |
| return (($res.Content -match '"service"\s*:\s*"backend1"') -and ($res.Content -match '"build"\s*:\s*"backend1-')) | |
| } catch { | |
| return $false | |
| } | |
| } | |
| function Ensure-Venv { | |
| if (-not (Test-Path ".venv\\Scripts\\python.exe")) { | |
| Write-Host "Creating venv at .venv ..." | |
| python -m venv .venv | |
| } | |
| } | |
| $projectRoot = Split-Path -Parent $MyInvocation.MyCommand.Path | |
| Set-Location $projectRoot | |
| Ensure-Venv | |
| Write-Host "Installing Python deps..." | |
| & ".\\.venv\\Scripts\\python.exe" -m pip install -r requirements.txt | Out-Host | |
| $candidatePorts = @(8000, 8010, 8020, 8030, 8040) | |
| $port = $null | |
| $startBackend = $true | |
| # Prefer reusing an already-running AP backend if found. | |
| foreach ($p in $candidatePorts) { | |
| if (Test-ApApi -Port $p) { $port = $p; $startBackend = $false; break } | |
| } | |
| foreach ($p in $candidatePorts) { | |
| if ($port) { break } | |
| if (Test-PortFree -Port $p) { $port = $p; break } | |
| } | |
| if (-not $port) { | |
| throw "No free port found. Tried: $($candidatePorts -join ', ')" | |
| } | |
| $apiBase = "http://127.0.0.1:$port" | |
| Write-Host "" | |
| if ($startBackend) { | |
| Write-Host "Starting backend on $apiBase ..." | |
| Start-Process powershell -WorkingDirectory $projectRoot -ArgumentList @( | |
| "-NoProfile", | |
| "-ExecutionPolicy", "Bypass", | |
| "-Command", | |
| "& '.\\.venv\\Scripts\\python.exe' -m uvicorn backend1.main:app --reload --host 127.0.0.1 --port $port" | |
| ) | Out-Null | |
| } else { | |
| Write-Host "Backend already running on $apiBase (reusing it)" | |
| } | |
| if (Test-PortFree -Port 5173) { | |
| Write-Host "Starting frontend dev server (Vite) on http://localhost:5173 ..." | |
| Start-Process powershell -WorkingDirectory (Join-Path $projectRoot "frontend") -ArgumentList @( | |
| "-NoProfile", | |
| "-ExecutionPolicy", "Bypass", | |
| "-Command", | |
| "`$env:VITE_API_PROXY_TARGET='$apiBase'; npm run dev" | |
| ) | Out-Null | |
| } else { | |
| Write-Host "Frontend dev server already running on http://localhost:5173 (not starting another)" | |
| } | |
| Write-Host "" | |
| Write-Host "Open:" | |
| Write-Host " Frontend UI: http://localhost:5173" | |
| Write-Host " Backend UI: $apiBase" | |
| Write-Host " API health: $apiBase/api/health" | |
| Write-Host "" | |
| Write-Host "If port 8000 is in use, this script automatically uses 8010/8020/etc." | |