$ErrorActionPreference = "Stop" $repoRoot = Resolve-Path "$PSScriptRoot\.." Set-Location $repoRoot function Assert-LastExitCode { param([Parameter(Mandatory = $true)][string]$CommandName) if ($LASTEXITCODE -ne 0) { throw "$CommandName failed with exit code $LASTEXITCODE." } } function Get-PythonCommand { $venvPython = Join-Path $repoRoot ".venv\Scripts\python.exe" if (Test-Path $venvPython) { return $venvPython } return "python" } function Ensure-PythonModule { param( [Parameter(Mandatory = $true)][string]$PythonExe, [Parameter(Mandatory = $true)][string]$ModuleName, [Parameter(Mandatory = $true)][string]$PackageName ) & $PythonExe -c "import importlib.util, sys; sys.exit(0 if importlib.util.find_spec('$ModuleName') else 1)" if ($LASTEXITCODE -eq 0) { return } Write-Host "Installing missing Python package: $PackageName" & $PythonExe -m pip install $PackageName Assert-LastExitCode -CommandName "python -m pip install $PackageName" } $pythonExe = Get-PythonCommand Write-Host "Installing backend Python requirements" & $pythonExe -m pip install -r (Join-Path $repoRoot "backend\requirements.txt") Assert-LastExitCode -CommandName "python -m pip install -r backend/requirements.txt" Write-Host "Running Python dependency integrity check" & $pythonExe -m pip check Assert-LastExitCode -CommandName "python -m pip check" Ensure-PythonModule -PythonExe $pythonExe -ModuleName "pip_audit" -PackageName "pip-audit" Write-Host "Running Python vulnerability scan" & $pythonExe -m pip_audit -r (Join-Path $repoRoot "backend\requirements.txt") --progress-spinner off --desc Assert-LastExitCode -CommandName "python -m pip_audit" Write-Host "Running backend unit tests" & $pythonExe -m unittest discover -s backend/tests -p "test_*.py" -v Assert-LastExitCode -CommandName "python -m unittest discover" Write-Host "Backend quality gate passed"