<# .SYNOPSIS Stops the Likwid development environment. .DESCRIPTION Gracefully stops backend, frontend, and PostgreSQL container. #> [CmdletBinding()] param() $ErrorActionPreference = 'Continue' $root = Split-Path -Parent $PSScriptRoot $stateDir = Join-Path $PSScriptRoot '.dev' $stateFile = Join-Path $stateDir 'state.json' function Stop-ProcessSafely([int]$ProcessId, [string]$Name) { if (-not $ProcessId) { return $false } $proc = Get-Process -Id $ProcessId -ErrorAction SilentlyContinue if (-not $proc) { return $false } Write-Host "Stopping $Name (PID $ProcessId)..." Stop-Process -Id $ProcessId -ErrorAction SilentlyContinue Start-Sleep -Milliseconds 500 # Force kill if still running $proc = Get-Process -Id $ProcessId -ErrorAction SilentlyContinue if ($proc) { Stop-Process -Id $ProcessId -Force -ErrorAction SilentlyContinue } return $true } function Stop-ProcessOnPort([int]$Port) { $connections = netstat -ano 2>$null | Select-String ":$Port.*LISTENING" foreach ($conn in $connections) { $parts = ($conn.Line -replace '\s+', ' ').Trim().Split(' ') $procId = [int]$parts[-1] if ($procId -gt 0) { Stop-ProcessSafely -ProcessId $procId -Name "process on port $Port" | Out-Null } } } Write-Host "=== Stopping Likwid Dev Environment ===" # Stop from saved state if (Test-Path $stateFile) { $state = Get-Content -Raw $stateFile | ConvertFrom-Json -ErrorAction SilentlyContinue if ($state) { Stop-ProcessSafely -ProcessId $state.frontendPid -Name 'Frontend' | Out-Null Stop-ProcessSafely -ProcessId $state.backendPid -Name 'Backend' | Out-Null } } # Cleanup any orphaned processes on the ports Stop-ProcessOnPort -Port 4321 Stop-ProcessOnPort -Port 3000 # Stop PostgreSQL container Write-Host "Stopping PostgreSQL container..." $composeFile = Join-Path $root 'compose/dev.yml' podman-compose -f $composeFile down 2>$null # Clean up state file if (Test-Path $stateFile) { Remove-Item -Force $stateFile } Write-Host "" Write-Host "All services stopped."