<# .SYNOPSIS Starts the Likwid development environment. .DESCRIPTION Starts PostgreSQL (via Podman), backend (Rust/Axum), and frontend (Astro). Use dev-stop.ps1 to stop all services. #> [CmdletBinding()] param() $ErrorActionPreference = 'Stop' # Paths $root = Split-Path -Parent $PSScriptRoot $stateDir = Join-Path $PSScriptRoot '.dev' $stateFile = Join-Path $stateDir 'state.json' $backendLog = Join-Path $stateDir 'backend.log' $frontendLog = Join-Path $stateDir 'frontend.log' New-Item -ItemType Directory -Force -Path $stateDir | Out-Null # Environment if (-not $env:POSTGRES_USER) { $env:POSTGRES_USER = 'likwid' } if (-not $env:POSTGRES_PASSWORD) { $env:POSTGRES_PASSWORD = 'likwid' } if (-not $env:POSTGRES_DB) { $env:POSTGRES_DB = 'likwid' } $env:DATABASE_URL = "postgres://$($env:POSTGRES_USER):$($env:POSTGRES_PASSWORD)@127.0.0.1:5432/$($env:POSTGRES_DB)" # Check if already running if (Test-Path $stateFile) { $state = Get-Content -Raw $stateFile | ConvertFrom-Json -ErrorAction SilentlyContinue if ($state -and $state.backendPid) { $p = Get-Process -Id $state.backendPid -ErrorAction SilentlyContinue if ($p) { Write-Host "Already running (backend PID $($state.backendPid)). Run dev-stop.ps1 first." exit 0 } } } # Start Podman machine if needed try { $machines = podman machine list --format json 2>$null | ConvertFrom-Json $running = $machines | Where-Object { $_.Running -eq $true } if (-not $running) { Write-Host "Starting Podman machine..." podman machine start ($machines | Select-Object -First 1).Name 2>$null } } catch { Write-Host "Podman machine check failed (may already be running)" } # Start PostgreSQL container Write-Host "Starting PostgreSQL..." $composeFile = Join-Path $root 'compose/dev.yml' $composeExitCode = 0 try { podman-compose -f $composeFile up -d 2>$null $composeExitCode = $LASTEXITCODE } catch { $composeExitCode = $LASTEXITCODE } if ($composeExitCode -ne 0) { $containerExistsExitCode = 0 try { podman container exists likwid-postgres 2>$null $containerExistsExitCode = $LASTEXITCODE } catch { $containerExistsExitCode = $LASTEXITCODE } if ($containerExistsExitCode -ne 0) { throw "Failed to start PostgreSQL via podman-compose (exit code: $composeExitCode)." } Write-Host "Warning: podman-compose returned exit code $composeExitCode, but likwid-postgres exists. Continuing." } # Wait for PostgreSQL to be ready $maxWait = 30 for ($i = 0; $i -lt $maxWait; $i++) { $pg = netstat -ano 2>$null | Select-String ':5432.*LISTENING' if ($pg) { break } Start-Sleep -Seconds 1 } Write-Host "Running database migrations..." Push-Location (Join-Path $root 'backend') try { sqlx migrate run --ignore-missing if ($LASTEXITCODE -ne 0) { throw "Failed to run database migrations (sqlx migrate run)." } } finally { Pop-Location } # Start backend Write-Host "Starting backend..." $backend = Start-Process -FilePath 'cmd.exe' ` -ArgumentList '/c', 'cargo', 'run', '2>&1' ` -WorkingDirectory (Join-Path $root 'backend') ` -PassThru -WindowStyle Hidden ` -RedirectStandardOutput $backendLog # Start frontend Write-Host "Starting frontend..." $frontend = Start-Process -FilePath 'cmd.exe' ` -ArgumentList '/c', "set PUBLIC_API_BASE=http://127.0.0.1:3000&& npm run dev", '2>&1' ` -WorkingDirectory (Join-Path $root 'frontend') ` -PassThru -WindowStyle Hidden ` -RedirectStandardOutput $frontendLog # Save state @{ backendPid = $backend.Id frontendPid = $frontend.Id startedAt = (Get-Date).ToString('o') } | ConvertTo-Json | Set-Content -Encoding UTF8 $stateFile # Brief wait for startup Start-Sleep -Seconds 3 # Status report Write-Host "" Write-Host "=== Likwid Dev Environment ===" if (-not $backend.HasExited) { Write-Host "Backend: Running (PID $($backend.Id)) - http://127.0.0.1:3000" } else { Write-Host "Backend: FAILED - check $backendLog" } if (-not $frontend.HasExited) { Write-Host "Frontend: Running (PID $($frontend.Id)) - http://localhost:4321" } else { Write-Host "Frontend: FAILED - check $frontendLog" } Write-Host "PostgreSQL: Running on port 5432" Write-Host "" Write-Host "Logs: $stateDir" Write-Host "Stop: .\scripts\dev-stop.ps1"