param( [switch]$Start, # неинтерактивно: запустить и выйти [switch]$Stop # неинтерактивно: остановить и выйти ) # LearnSpace — панель управления сервером (консоль-меню). # Запуск: двойной клик по control-panel.bat. Сервер работает в фоне и переживает # закрытие панели. Живые логи открываются в отдельном окне. $ErrorActionPreference = 'Continue' try { chcp 65001 > $null } catch {} try { [Console]::OutputEncoding = [System.Text.UTF8Encoding]::new() } catch {} $root = Split-Path -Parent $PSScriptRoot $backend = Join-Path $root 'backend' $log = Join-Path $env:TEMP 'learnspace-server.log' $errlog = Join-Path $env:TEMP 'learnspace-server.err.log' Set-Location $backend function Get-Port { try { $p = & node -e 'try{process.stdout.write(String(require("./src/config").PORT||3000))}catch(e){process.stdout.write("3000")}' 2>$null if ("$p" -match '^\d+$') { return [int]"$p" } } catch {} return 3000 } $script:Port = Get-Port function Server-Proc { try { $c = Get-NetTCPConnection -LocalPort $script:Port -State Listen -ErrorAction Stop | Select-Object -First 1 if ($c) { return Get-Process -Id $c.OwningProcess -ErrorAction SilentlyContinue } } catch {} return $null } function Status-Line { $p = Server-Proc if ($p) { $ups = '?' try { $u = (Get-Date) - $p.StartTime; $ups = ('{0}ч {1}м' -f [int]$u.TotalHours, $u.Minutes) } catch {} return ('РАБОТАЕТ — PID ' + $p.Id + ', порт ' + $script:Port + ', аптайм ' + $ups) } return 'остановлен' } function Start-Server { if (Server-Proc) { Write-Host ' Сервер уже работает.' -ForegroundColor Yellow; return } Write-Host ' Применяю миграции (идемпотентно)...' -ForegroundColor DarkGray try { & node src/db/migrations-runner.js | Out-Host } catch { Write-Host (' Миграции: ' + $_.Exception.Message) -ForegroundColor Red } Remove-Item $log, $errlog -ErrorAction SilentlyContinue Start-Process -FilePath node -ArgumentList 'src/server.js' -WorkingDirectory $backend -WindowStyle Hidden -RedirectStandardOutput $log -RedirectStandardError $errlog | Out-Null for ($i = 0; $i -lt 14; $i++) { Start-Sleep -Milliseconds 600; if (Server-Proc) { break } } if (Server-Proc) { Write-Host (' Сервер запущен на http://localhost:' + $script:Port) -ForegroundColor Green } else { Write-Host ' Не удалось запустить. Последние строки ошибок:' -ForegroundColor Red if (Test-Path $errlog) { Get-Content $errlog -Tail 14 -ErrorAction SilentlyContinue } } } function Stop-Server { $p = Server-Proc if (-not $p) { Write-Host ' Сервер не запущен.' -ForegroundColor Yellow; return } Stop-Process -Id $p.Id -Force -ErrorAction SilentlyContinue Start-Sleep -Milliseconds 500 Write-Host (' Сервер остановлен (PID ' + $p.Id + ').') -ForegroundColor Green } function Open-Logs { if (-not (Test-Path $log)) { Write-Host ' Логов нет: сервер не запускался через панель. Запустите его пунктом [1] или [3].' -ForegroundColor Yellow return } $cmd = "`$Host.UI.RawUI.WindowTitle='LearnSpace — живые логи'; Write-Host 'Живые логи сервера (закройте окно, чтобы прекратить просмотр):' -ForegroundColor Cyan; Get-Content -Path '$log' -Wait -Tail 50" Start-Process powershell -ArgumentList '-NoProfile', '-NoExit', '-Command', $cmd Write-Host ' Логи открыты в отдельном окне.' -ForegroundColor Green } function Run-Cmd($title, $block) { Write-Host '' Write-Host (' >>> ' + $title) -ForegroundColor Cyan Write-Host '' & $block Write-Host '' [void](Read-Host ' [Enter] вернуться в меню') } # ── Неинтерактивные режимы (для start/stop-server.bat) ── if ($Stop) { Stop-Server; Start-Sleep -Milliseconds 800; exit } if ($Start) { Start-Server; Start-Sleep -Milliseconds 800; exit } # ── Меню ── $run = $true while ($run) { Clear-Host $bar = ' ' + ('=' * 56) Write-Host '' Write-Host $bar -ForegroundColor DarkCyan Write-Host ' LearnSpace — Панель управления' -ForegroundColor Cyan Write-Host $bar -ForegroundColor DarkCyan $st = Status-Line if ($st -like 'РАБОТАЕТ*') { Write-Host (' Статус: ' + $st) -ForegroundColor Green } else { Write-Host (' Статус: ' + $st) -ForegroundColor Yellow } Write-Host (' URL: http://localhost:' + $script:Port) -ForegroundColor DarkGray Write-Host (' Папка: ' + $backend) -ForegroundColor DarkGray Write-Host $bar -ForegroundColor DarkCyan Write-Host '' Write-Host ' [1] Запустить сервер [5] Применить миграции' Write-Host ' [2] Остановить сервер [6] Тесты (npm test)' Write-Host ' [3] Перезапустить [7] Проверка роутов (lint)' Write-Host ' [4] Живые логи (окно) [8] Открыть сайт в браузере' Write-Host '' Write-Host ' [9] Обновить статус [0] Выход' Write-Host '' $c = Read-Host ' Выбор' switch ($c.Trim()) { '1' { Start-Server; Start-Sleep 1 } '2' { Stop-Server; Start-Sleep 1 } '3' { Stop-Server; Start-Sleep -Milliseconds 800; Start-Server; Start-Sleep 1 } '4' { Open-Logs; Start-Sleep 1 } '5' { Run-Cmd 'Применение миграций' { & node src/db/migrations-runner.js | Out-Host } } '6' { Run-Cmd 'Тесты (npm test)' { & npm test } } '7' { Run-Cmd 'Проверка авторизации роутов' { & npm run lint:routes } } '8' { Start-Process ('http://localhost:' + $script:Port) } '9' { } '0' { $run = $false } default { } } } Write-Host '' Write-Host ' Панель закрыта. Сервер, если запущен, продолжает работать в фоне.' -ForegroundColor Cyan Write-Host ' Остановить позже: stop-server.bat или пункт [2] панели.' -ForegroundColor DarkGray