Initial commit - Church Music Database
This commit is contained in:
34
legacy-site/scripts/batch/configure-firewall.bat
Normal file
34
legacy-site/scripts/batch/configure-firewall.bat
Normal file
@@ -0,0 +1,34 @@
|
||||
@echo off
|
||||
REM Configure Windows Firewall for No-IP External Access
|
||||
REM Run this script as Administrator
|
||||
|
||||
echo ========================================
|
||||
echo CHURCH APP FIREWALL CONFIGURATION
|
||||
echo ========================================
|
||||
echo.
|
||||
|
||||
echo Creating firewall rule for Frontend (Port 3000)...
|
||||
netsh advfirewall firewall add rule name="Church App Frontend" dir=in action=allow protocol=TCP localport=3000 profile=any
|
||||
if %errorlevel% equ 0 (
|
||||
echo [OK] Frontend rule created
|
||||
) else (
|
||||
echo [ERROR] Failed to create frontend rule
|
||||
)
|
||||
|
||||
echo.
|
||||
echo Creating firewall rule for Backend (Port 5000)...
|
||||
netsh advfirewall firewall add rule name="Church App Backend" dir=in action=allow protocol=TCP localport=5000 profile=any
|
||||
if %errorlevel% equ 0 (
|
||||
echo [OK] Backend rule created
|
||||
) else (
|
||||
echo [ERROR] Failed to create backend rule
|
||||
)
|
||||
|
||||
echo.
|
||||
echo ========================================
|
||||
echo FIREWALL RULES CONFIGURED
|
||||
echo ========================================
|
||||
echo.
|
||||
echo To verify, run: netsh advfirewall firewall show rule name=all
|
||||
echo.
|
||||
pause
|
||||
22
legacy-site/scripts/batch/restart-all-services.bat
Normal file
22
legacy-site/scripts/batch/restart-all-services.bat
Normal file
@@ -0,0 +1,22 @@
|
||||
@echo off
|
||||
REM ========================================
|
||||
REM Church SongLyric - Quick Restart
|
||||
REM ========================================
|
||||
|
||||
title Restart All Services
|
||||
color 0E
|
||||
|
||||
echo.
|
||||
echo ========================================
|
||||
echo RESTARTING ALL SERVICES
|
||||
echo ========================================
|
||||
echo.
|
||||
|
||||
echo Stopping services...
|
||||
call stop-all-services.bat
|
||||
|
||||
timeout /t 3 /nobreak >nul
|
||||
|
||||
echo.
|
||||
echo Starting services...
|
||||
call start-all-services.bat
|
||||
81
legacy-site/scripts/batch/start-all-services.bat
Normal file
81
legacy-site/scripts/batch/start-all-services.bat
Normal file
@@ -0,0 +1,81 @@
|
||||
@echo off
|
||||
REM ========================================
|
||||
REM Church SongLyric - All Services Launcher
|
||||
REM ========================================
|
||||
REM This script starts MongoDB, Backend, and Frontend in hidden windows
|
||||
|
||||
title Church SongLyric - Service Launcher
|
||||
color 0A
|
||||
|
||||
echo.
|
||||
echo ========================================
|
||||
echo CHURCH SONGLYRIC SERVICE LAUNCHER
|
||||
echo ========================================
|
||||
echo.
|
||||
|
||||
REM Check if MongoDB is running
|
||||
echo [1/4] Checking MongoDB...
|
||||
tasklist /FI "IMAGENAME eq mongod.exe" 2>NUL | find /I /N "mongod.exe">NUL
|
||||
if "%ERRORLEVEL%"=="0" (
|
||||
echo MongoDB is already running
|
||||
) else (
|
||||
echo Starting MongoDB...
|
||||
start "" "C:\Program Files\MongoDB\Server\8.0\bin\mongod.exe" --dbpath "C:\data\db"
|
||||
timeout /t 3 /nobreak >nul
|
||||
echo MongoDB started
|
||||
)
|
||||
|
||||
echo.
|
||||
echo [2/4] Starting Backend Server (Flask)...
|
||||
cd /d "%~dp0backend"
|
||||
start "Church Backend" /MIN cmd /c "venv\Scripts\python.exe app.py"
|
||||
timeout /t 3 /nobreak >nul
|
||||
echo Backend starting on port 5000...
|
||||
|
||||
echo.
|
||||
echo [3/4] Starting Frontend Server (React)...
|
||||
cd /d "%~dp0frontend"
|
||||
start "Church Frontend" /MIN cmd /c "npm start"
|
||||
timeout /t 5 /nobreak >nul
|
||||
echo Frontend starting on port 3000...
|
||||
|
||||
echo.
|
||||
echo [4/4] Verifying services...
|
||||
timeout /t 5 /nobreak >nul
|
||||
|
||||
REM Test backend
|
||||
powershell -Command "try { $r = Invoke-RestMethod -Uri 'http://localhost:5000/api/health' -TimeoutSec 5; Write-Host ' Backend: ONLINE - Status:' $r.status -ForegroundColor Green } catch { Write-Host ' Backend: Starting... (wait 10 seconds)' -ForegroundColor Yellow }"
|
||||
|
||||
REM Test frontend
|
||||
powershell -Command "try { $r = Invoke-WebRequest -Uri 'http://localhost:3000' -TimeoutSec 5 -UseBasicParsing; Write-Host ' Frontend: ONLINE' -ForegroundColor Green } catch { Write-Host ' Frontend: Starting... (wait 10 seconds)' -ForegroundColor Yellow }"
|
||||
|
||||
echo.
|
||||
echo ========================================
|
||||
echo ALL SERVICES STARTED!
|
||||
echo ========================================
|
||||
echo.
|
||||
echo Access URLs:
|
||||
echo Local: http://localhost:3000
|
||||
echo LAN: http://192.168.10.178:3000
|
||||
echo External: http://houseofprayer.ddns.net:3000
|
||||
echo.
|
||||
echo Backend API:
|
||||
echo Local: http://localhost:5000
|
||||
echo External: http://houseofprayer.ddns.net:8080
|
||||
echo.
|
||||
echo Services running in background (minimized windows)
|
||||
echo Close those windows to stop the servers
|
||||
echo.
|
||||
echo Press any key to open the app in browser...
|
||||
pause >nul
|
||||
|
||||
start http://localhost:3000
|
||||
|
||||
echo.
|
||||
echo ========================================
|
||||
echo App opened in browser!
|
||||
echo ========================================
|
||||
echo.
|
||||
echo To stop all services, run: stop-all-services.bat
|
||||
echo.
|
||||
pause
|
||||
33
legacy-site/scripts/batch/start-all.bat
Normal file
33
legacy-site/scripts/batch/start-all.bat
Normal file
@@ -0,0 +1,33 @@
|
||||
@echo off
|
||||
REM Start Both Backend and Frontend Servers
|
||||
REM This script launches both servers in separate windows
|
||||
|
||||
echo ========================================
|
||||
echo CHURCH APP - STARTING ALL SERVERS
|
||||
echo ========================================
|
||||
echo.
|
||||
|
||||
echo [1/2] Starting Backend Server (Flask API)...
|
||||
start "Church App - Backend" cmd /k "cd /d "%~dp0" && start-backend.bat"
|
||||
timeout /t 3 /nobreak > nul
|
||||
|
||||
echo [2/2] Starting Frontend Server (React)...
|
||||
start "Church App - Frontend" cmd /k "cd /d "%~dp0" && start-frontend.bat"
|
||||
|
||||
echo.
|
||||
echo ========================================
|
||||
echo BOTH SERVERS STARTED
|
||||
echo ========================================
|
||||
echo.
|
||||
echo Two new windows have opened:
|
||||
echo 1. Backend Server (Flask API on port 5000)
|
||||
echo 2. Frontend Server (React on port 3000)
|
||||
echo.
|
||||
echo Access the app at:
|
||||
echo Local: http://localhost:3000
|
||||
echo LAN: http://192.168.74.1:3000
|
||||
echo External: http://houseofprayer.ddns.net:3000
|
||||
echo.
|
||||
echo To stop servers, close both windows or press Ctrl+C
|
||||
echo.
|
||||
pause
|
||||
26
legacy-site/scripts/batch/start-backend.bat
Normal file
26
legacy-site/scripts/batch/start-backend.bat
Normal file
@@ -0,0 +1,26 @@
|
||||
@echo off
|
||||
REM Start Church Song Lyric Backend Server
|
||||
REM This script starts the Flask backend API
|
||||
|
||||
echo ========================================
|
||||
echo CHURCH APP - BACKEND SERVER
|
||||
echo ========================================
|
||||
echo.
|
||||
echo Starting Flask API server on port 5000...
|
||||
echo Local Access: http://localhost:5000
|
||||
echo LAN Access: http://192.168.10.178:5000
|
||||
echo External Access: http://houseofprayer.ddns.net:5000
|
||||
echo.
|
||||
echo Press Ctrl+C to stop the server
|
||||
echo ========================================
|
||||
echo.
|
||||
|
||||
cd /d "%~dp0backend"
|
||||
|
||||
REM Activate virtual environment
|
||||
call venv\Scripts\activate.bat
|
||||
|
||||
REM Start Flask server
|
||||
python app.py
|
||||
|
||||
pause
|
||||
24
legacy-site/scripts/batch/start-frontend.bat
Normal file
24
legacy-site/scripts/batch/start-frontend.bat
Normal file
@@ -0,0 +1,24 @@
|
||||
@echo off
|
||||
REM Start Church Song Lyric Frontend
|
||||
REM This script starts the React development server
|
||||
|
||||
echo ========================================
|
||||
echo CHURCH APP - FRONTEND SERVER
|
||||
echo ========================================
|
||||
echo.
|
||||
echo Starting React development server on port 3000...
|
||||
echo Local Access: http://localhost:3000
|
||||
echo LAN Access: http://192.168.10.178:3000
|
||||
echo External Access: http://houseofprayer.ddns.net:3000
|
||||
echo.
|
||||
echo The browser will open automatically in a few seconds...
|
||||
echo Press Ctrl+C to stop the server
|
||||
echo ========================================
|
||||
echo.
|
||||
|
||||
cd /d "%~dp0frontend"
|
||||
|
||||
REM Start React development server
|
||||
npm start
|
||||
|
||||
pause
|
||||
44
legacy-site/scripts/batch/stop-all-services.bat
Normal file
44
legacy-site/scripts/batch/stop-all-services.bat
Normal file
@@ -0,0 +1,44 @@
|
||||
@echo off
|
||||
REM ========================================
|
||||
REM Church SongLyric - Stop All Services
|
||||
REM ========================================
|
||||
|
||||
title Stop All Services
|
||||
color 0C
|
||||
|
||||
echo.
|
||||
echo ========================================
|
||||
echo STOPPING ALL CHURCH SONGLYRIC SERVICES
|
||||
echo ========================================
|
||||
echo.
|
||||
|
||||
echo [1/3] Stopping Frontend (Node.js)...
|
||||
taskkill /FI "WindowTitle eq Church Frontend*" /T /F >nul 2>&1
|
||||
tasklist /FI "IMAGENAME eq node.exe" 2>NUL | find /I /N "node.exe">NUL
|
||||
if "%ERRORLEVEL%"=="0" (
|
||||
echo Stopping all Node.js processes...
|
||||
taskkill /IM node.exe /F >nul 2>&1
|
||||
echo Frontend stopped
|
||||
) else (
|
||||
echo Frontend not running
|
||||
)
|
||||
|
||||
echo.
|
||||
echo [2/3] Stopping Backend (Python)...
|
||||
taskkill /FI "WindowTitle eq Church Backend*" /T /F >nul 2>&1
|
||||
wmic process where "commandline like '%%app.py%%'" delete >nul 2>&1
|
||||
echo Backend stopped
|
||||
|
||||
echo.
|
||||
echo [3/3] Stopping MongoDB (optional)...
|
||||
echo Note: MongoDB will keep running (recommended for quick restarts)
|
||||
echo To stop MongoDB manually, run: net stop MongoDB
|
||||
echo.
|
||||
|
||||
echo ========================================
|
||||
echo ALL SERVICES STOPPED!
|
||||
echo ========================================
|
||||
echo.
|
||||
echo To restart, run: start-all-services.bat
|
||||
echo.
|
||||
pause
|
||||
107
legacy-site/scripts/batch/test-noip-setup.bat
Normal file
107
legacy-site/scripts/batch/test-noip-setup.bat
Normal file
@@ -0,0 +1,107 @@
|
||||
@echo off
|
||||
REM Test No-IP Configuration
|
||||
REM This script tests if your No-IP setup is working
|
||||
|
||||
echo ========================================
|
||||
echo NO-IP CONFIGURATION TEST
|
||||
echo ========================================
|
||||
echo.
|
||||
echo Domain: houseofprayer.ddns.net
|
||||
echo.
|
||||
|
||||
echo [1/5] Testing DNS Resolution...
|
||||
echo.
|
||||
nslookup houseofprayer.ddns.net
|
||||
if %errorlevel% equ 0 (
|
||||
echo [OK] DNS resolves correctly
|
||||
) else (
|
||||
echo [ERROR] DNS resolution failed
|
||||
echo Make sure No-IP DUC is running and up to date
|
||||
)
|
||||
echo.
|
||||
echo ========================================
|
||||
echo.
|
||||
|
||||
echo [2/5] Checking if backend is running locally...
|
||||
echo.
|
||||
curl -s http://localhost:5000/api/health > nul 2>&1
|
||||
if %errorlevel% equ 0 (
|
||||
echo [OK] Backend running on localhost:5000
|
||||
curl http://localhost:5000/api/health
|
||||
) else (
|
||||
echo [ERROR] Backend not running
|
||||
echo Start the backend server first: start-backend.bat
|
||||
)
|
||||
echo.
|
||||
echo ========================================
|
||||
echo.
|
||||
|
||||
echo [3/5] Checking if frontend is running locally...
|
||||
echo.
|
||||
curl -s http://localhost:3000 > nul 2>&1
|
||||
if %errorlevel% equ 0 (
|
||||
echo [OK] Frontend running on localhost:3000
|
||||
) else (
|
||||
echo [WARNING] Frontend not detected
|
||||
echo Start the frontend server: start-frontend.bat
|
||||
)
|
||||
echo.
|
||||
echo ========================================
|
||||
echo.
|
||||
|
||||
echo [4/5] Checking listening ports...
|
||||
echo.
|
||||
netstat -an | findstr ":5000"
|
||||
netstat -an | findstr ":3000"
|
||||
if %errorlevel% equ 0 (
|
||||
echo [OK] Servers are listening on required ports
|
||||
) else (
|
||||
echo [WARNING] Servers may not be listening
|
||||
)
|
||||
echo.
|
||||
echo ========================================
|
||||
echo.
|
||||
|
||||
echo [5/5] Testing external backend access...
|
||||
echo.
|
||||
echo Attempting to connect to: http://houseofprayer.ddns.net:5000/api/health
|
||||
echo.
|
||||
curl -s --connect-timeout 5 http://houseofprayer.ddns.net:5000/api/health
|
||||
if %errorlevel% equ 0 (
|
||||
echo.
|
||||
echo [OK] External access working!
|
||||
echo Your No-IP setup is complete and working
|
||||
) else (
|
||||
echo.
|
||||
echo [ERROR] Cannot connect externally
|
||||
echo.
|
||||
echo Possible issues:
|
||||
echo 1. Router port forwarding not configured
|
||||
echo 2. Windows Firewall blocking connections
|
||||
echo 3. No-IP DUC not running or not updated
|
||||
echo 4. ISP blocking the port
|
||||
echo.
|
||||
echo To test from outside your network:
|
||||
echo - Use phone with mobile data (WiFi off)
|
||||
echo - Visit: http://houseofprayer.ddns.net:5000/api/health
|
||||
)
|
||||
echo.
|
||||
echo ========================================
|
||||
echo.
|
||||
|
||||
echo Test Summary:
|
||||
echo - DNS Resolution: Check above
|
||||
echo - Local Backend: Check above
|
||||
echo - Local Frontend: Check above
|
||||
echo - Port Listening: Check above
|
||||
echo - External Access: Check above
|
||||
echo.
|
||||
echo Next Steps:
|
||||
echo 1. If DNS fails: Check No-IP DUC is running
|
||||
echo 2. If local fails: Start the servers
|
||||
echo 3. If external fails: Configure router port forwarding
|
||||
echo 4. If still fails: Run configure-firewall.bat as admin
|
||||
echo.
|
||||
echo For detailed troubleshooting, see: NOIP_SETUP_GUIDE.md
|
||||
echo.
|
||||
pause
|
||||
153
legacy-site/scripts/html/fix-all-devices.html
Normal file
153
legacy-site/scripts/html/fix-all-devices.html
Normal file
@@ -0,0 +1,153 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Quick Fix - All Devices</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial;
|
||||
padding: 40px;
|
||||
background: #f0f0f0;
|
||||
}
|
||||
.container {
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
background: white;
|
||||
padding: 30px;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
h1 {
|
||||
color: #333;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.button {
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: 15px;
|
||||
margin: 10px 0;
|
||||
background: #4caf50;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
font-weight: bold;
|
||||
}
|
||||
.button:hover {
|
||||
background: #45a049;
|
||||
}
|
||||
.status {
|
||||
padding: 15px;
|
||||
margin: 15px 0;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.good {
|
||||
background: #d4edda;
|
||||
color: #155724;
|
||||
}
|
||||
.bad {
|
||||
background: #f8d7da;
|
||||
color: #721c24;
|
||||
}
|
||||
.info {
|
||||
background: #d1ecf1;
|
||||
color: #0c5460;
|
||||
}
|
||||
#details {
|
||||
margin-top: 20px;
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>🔧 Fix All Devices - One Click</h1>
|
||||
<button class="button" onclick="fixNow()">✨ FIX EVERYTHING NOW</button>
|
||||
|
||||
<div id="details"></div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
async function fixNow() {
|
||||
const status = document.getElementById("status");
|
||||
const details = document.getElementById("details");
|
||||
|
||||
status.className = "status info";
|
||||
status.textContent = "Fixing settings...";
|
||||
|
||||
// Detect if desktop or mobile
|
||||
const isDesktop =
|
||||
window.location.hostname === "localhost" ||
|
||||
window.location.hostname === "127.0.0.1";
|
||||
const hostname = isDesktop ? "localhost" : window.location.hostname;
|
||||
|
||||
// Fix settings
|
||||
const settings = {
|
||||
protocol: "http",
|
||||
hostname: hostname,
|
||||
port: "5000",
|
||||
useLocalStorage: false,
|
||||
};
|
||||
|
||||
localStorage.setItem("api_settings", JSON.stringify(settings));
|
||||
|
||||
// Test connection
|
||||
const testUrl = `http://${hostname}:5000/api/health`;
|
||||
|
||||
try {
|
||||
const response = await fetch(testUrl);
|
||||
const data = await response.json();
|
||||
|
||||
if (data.status === "ok") {
|
||||
// Get counts
|
||||
const songsResp = await fetch(`http://${hostname}:5000/api/songs`);
|
||||
const songs = await songsResp.json();
|
||||
const profilesResp = await fetch(
|
||||
`http://${hostname}:5000/api/profiles`
|
||||
);
|
||||
const profiles = await profilesResp.json();
|
||||
|
||||
status.className = "status good";
|
||||
status.innerHTML = `
|
||||
<strong>✅ FIXED!</strong><br>
|
||||
Backend connected successfully<br>
|
||||
Songs: ${songs.length} | Profiles: ${profiles.length}
|
||||
`;
|
||||
|
||||
details.innerHTML = `
|
||||
<p><strong>What was fixed:</strong></p>
|
||||
<ul>
|
||||
<li>Local Mode turned OFF</li>
|
||||
<li>Hostname set to: ${hostname}</li>
|
||||
<li>Port set to: 5000</li>
|
||||
<li>Connection verified</li>
|
||||
</ul>
|
||||
<p><strong>Next step:</strong></p>
|
||||
<p>Go to <a href="http://${hostname}:3000">main app</a> and refresh (Ctrl+Shift+R)</p>
|
||||
`;
|
||||
} else {
|
||||
throw new Error("Backend returned unexpected status");
|
||||
}
|
||||
} catch (e) {
|
||||
status.className = "status bad";
|
||||
status.innerHTML = `
|
||||
<strong>❌ Connection Failed</strong><br>
|
||||
${e.message}<br><br>
|
||||
Make sure backend is running on port 5000
|
||||
`;
|
||||
|
||||
details.innerHTML = `
|
||||
<p><strong>To start backend:</strong></p>
|
||||
<code style="display: block; background: #f5f5f5; padding: 10px; border-radius: 5px;">
|
||||
cd "E:\\Documents\\Website Projects\\Church_SongLyric\\backend"<br>
|
||||
.\\venv\\Scripts\\python.exe app.py
|
||||
</code>
|
||||
`;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
341
legacy-site/scripts/html/test-concurrent-users.html
Normal file
341
legacy-site/scripts/html/test-concurrent-users.html
Normal file
@@ -0,0 +1,341 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Concurrent User Load Test - HOP Worship App</title>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
|
||||
<style>
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
|
||||
sans-serif;
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
background: #f5f5f5;
|
||||
}
|
||||
.container {
|
||||
background: white;
|
||||
padding: 30px;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
h1 {
|
||||
color: #667eea;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.subtitle {
|
||||
color: #666;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
.test-controls {
|
||||
margin-bottom: 30px;
|
||||
padding: 20px;
|
||||
background: #f8f9fa;
|
||||
border-radius: 8px;
|
||||
}
|
||||
label {
|
||||
display: block;
|
||||
margin-bottom: 8px;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
}
|
||||
input[type="number"],
|
||||
input[type="text"] {
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
border: 2px solid #ddd;
|
||||
border-radius: 6px;
|
||||
font-size: 14px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
button {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 12px 24px;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
margin-right: 10px;
|
||||
}
|
||||
button:hover {
|
||||
opacity: 0.9;
|
||||
}
|
||||
button:disabled {
|
||||
background: #ccc;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
.stop-btn {
|
||||
background: linear-gradient(135deg, #eb3349 0%, #f45c43 100%);
|
||||
}
|
||||
.results {
|
||||
margin-top: 20px;
|
||||
}
|
||||
.stat-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||
gap: 15px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.stat-card {
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
text-align: center;
|
||||
}
|
||||
.stat-card.success {
|
||||
background: #d4edda;
|
||||
border: 2px solid #28a745;
|
||||
}
|
||||
.stat-card.error {
|
||||
background: #f8d7da;
|
||||
border: 2px solid #dc3545;
|
||||
}
|
||||
.stat-card.info {
|
||||
background: #d1ecf1;
|
||||
border: 2px solid #17a2b8;
|
||||
}
|
||||
.stat-value {
|
||||
font-size: 32px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.stat-label {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
}
|
||||
.log {
|
||||
background: #1e1e1e;
|
||||
color: #00ff00;
|
||||
padding: 15px;
|
||||
border-radius: 6px;
|
||||
max-height: 400px;
|
||||
overflow-y: auto;
|
||||
font-family: "Courier New", monospace;
|
||||
font-size: 12px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
.log-entry {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.log-success {
|
||||
color: #00ff00;
|
||||
}
|
||||
.log-error {
|
||||
color: #ff4444;
|
||||
}
|
||||
.log-info {
|
||||
color: #44ccff;
|
||||
}
|
||||
.log-warning {
|
||||
color: #ffaa00;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>🎵 HOP Worship App - Concurrent User Load Test</h1>
|
||||
<p class="subtitle">
|
||||
Test multiple simultaneous logins to verify system stability
|
||||
</p>
|
||||
|
||||
<div class="test-controls">
|
||||
<label>Number of Concurrent Users:</label>
|
||||
<input type="number" id="userCount" value="10" min="1" max="100" />
|
||||
|
||||
<label>Site URL:</label>
|
||||
<input
|
||||
type="text"
|
||||
id="siteUrl"
|
||||
value="http://192.168.10.130:3000"
|
||||
placeholder="http://localhost:3000"
|
||||
/>
|
||||
|
||||
<label>Username:</label>
|
||||
<input type="text" id="username" value="hop" />
|
||||
|
||||
<label>Password:</label>
|
||||
<input type="text" id="password" value="hop@2026ilovejesus" />
|
||||
|
||||
<button onclick="startTest()" id="startBtn">▶️ Start Load Test</button>
|
||||
<button onclick="stopTest()" id="stopBtn" class="stop-btn" disabled>
|
||||
⏹️ Stop Test
|
||||
</button>
|
||||
<button onclick="clearLog()">🗑️ Clear Log</button>
|
||||
</div>
|
||||
|
||||
<div class="results">
|
||||
<div class="stat-grid">
|
||||
<div class="stat-card success">
|
||||
<div class="stat-value" id="successCount">0</div>
|
||||
<div class="stat-label">Successful Logins</div>
|
||||
</div>
|
||||
<div class="stat-card error">
|
||||
<div class="stat-value" id="errorCount">0</div>
|
||||
<div class="stat-label">Failed Attempts</div>
|
||||
</div>
|
||||
<div class="stat-card info">
|
||||
<div class="stat-value" id="activeCount">0</div>
|
||||
<div class="stat-label">Active Sessions</div>
|
||||
</div>
|
||||
<div class="stat-card info">
|
||||
<div class="stat-value" id="avgTime">0ms</div>
|
||||
<div class="stat-label">Avg Response Time</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3>Test Log:</h3>
|
||||
<div class="log" id="logContainer"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
let stats = {
|
||||
success: 0,
|
||||
error: 0,
|
||||
active: 0,
|
||||
times: [],
|
||||
};
|
||||
let testRunning = false;
|
||||
let windows = [];
|
||||
|
||||
function log(message, type = "info") {
|
||||
const container = document.getElementById("logContainer");
|
||||
const timestamp = new Date().toLocaleTimeString();
|
||||
const entry = document.createElement("div");
|
||||
entry.className = `log-entry log-${type}`;
|
||||
entry.textContent = `[${timestamp}] ${message}`;
|
||||
container.appendChild(entry);
|
||||
container.scrollTop = container.scrollHeight;
|
||||
}
|
||||
|
||||
function updateStats() {
|
||||
document.getElementById("successCount").textContent = stats.success;
|
||||
document.getElementById("errorCount").textContent = stats.error;
|
||||
document.getElementById("activeCount").textContent = stats.active;
|
||||
|
||||
if (stats.times.length > 0) {
|
||||
const avg =
|
||||
stats.times.reduce((a, b) => a + b, 0) / stats.times.length;
|
||||
document.getElementById("avgTime").textContent =
|
||||
Math.round(avg) + "ms";
|
||||
}
|
||||
}
|
||||
|
||||
function hashPassword(pwd) {
|
||||
return CryptoJS.SHA256(pwd).toString();
|
||||
}
|
||||
|
||||
function simulateLogin(userId, url, username, password) {
|
||||
return new Promise((resolve) => {
|
||||
const startTime = Date.now();
|
||||
|
||||
try {
|
||||
// Simulate authentication logic (client-side)
|
||||
const passwordHash = hashPassword(password);
|
||||
const MASTER_PASSWORD_HASH =
|
||||
"5cdf907c69ae7a7f0c2e18a67e9b70a4c4fc35f9582637354c1bc45edf092a79";
|
||||
|
||||
setTimeout(() => {
|
||||
const elapsed = Date.now() - startTime;
|
||||
|
||||
if (username === "hop" && passwordHash === MASTER_PASSWORD_HASH) {
|
||||
stats.success++;
|
||||
stats.active++;
|
||||
stats.times.push(elapsed);
|
||||
log(
|
||||
`User ${userId}: Login successful (${elapsed}ms)`,
|
||||
"success"
|
||||
);
|
||||
resolve({ success: true, time: elapsed });
|
||||
} else {
|
||||
stats.error++;
|
||||
log(`User ${userId}: Invalid credentials`, "error");
|
||||
resolve({ success: false, time: elapsed });
|
||||
}
|
||||
updateStats();
|
||||
}, Math.random() * 100); // Simulate network latency
|
||||
} catch (err) {
|
||||
stats.error++;
|
||||
log(`User ${userId}: Error - ${err.message}`, "error");
|
||||
updateStats();
|
||||
resolve({ success: false, error: err.message });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function startTest() {
|
||||
if (testRunning) return;
|
||||
|
||||
testRunning = true;
|
||||
document.getElementById("startBtn").disabled = true;
|
||||
document.getElementById("stopBtn").disabled = false;
|
||||
|
||||
// Reset stats
|
||||
stats = { success: 0, error: 0, active: 0, times: [] };
|
||||
updateStats();
|
||||
|
||||
const userCount = parseInt(document.getElementById("userCount").value);
|
||||
const url = document.getElementById("siteUrl").value;
|
||||
const username = document.getElementById("username").value;
|
||||
const password = document.getElementById("password").value;
|
||||
|
||||
log(
|
||||
`Starting load test with ${userCount} concurrent users...`,
|
||||
"warning"
|
||||
);
|
||||
log(`Target: ${url}`, "info");
|
||||
|
||||
// Simulate concurrent logins
|
||||
const promises = [];
|
||||
for (let i = 1; i <= userCount; i++) {
|
||||
promises.push(simulateLogin(i, url, username, password));
|
||||
}
|
||||
|
||||
await Promise.all(promises);
|
||||
|
||||
log(`Load test completed!`, "success");
|
||||
log(
|
||||
`Success: ${stats.success}/${userCount}, Errors: ${stats.error}`,
|
||||
"info"
|
||||
);
|
||||
|
||||
if (stats.times.length > 0) {
|
||||
const avg =
|
||||
stats.times.reduce((a, b) => a + b, 0) / stats.times.length;
|
||||
const min = Math.min(...stats.times);
|
||||
const max = Math.max(...stats.times);
|
||||
log(
|
||||
`Response times - Min: ${min}ms, Max: ${max}ms, Avg: ${Math.round(
|
||||
avg
|
||||
)}ms`,
|
||||
"info"
|
||||
);
|
||||
}
|
||||
|
||||
document.getElementById("startBtn").disabled = false;
|
||||
document.getElementById("stopBtn").disabled = true;
|
||||
testRunning = false;
|
||||
}
|
||||
|
||||
function stopTest() {
|
||||
testRunning = false;
|
||||
document.getElementById("startBtn").disabled = false;
|
||||
document.getElementById("stopBtn").disabled = true;
|
||||
log("Test stopped by user", "warning");
|
||||
}
|
||||
|
||||
function clearLog() {
|
||||
document.getElementById("logContainer").innerHTML = "";
|
||||
log("Log cleared", "info");
|
||||
}
|
||||
|
||||
// Initial log message
|
||||
log(
|
||||
'Load testing tool ready. Configure settings and click "Start Load Test"',
|
||||
"info"
|
||||
);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
40
legacy-site/scripts/html/test_api.html
Normal file
40
legacy-site/scripts/html/test_api.html
Normal file
@@ -0,0 +1,40 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>API Test</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>House of Prayer - API Test</h1>
|
||||
<div id="status"></div>
|
||||
<div id="profiles"></div>
|
||||
<div id="plans"></div>
|
||||
|
||||
<script>
|
||||
const statusDiv = document.getElementById('status');
|
||||
const profilesDiv = document.getElementById('profiles');
|
||||
const plansDiv = document.getElementById('plans');
|
||||
|
||||
async function testAPI() {
|
||||
try {
|
||||
// Test profiles
|
||||
const profileRes = await fetch('http://localhost:5000/api/profiles');
|
||||
const profiles = await profileRes.json();
|
||||
statusDiv.innerHTML = '<p style="color: green;">✓ Backend API is working!</p>';
|
||||
profilesDiv.innerHTML = '<h2>Profiles:</h2><pre>' + JSON.stringify(profiles, null, 2) + '</pre>';
|
||||
|
||||
// Test plans
|
||||
const plansRes = await fetch('http://localhost:5000/api/plans');
|
||||
const plans = await plansRes.json();
|
||||
plansDiv.innerHTML = '<h2>Plans:</h2><pre>' + JSON.stringify(plans, null, 2) + '</pre>';
|
||||
|
||||
} catch (error) {
|
||||
statusDiv.innerHTML = '<p style="color: red;">✗ Error: ' + error.message + '</p>';
|
||||
}
|
||||
}
|
||||
|
||||
testAPI();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
48
legacy-site/scripts/restart-services.sh
Executable file
48
legacy-site/scripts/restart-services.sh
Executable file
@@ -0,0 +1,48 @@
|
||||
#!/bin/bash
|
||||
# Restart script for Church Music App services
|
||||
|
||||
echo "🔄 Restarting Church Music App Services..."
|
||||
|
||||
# Stop services
|
||||
echo "⏸️ Stopping services..."
|
||||
pkill -f "gunicorn.*church_music_backend" || true
|
||||
pkill -f "serve.*5100" || true
|
||||
sleep 2
|
||||
|
||||
# Start backend
|
||||
echo "🚀 Starting backend..."
|
||||
cd /media/pts/Website/Church_HOP_MusicData/backend
|
||||
source venv/bin/activate
|
||||
nohup gunicorn \
|
||||
--bind 127.0.0.1:8080 \
|
||||
--workers 2 \
|
||||
--worker-class sync \
|
||||
--timeout 120 \
|
||||
--graceful-timeout 30 \
|
||||
--keep-alive 5 \
|
||||
--access-logfile logs/access.log \
|
||||
--error-logfile logs/error.log \
|
||||
--log-level info \
|
||||
--name church_music_backend \
|
||||
app:app > logs/backend.log 2>&1 &
|
||||
|
||||
echo "⏳ Waiting for backend to start..."
|
||||
sleep 3
|
||||
|
||||
# Start frontend
|
||||
echo "🚀 Starting frontend..."
|
||||
cd /media/pts/Website/Church_HOP_MusicData/frontend
|
||||
nohup serve -s -p 5100 --no-clipboard build > ../frontend.log 2>&1 &
|
||||
|
||||
echo "⏳ Waiting for frontend to start..."
|
||||
sleep 2
|
||||
|
||||
# Check status
|
||||
echo ""
|
||||
echo "📊 Service Status:"
|
||||
echo "Backend: $(curl -s http://localhost:8080/api/health | grep -o 'ok' || echo '❌ Not responding')"
|
||||
echo "Frontend: $(curl -s http://localhost:5100 | grep -o 'HOP Worship' | head -1 || echo '❌ Not responding')"
|
||||
echo ""
|
||||
echo "✅ Services restarted!"
|
||||
echo "🌐 Frontend: http://localhost:5100"
|
||||
echo "🔧 Backend API: http://localhost:8080"
|
||||
169
legacy-site/scripts/security-hardening.py
Executable file
169
legacy-site/scripts/security-hardening.py
Executable file
@@ -0,0 +1,169 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Security Hardening Script for Church Music Database
|
||||
Implements critical security fixes
|
||||
"""
|
||||
|
||||
import os
|
||||
import secrets
|
||||
import sys
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
def generate_secure_key():
|
||||
"""Generate cryptographically secure secret key"""
|
||||
return secrets.token_hex(32)
|
||||
|
||||
def check_env_file_security(env_path):
|
||||
"""Check if .env file has secure permissions"""
|
||||
if not os.path.exists(env_path):
|
||||
return False, "File does not exist"
|
||||
|
||||
stat_info = os.stat(env_path)
|
||||
mode = stat_info.st_mode & 0o777
|
||||
|
||||
if mode != 0o600:
|
||||
return False, f"Insecure permissions: {oct(mode)}. Should be 0600"
|
||||
return True, "OK"
|
||||
|
||||
def secure_env_file(env_path):
|
||||
"""Set secure permissions on .env file"""
|
||||
try:
|
||||
os.chmod(env_path, 0o600)
|
||||
return True
|
||||
except Exception as e:
|
||||
return False, str(e)
|
||||
|
||||
def validate_postgresql_uri(uri):
|
||||
"""Validate PostgreSQL connection string"""
|
||||
if not uri or uri == "":
|
||||
return False, "Empty URI"
|
||||
|
||||
# Check for default/weak passwords
|
||||
weak_patterns = [
|
||||
'your_password',
|
||||
'password',
|
||||
'admin',
|
||||
'123456',
|
||||
'postgres'
|
||||
]
|
||||
|
||||
for pattern in weak_patterns:
|
||||
if pattern.lower() in uri.lower():
|
||||
return False, f"Weak/default password detected: {pattern}"
|
||||
|
||||
# Validate format
|
||||
if not uri.startswith('postgresql://'):
|
||||
return False, "Invalid PostgreSQL URI format"
|
||||
|
||||
return True, "OK"
|
||||
|
||||
def main():
|
||||
print("╔══════════════════════════════════════════════════════════════╗")
|
||||
print("║ SECURITY HARDENING - Critical Fixes ║")
|
||||
print("╚══════════════════════════════════════════════════════════════╝")
|
||||
print()
|
||||
|
||||
project_root = Path(__file__).parent
|
||||
backend_dir = project_root / "backend"
|
||||
env_file = backend_dir / ".env"
|
||||
|
||||
issues_found = []
|
||||
fixes_applied = []
|
||||
|
||||
# Check 1: .env file exists and has secure permissions
|
||||
print("🔒 Checking .env file security...")
|
||||
if env_file.exists():
|
||||
is_secure, msg = check_env_file_security(env_file)
|
||||
if not is_secure:
|
||||
issues_found.append(f".env file: {msg}")
|
||||
if secure_env_file(env_file):
|
||||
fixes_applied.append("Set .env permissions to 0600")
|
||||
print(" ✓ Fixed: Set secure permissions (0600)")
|
||||
else:
|
||||
print(f" ✗ Failed to secure .env file")
|
||||
else:
|
||||
print(" ✓ .env file has secure permissions")
|
||||
else:
|
||||
issues_found.append(".env file does not exist")
|
||||
print(" ⚠ .env file not found. Use .env.template to create one.")
|
||||
|
||||
# Check 2: SECRET_KEY strength
|
||||
print("\n🔑 Checking SECRET_KEY...")
|
||||
if env_file.exists():
|
||||
with open(env_file, 'r') as f:
|
||||
content = f.read()
|
||||
secret_match = re.search(r'SECRET_KEY=(.+)', content)
|
||||
if secret_match:
|
||||
secret_key = secret_match.group(1).strip()
|
||||
if len(secret_key) < 32:
|
||||
issues_found.append(f"SECRET_KEY is too short ({len(secret_key)} chars, need 64+)")
|
||||
print(f" ⚠ SECRET_KEY is weak (length: {len(secret_key)})")
|
||||
print(f" → Generate new key: python3 -c \"import secrets; print(secrets.token_hex(32))\"")
|
||||
else:
|
||||
print(" ✓ SECRET_KEY length is adequate")
|
||||
else:
|
||||
issues_found.append("SECRET_KEY not found in .env")
|
||||
print(" ✗ SECRET_KEY not found")
|
||||
|
||||
# Check 3: Database password strength
|
||||
print("\n🗄️ Checking database password...")
|
||||
if env_file.exists():
|
||||
with open(env_file, 'r') as f:
|
||||
content = f.read()
|
||||
uri_match = re.search(r'POSTGRESQL_URI=(.+)', content)
|
||||
if uri_match:
|
||||
uri = uri_match.group(1).strip()
|
||||
is_valid, msg = validate_postgresql_uri(uri)
|
||||
if not is_valid:
|
||||
issues_found.append(f"Database URI: {msg}")
|
||||
print(f" ✗ {msg}")
|
||||
else:
|
||||
print(" ✓ Database URI appears secure")
|
||||
else:
|
||||
issues_found.append("POSTGRESQL_URI not found")
|
||||
print(" ✗ POSTGRESQL_URI not configured")
|
||||
|
||||
# Check 4: .gitignore exists
|
||||
print("\n📝 Checking .gitignore...")
|
||||
gitignore = project_root / ".gitignore"
|
||||
if gitignore.exists():
|
||||
with open(gitignore, 'r') as f:
|
||||
content = f.read()
|
||||
if '*.env' in content or '.env' in content:
|
||||
print(" ✓ .gitignore protects .env files")
|
||||
else:
|
||||
issues_found.append(".env files not in .gitignore")
|
||||
print(" ✗ .env files not protected by .gitignore")
|
||||
else:
|
||||
issues_found.append(".gitignore does not exist")
|
||||
print(" ✗ .gitignore not found")
|
||||
|
||||
# Summary
|
||||
print("\n" + "="*64)
|
||||
print("SUMMARY")
|
||||
print("="*64)
|
||||
|
||||
if issues_found:
|
||||
print(f"\n⚠️ {len(issues_found)} security issue(s) found:")
|
||||
for i, issue in enumerate(issues_found, 1):
|
||||
print(f" {i}. {issue}")
|
||||
else:
|
||||
print("\n✅ No critical security issues found")
|
||||
|
||||
if fixes_applied:
|
||||
print(f"\n✓ {len(fixes_applied)} fix(es) applied:")
|
||||
for fix in fixes_applied:
|
||||
print(f" • {fix}")
|
||||
|
||||
print("\n📋 NEXT STEPS:")
|
||||
print(" 1. Rotate SECRET_KEY immediately if weak")
|
||||
print(" 2. Update database password if using defaults")
|
||||
print(" 3. Never commit .env files to git")
|
||||
print(" 4. Review all environment variables")
|
||||
print(" 5. Run this script regularly")
|
||||
|
||||
return 0 if not issues_found else 1
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
179
legacy-site/scripts/shell/ARCHITECTURE_AUDIT.sh
Executable file
179
legacy-site/scripts/shell/ARCHITECTURE_AUDIT.sh
Executable file
@@ -0,0 +1,179 @@
|
||||
#!/bin/bash
|
||||
# Comprehensive System Architecture & Security Audit
|
||||
# Generated: December 17, 2025
|
||||
|
||||
echo "╔══════════════════════════════════════════════════════════════╗"
|
||||
echo "║ SYSTEM ARCHITECTURE & SECURITY AUDIT ║"
|
||||
echo "╚══════════════════════════════════════════════════════════════╝"
|
||||
echo ""
|
||||
|
||||
# Project Structure
|
||||
echo "PROJECT: Church Music Database (House of Prayer)"
|
||||
echo "TYPE: Full-Stack Web Application"
|
||||
echo "ENVIRONMENT: Production (Linux)"
|
||||
echo ""
|
||||
|
||||
echo "TECH STACK:"
|
||||
echo " Frontend: React 18.2 + React Router + Bootstrap 5"
|
||||
echo " Backend: Flask + Gunicorn + PostgreSQL"
|
||||
echo " Server: Nginx (HTTPS with Let's Encrypt)"
|
||||
echo " Database: PostgreSQL 15+"
|
||||
echo " Deployment: Systemd services"
|
||||
echo ""
|
||||
|
||||
echo "═══════════════════════════════════════════════════════════════"
|
||||
echo "CRITICAL SECURITY ISSUES IDENTIFIED"
|
||||
echo "═══════════════════════════════════════════════════════════════"
|
||||
echo ""
|
||||
|
||||
echo "🔴 CRITICAL - Hardcoded Secrets in Repository"
|
||||
echo " • SECRET_KEY exposed in .env file (committed to repo)"
|
||||
echo " • Database password visible in .env"
|
||||
echo " • Master password hash exposed in frontend code"
|
||||
echo " • No .gitignore for sensitive files"
|
||||
echo ""
|
||||
|
||||
echo "🔴 CRITICAL - Authentication Weakness"
|
||||
echo " • Client-side only authentication (no JWT/session)"
|
||||
echo " • Password hash visible in frontend source"
|
||||
echo " • No rate limiting on login attempts"
|
||||
echo " • No account lockout mechanism"
|
||||
echo ""
|
||||
|
||||
echo "🟠 HIGH - CORS Misconfiguration"
|
||||
echo " • Wildcard origins allowed in nginx"
|
||||
echo " • Multiple origin patterns (some redundant)"
|
||||
echo " • CORS headers in both nginx and Flask (conflict risk)"
|
||||
echo ""
|
||||
|
||||
echo "🟠 HIGH - Missing Input Validation"
|
||||
echo " • No schema validation on API endpoints"
|
||||
echo " • Missing SQL injection protection in some queries"
|
||||
echo " • File upload size check but no MIME type validation"
|
||||
echo " • No request rate limiting"
|
||||
echo ""
|
||||
|
||||
echo "🟡 MEDIUM - Database Connection Management"
|
||||
echo " • No connection timeout settings"
|
||||
echo " • Missing prepared statements in some queries"
|
||||
echo " • No query timeout limits"
|
||||
echo ""
|
||||
|
||||
echo "🟡 MEDIUM - Error Handling"
|
||||
echo " • Generic error messages expose stack traces"
|
||||
echo " • No centralized error logging"
|
||||
echo " • Missing error monitoring/alerting"
|
||||
echo ""
|
||||
|
||||
echo "🟡 MEDIUM - Session Management"
|
||||
echo " • No session expiration enforcement"
|
||||
echo " • localStorage used for sensitive data"
|
||||
echo " • No CSRF protection"
|
||||
echo ""
|
||||
|
||||
echo "═══════════════════════════════════════════════════════════════"
|
||||
echo "ARCHITECTURE ANTI-PATTERNS"
|
||||
echo "═══════════════════════════════════════════════════════════════"
|
||||
echo ""
|
||||
|
||||
echo "⚠️ Mixed Dev/Production Code"
|
||||
echo " • Development server scripts alongside production"
|
||||
echo " • No clear environment separation"
|
||||
echo " • Multiple start scripts causing confusion"
|
||||
echo ""
|
||||
|
||||
echo "⚠️ Monolithic File Structure"
|
||||
echo " • app.py is 895 lines (should be modularized)"
|
||||
echo " • No separation of concerns (routes, models, utils)"
|
||||
echo " • App.js is 7661 lines (should be split into components)"
|
||||
echo ""
|
||||
|
||||
echo "⚠️ Missing API Documentation"
|
||||
echo " • No OpenAPI/Swagger documentation"
|
||||
echo " • Inconsistent API response formats"
|
||||
echo " • No API versioning"
|
||||
echo ""
|
||||
|
||||
echo "⚠️ No Automated Testing"
|
||||
echo " • No unit tests"
|
||||
echo " • No integration tests"
|
||||
echo " • No CI/CD pipeline"
|
||||
echo ""
|
||||
|
||||
echo "═══════════════════════════════════════════════════════════════"
|
||||
echo "PERFORMANCE ISSUES"
|
||||
echo "═══════════════════════════════════════════════════════════════"
|
||||
echo ""
|
||||
|
||||
echo "📉 Database N+1 Queries"
|
||||
echo " • Missing eager loading in relationships"
|
||||
echo " • Queries in loops (plans, profile songs)"
|
||||
echo ""
|
||||
|
||||
echo "📉 No Caching Layer"
|
||||
echo " • Repeated database queries for same data"
|
||||
echo " • No Redis/Memcached integration"
|
||||
echo " • Static assets served through proxy (slow)"
|
||||
echo ""
|
||||
|
||||
echo "📉 Large Bundle Size"
|
||||
echo " • Frontend bundle ~380KB (should be code-split)"
|
||||
echo " • No lazy loading for routes"
|
||||
echo " • All components loaded upfront"
|
||||
echo ""
|
||||
|
||||
echo "═══════════════════════════════════════════════════════════════"
|
||||
echo "MISSING FEATURES"
|
||||
echo "═══════════════════════════════════════════════════════════════"
|
||||
echo ""
|
||||
|
||||
echo "❌ No Backup Strategy"
|
||||
echo " • No automated database backups"
|
||||
echo " • No backup verification"
|
||||
echo " • No disaster recovery plan"
|
||||
echo ""
|
||||
|
||||
echo "❌ No Monitoring/Observability"
|
||||
echo " • No application metrics"
|
||||
echo " • No health check dashboard"
|
||||
echo " • No error tracking (Sentry, etc.)"
|
||||
echo ""
|
||||
|
||||
echo "❌ No Audit Logging"
|
||||
echo " • No user action logs"
|
||||
echo " • No data change tracking"
|
||||
echo " • No compliance logging"
|
||||
echo ""
|
||||
|
||||
echo "═══════════════════════════════════════════════════════════════"
|
||||
echo "RECOMMENDATIONS"
|
||||
echo "═══════════════════════════════════════════════════════════════"
|
||||
echo ""
|
||||
|
||||
echo "IMMEDIATE (Within 24 hours):"
|
||||
echo " 1. Rotate SECRET_KEY and store in environment"
|
||||
echo " 2. Add .env files to .gitignore"
|
||||
echo " 3. Implement server-side authentication"
|
||||
echo " 4. Add rate limiting to all endpoints"
|
||||
echo " 5. Fix CORS configuration"
|
||||
echo ""
|
||||
|
||||
echo "SHORT-TERM (Within 1 week):"
|
||||
echo " 6. Refactor monolithic files into modules"
|
||||
echo " 7. Add input validation schemas (Pydantic)"
|
||||
echo " 8. Implement database backup automation"
|
||||
echo " 9. Add comprehensive error handling"
|
||||
echo " 10. Set up monitoring and alerting"
|
||||
echo ""
|
||||
|
||||
echo "LONG-TERM (Within 1 month):"
|
||||
echo " 11. Implement automated testing (80%+ coverage)"
|
||||
echo " 12. Add API documentation (OpenAPI)"
|
||||
echo " 13. Implement caching layer (Redis)"
|
||||
echo " 14. Code-split frontend for performance"
|
||||
echo " 15. Set up CI/CD pipeline"
|
||||
echo ""
|
||||
|
||||
echo "═══════════════════════════════════════════════════════════════"
|
||||
echo "AUDIT COMPLETE"
|
||||
echo "═══════════════════════════════════════════════════════════════"
|
||||
107
legacy-site/scripts/shell/backup-database.sh
Executable file
107
legacy-site/scripts/shell/backup-database.sh
Executable file
@@ -0,0 +1,107 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# PostgreSQL Database Backup Script with Rotation
|
||||
# Backs up database and maintains 7 days of history
|
||||
#
|
||||
|
||||
set -e # Exit on error
|
||||
|
||||
# Configuration
|
||||
BACKUP_DIR="/media/pts/Website/Church_HOP_MusicData/backups"
|
||||
DB_NAME="church_songlyric"
|
||||
DB_USER="songlyric_user"
|
||||
DB_HOST="192.168.10.130"
|
||||
DB_PORT="5432"
|
||||
RETENTION_DAYS=7
|
||||
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
|
||||
BACKUP_FILE="$BACKUP_DIR/${DB_NAME}_${TIMESTAMP}.sql.gz"
|
||||
LOG_FILE="$BACKUP_DIR/backup.log"
|
||||
|
||||
# Colors for output
|
||||
GREEN='\033[0;32m'
|
||||
RED='\033[0;31m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Logging function
|
||||
log() {
|
||||
echo "[$(date +'%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
|
||||
}
|
||||
|
||||
# Create backup directory if it doesn't exist
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
|
||||
log "=========================================="
|
||||
log "Starting database backup"
|
||||
log "Database: $DB_NAME"
|
||||
log "Timestamp: $TIMESTAMP"
|
||||
|
||||
# Check if PostgreSQL client is installed
|
||||
if ! command -v pg_dump &> /dev/null; then
|
||||
log "ERROR: pg_dump not found. Install postgresql-client"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check database connectivity
|
||||
if ! PGPASSWORD="$POSTGRES_PASSWORD" psql -h "$DB_HOST" -U "$DB_USER" -d "$DB_NAME" -c "\q" 2>/dev/null; then
|
||||
log "WARNING: Cannot connect to database. Check credentials in .env"
|
||||
fi
|
||||
|
||||
# Perform backup
|
||||
log "Creating backup..."
|
||||
if PGPASSWORD="$POSTGRES_PASSWORD" pg_dump \
|
||||
-h "$DB_HOST" \
|
||||
-U "$DB_USER" \
|
||||
-d "$DB_NAME" \
|
||||
--verbose \
|
||||
--format=plain \
|
||||
--no-owner \
|
||||
--no-privileges \
|
||||
2>> "$LOG_FILE" | gzip > "$BACKUP_FILE"; then
|
||||
|
||||
BACKUP_SIZE=$(du -h "$BACKUP_FILE" | cut -f1)
|
||||
log "✓ Backup created successfully: $BACKUP_FILE"
|
||||
log " Size: $BACKUP_SIZE"
|
||||
else
|
||||
log "✗ Backup failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Verify backup integrity
|
||||
log "Verifying backup integrity..."
|
||||
if gzip -t "$BACKUP_FILE"; then
|
||||
log "✓ Backup file integrity verified"
|
||||
else
|
||||
log "✗ Backup file is corrupted"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Clean up old backups
|
||||
log "Cleaning up old backups (keeping last $RETENTION_DAYS days)..."
|
||||
find "$BACKUP_DIR" -name "${DB_NAME}_*.sql.gz" -type f -mtime +$RETENTION_DAYS -delete
|
||||
OLD_COUNT=$(find "$BACKUP_DIR" -name "${DB_NAME}_*.sql.gz" -type f | wc -l)
|
||||
log "✓ Retained $OLD_COUNT backup file(s)"
|
||||
|
||||
# Create a 'latest' symlink
|
||||
ln -sf "$BACKUP_FILE" "$BACKUP_DIR/${DB_NAME}_latest.sql.gz"
|
||||
log "✓ Updated latest backup symlink"
|
||||
|
||||
# Display backup summary
|
||||
echo ""
|
||||
echo -e "${GREEN}=========================================="
|
||||
echo -e "BACKUP COMPLETED SUCCESSFULLY"
|
||||
echo -e "==========================================${NC}"
|
||||
echo "Backup file: $BACKUP_FILE"
|
||||
echo "Size: $BACKUP_SIZE"
|
||||
echo "Retention: $RETENTION_DAYS days"
|
||||
echo "Total backups: $OLD_COUNT"
|
||||
echo ""
|
||||
|
||||
# Optional: Upload to cloud storage (uncomment and configure)
|
||||
# log "Uploading to cloud storage..."
|
||||
# aws s3 cp "$BACKUP_FILE" "s3://your-bucket/backups/" || log "Cloud upload failed"
|
||||
|
||||
log "Backup process completed"
|
||||
log "=========================================="
|
||||
|
||||
exit 0
|
||||
43
legacy-site/scripts/shell/check-database.sh
Executable file
43
legacy-site/scripts/shell/check-database.sh
Executable file
@@ -0,0 +1,43 @@
|
||||
#!/bin/bash
|
||||
# Quick verification that PostgreSQL is storing data
|
||||
|
||||
echo "Checking PostgreSQL database..."
|
||||
|
||||
# Method 1: Direct query
|
||||
PGPASSWORD=your_password psql -U songlyric_user -d church_songlyric -t -c "
|
||||
SELECT
|
||||
'Songs: ' || COUNT(*) as count FROM songs
|
||||
UNION ALL
|
||||
SELECT
|
||||
'Profiles: ' || COUNT(*) FROM profiles
|
||||
UNION ALL
|
||||
SELECT
|
||||
'Profile-Songs: ' || COUNT(*) FROM profile_songs;
|
||||
" 2>/dev/null || {
|
||||
echo "Direct PostgreSQL query failed, trying Python..."
|
||||
|
||||
# Method 2: Python check
|
||||
cd /media/pts/Website/Church_HOP_MusicData/backend
|
||||
source venv/bin/activate
|
||||
python3 << 'PYTHON'
|
||||
from postgresql_models import SessionLocal, Song, Profile, ProfileSong
|
||||
session = SessionLocal()
|
||||
try:
|
||||
songs = session.query(Song).count()
|
||||
profiles = session.query(Profile).count()
|
||||
profile_songs = session.query(ProfileSong).count()
|
||||
print(f"✅ PostgreSQL Data:")
|
||||
print(f" Songs: {songs}")
|
||||
print(f" Profiles: {profiles}")
|
||||
print(f" Profile-Songs: {profile_songs}")
|
||||
if songs > 0:
|
||||
print(f"\n✅ Data is being stored in PostgreSQL!")
|
||||
else:
|
||||
print(f"\n⚠️ Warning: No songs found")
|
||||
finally:
|
||||
session.close()
|
||||
PYTHON
|
||||
}
|
||||
|
||||
echo ""
|
||||
echo "Database check complete."
|
||||
149
legacy-site/scripts/shell/cleanup-ports.sh
Executable file
149
legacy-site/scripts/shell/cleanup-ports.sh
Executable file
@@ -0,0 +1,149 @@
|
||||
#!/bin/bash
|
||||
# Port Cleanup Script - Kill any processes using critical ports
|
||||
# This prevents port conflicts when starting services
|
||||
|
||||
echo "╔════════════════════════════════════════════════════════════════╗"
|
||||
echo "║ Port Cleanup & Conflict Resolution ║"
|
||||
echo "╚════════════════════════════════════════════════════════════════╝"
|
||||
echo ""
|
||||
|
||||
# Colors
|
||||
GREEN='\033[0;32m'
|
||||
RED='\033[0;31m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Ports to check
|
||||
BACKEND_PORT=8080
|
||||
FRONTEND_PORT=5100
|
||||
|
||||
# Function to check and kill process on a port
|
||||
cleanup_port() {
|
||||
local port=$1
|
||||
local service_name=$2
|
||||
|
||||
echo "Checking port $port ($service_name)..."
|
||||
|
||||
# Find process using the port
|
||||
local pids=$(sudo lsof -ti :$port 2>/dev/null)
|
||||
|
||||
if [ -z "$pids" ]; then
|
||||
echo -e "${GREEN}✓ Port $port is free${NC}"
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo -e "${YELLOW}⚠ Port $port is in use by PID(s): $pids${NC}"
|
||||
|
||||
# Get process details
|
||||
for pid in $pids; do
|
||||
local cmd=$(ps -p $pid -o comm= 2>/dev/null)
|
||||
local full_cmd=$(ps -p $pid -o args= 2>/dev/null)
|
||||
echo " Process: $cmd (PID $pid)"
|
||||
echo " Command: $full_cmd"
|
||||
|
||||
# Check if it's a systemd service
|
||||
if systemctl status church-music-backend.service 2>/dev/null | grep -q "Main PID: $pid"; then
|
||||
echo -e "${YELLOW} This is the systemd backend service - use 'systemctl stop' instead${NC}"
|
||||
continue
|
||||
fi
|
||||
|
||||
if systemctl status church-music-frontend.service 2>/dev/null | grep -q "Main PID: $pid"; then
|
||||
echo -e "${YELLOW} This is the systemd frontend service - use 'systemctl stop' instead${NC}"
|
||||
continue
|
||||
fi
|
||||
|
||||
# Kill the rogue process
|
||||
echo " Killing process $pid..."
|
||||
sudo kill -9 $pid 2>/dev/null
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo -e "${GREEN} ✓ Process $pid killed${NC}"
|
||||
else
|
||||
echo -e "${RED} ✗ Failed to kill process $pid${NC}"
|
||||
fi
|
||||
done
|
||||
|
||||
# Verify port is now free
|
||||
sleep 1
|
||||
if sudo lsof -ti :$port &>/dev/null; then
|
||||
echo -e "${RED}✗ Port $port still in use after cleanup${NC}"
|
||||
return 1
|
||||
else
|
||||
echo -e "${GREEN}✓ Port $port is now free${NC}"
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
# Clean up PID files from development mode
|
||||
cleanup_pid_files() {
|
||||
echo ""
|
||||
echo "Cleaning up stale PID files..."
|
||||
|
||||
if [ -f /tmp/church-backend.pid ]; then
|
||||
local pid=$(cat /tmp/church-backend.pid)
|
||||
if ! ps -p $pid > /dev/null 2>&1; then
|
||||
rm /tmp/church-backend.pid
|
||||
echo -e "${GREEN}✓ Removed stale backend PID file${NC}"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -f /tmp/church-frontend.pid ]; then
|
||||
local pid=$(cat /tmp/church-frontend.pid)
|
||||
if ! ps -p $pid > /dev/null 2>&1; then
|
||||
rm /tmp/church-frontend.pid
|
||||
echo -e "${GREEN}✓ Removed stale frontend PID file${NC}"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Kill any webpack dev servers or react-scripts
|
||||
cleanup_dev_servers() {
|
||||
echo ""
|
||||
echo "Checking for development servers..."
|
||||
|
||||
local react_pids=$(pgrep -f "react-scripts start" 2>/dev/null)
|
||||
if [ -n "$react_pids" ]; then
|
||||
echo -e "${YELLOW}⚠ Found React dev server processes${NC}"
|
||||
for pid in $react_pids; do
|
||||
echo " Killing react-scripts (PID $pid)"
|
||||
kill -9 $pid 2>/dev/null || true
|
||||
done
|
||||
echo -e "${GREEN}✓ React dev servers killed${NC}"
|
||||
fi
|
||||
|
||||
local webpack_pids=$(pgrep -f "webpack-dev-server" 2>/dev/null)
|
||||
if [ -n "$webpack_pids" ]; then
|
||||
echo -e "${YELLOW}⚠ Found webpack-dev-server processes${NC}"
|
||||
for pid in $webpack_pids; do
|
||||
echo " Killing webpack-dev-server (PID $pid)"
|
||||
kill -9 $pid 2>/dev/null || true
|
||||
done
|
||||
echo -e "${GREEN}✓ Webpack dev servers killed${NC}"
|
||||
fi
|
||||
|
||||
if [ -z "$react_pids" ] && [ -z "$webpack_pids" ]; then
|
||||
echo -e "${GREEN}✓ No development servers found${NC}"
|
||||
fi
|
||||
}
|
||||
|
||||
# Main execution
|
||||
echo "Starting port cleanup..."
|
||||
echo ""
|
||||
|
||||
cleanup_port $BACKEND_PORT "Backend API"
|
||||
echo ""
|
||||
cleanup_port $FRONTEND_PORT "Frontend Server"
|
||||
echo ""
|
||||
cleanup_pid_files
|
||||
echo ""
|
||||
cleanup_dev_servers
|
||||
|
||||
echo ""
|
||||
echo "╔════════════════════════════════════════════════════════════════╗"
|
||||
echo "║ CLEANUP COMPLETE ║"
|
||||
echo "╚════════════════════════════════════════════════════════════════╝"
|
||||
echo ""
|
||||
echo "You can now start the services:"
|
||||
echo " sudo systemctl start church-music-backend"
|
||||
echo " sudo systemctl start church-music-frontend"
|
||||
echo ""
|
||||
86
legacy-site/scripts/shell/deploy-production.sh
Executable file
86
legacy-site/scripts/shell/deploy-production.sh
Executable file
@@ -0,0 +1,86 @@
|
||||
#!/bin/bash
|
||||
# Production Deployment Script for Church Music System
|
||||
# This script will set up auto-start services and optimize for production
|
||||
|
||||
set -e
|
||||
|
||||
echo "🚀 Starting production deployment..."
|
||||
|
||||
# Colors for output
|
||||
GREEN='\033[0;32m'
|
||||
BLUE='\033[0;34m'
|
||||
RED='\033[0;31m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
PROJECT_DIR="/media/pts/Website/Church_HOP_MusicData"
|
||||
BACKEND_DIR="$PROJECT_DIR/backend"
|
||||
FRONTEND_DIR="$PROJECT_DIR/frontend"
|
||||
|
||||
# Step 1: Stop current development servers
|
||||
echo -e "${BLUE}[1/7] Stopping development servers...${NC}"
|
||||
pkill -f "python.*app.py" 2>/dev/null || true
|
||||
pkill -f "node.*react-scripts" 2>/dev/null || true
|
||||
sleep 2
|
||||
|
||||
# Step 2: Build production frontend
|
||||
echo -e "${BLUE}[2/7] Building production React frontend...${NC}"
|
||||
cd $FRONTEND_DIR
|
||||
export NODE_OPTIONS=--max-old-space-size=2048
|
||||
npm run build || {
|
||||
echo -e "${RED}Frontend build failed. Check for syntax errors.${NC}"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Step 3: Install systemd service for backend
|
||||
echo -e "${BLUE}[3/7] Installing backend systemd service...${NC}"
|
||||
sudo cp /tmp/church-music-backend.service /etc/systemd/system/
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable church-music-backend.service
|
||||
sudo systemctl restart church-music-backend.service
|
||||
|
||||
# Step 4: Install Nginx configuration
|
||||
echo -e "${BLUE}[4/7] Installing Nginx configuration...${NC}"
|
||||
sudo apt-get install -y nginx 2>/dev/null || true
|
||||
sudo cp /tmp/church-music-nginx.conf /etc/nginx/sites-available/church-music
|
||||
sudo ln -sf /etc/nginx/sites-available/church-music /etc/nginx/sites-enabled/
|
||||
sudo nginx -t || {
|
||||
echo -e "${RED}Nginx configuration test failed${NC}"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Step 5: Start/restart services
|
||||
echo -e "${BLUE}[5/7] Starting services...${NC}"
|
||||
sudo systemctl enable nginx
|
||||
sudo systemctl restart nginx
|
||||
sudo systemctl status church-music-backend.service --no-pager || true
|
||||
|
||||
# Step 6: Verify PostgreSQL data
|
||||
echo -e "${BLUE}[6/7] Verifying PostgreSQL connection...${NC}"
|
||||
cd $BACKEND_DIR
|
||||
source venv/bin/activate
|
||||
python -c "from postgresql_models import SessionLocal; s = SessionLocal(); print('✅ PostgreSQL connected'); s.close()" || {
|
||||
echo -e "${RED}PostgreSQL connection failed${NC}"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Step 7: Display status
|
||||
echo -e "${BLUE}[7/7] Deployment complete!${NC}"
|
||||
echo ""
|
||||
echo -e "${GREEN}✅ Production services are running:${NC}"
|
||||
echo " • Backend: sudo systemctl status church-music-backend"
|
||||
echo " • Frontend: sudo systemctl status nginx"
|
||||
echo ""
|
||||
echo -e "${GREEN}✅ Access your site:${NC}"
|
||||
echo " • Local: http://localhost:3000"
|
||||
echo " • Network: http://192.168.10.130:3000"
|
||||
echo " • External: http://houseofprayer.ddns.net:3000"
|
||||
echo ""
|
||||
echo -e "${GREEN}✅ Services will auto-start on system restart${NC}"
|
||||
echo ""
|
||||
echo -e "${GREEN}✅ Resource optimized for shared server:${NC}"
|
||||
echo " • Backend: 512MB RAM, 50% CPU"
|
||||
echo " • Nginx: Gzip enabled, caching configured"
|
||||
echo ""
|
||||
echo "Logs:"
|
||||
echo " • Backend: $BACKEND_DIR/logs/"
|
||||
echo " • Nginx: /var/log/nginx/church-music-*.log"
|
||||
75
legacy-site/scripts/shell/kill-dev-servers.sh
Executable file
75
legacy-site/scripts/shell/kill-dev-servers.sh
Executable file
@@ -0,0 +1,75 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Kill All Development Servers Script
|
||||
# Ensures no development servers (react-scripts, webpack-dev-server) are running
|
||||
# This should be run before starting production services
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
echo "=========================================="
|
||||
echo "Killing all development servers..."
|
||||
echo "=========================================="
|
||||
|
||||
# Kill react-scripts (development server)
|
||||
echo "Checking for react-scripts processes..."
|
||||
REACT_PIDS=$(pgrep -f "react-scripts" || true)
|
||||
if [ -n "$REACT_PIDS" ]; then
|
||||
echo "Found react-scripts processes: $REACT_PIDS"
|
||||
pkill -9 -f "react-scripts" || true
|
||||
echo "✓ Killed react-scripts"
|
||||
else
|
||||
echo "✓ No react-scripts processes found"
|
||||
fi
|
||||
|
||||
# Kill webpack-dev-server
|
||||
echo "Checking for webpack-dev-server processes..."
|
||||
WEBPACK_PIDS=$(pgrep -f "webpack-dev-server" || true)
|
||||
if [ -n "$WEBPACK_PIDS" ]; then
|
||||
echo "Found webpack-dev-server processes: $WEBPACK_PIDS"
|
||||
pkill -9 -f "webpack-dev-server" || true
|
||||
echo "✓ Killed webpack-dev-server"
|
||||
else
|
||||
echo "✓ No webpack-dev-server processes found"
|
||||
fi
|
||||
|
||||
# Kill any Python dev servers (app.py running directly, NOT gunicorn)
|
||||
echo "Checking for Python dev servers..."
|
||||
# Only kill python processes running app.py directly, NOT gunicorn workers
|
||||
for pid in $(pgrep -f "python.*app\.py" || true); do
|
||||
CMD=$(ps -p $pid -o args= 2>/dev/null || true)
|
||||
# Skip if it's a gunicorn worker
|
||||
if echo "$CMD" | grep -q "gunicorn"; then
|
||||
echo "Skipping gunicorn process: $pid"
|
||||
continue
|
||||
fi
|
||||
# Kill if it's a direct python app.py process
|
||||
if echo "$CMD" | grep -q "python.*app\.py"; then
|
||||
echo "Killing Python dev server: $pid ($CMD)"
|
||||
kill -9 $pid 2>/dev/null || true
|
||||
fi
|
||||
done
|
||||
echo "✓ Python dev server check complete"
|
||||
|
||||
# Wait for ports to be released
|
||||
echo "Waiting for ports to be released..."
|
||||
sleep 1
|
||||
|
||||
# Verify port 5100 is free (except for production serve)
|
||||
PORT_5100=$(lsof -i :5100 2>/dev/null | grep -v "serve" || true)
|
||||
if [ -n "$PORT_5100" ]; then
|
||||
echo "⚠ Warning: Port 5100 in use by non-serve process"
|
||||
echo "$PORT_5100"
|
||||
# Only kill non-serve processes on port 5100
|
||||
lsof -i :5100 2>/dev/null | grep -v -E "serve|COMMAND" | awk '{print $2}' | xargs -r kill -9 || true
|
||||
sleep 1
|
||||
else
|
||||
echo "✓ Port 5100 is free or only used by serve"
|
||||
fi
|
||||
|
||||
echo "=========================================="
|
||||
echo "✓ All development servers killed"
|
||||
echo "✓ Ports verified (production services preserved)"
|
||||
echo "=========================================="
|
||||
|
||||
exit 0
|
||||
115
legacy-site/scripts/shell/manage-services.sh
Executable file
115
legacy-site/scripts/shell/manage-services.sh
Executable file
@@ -0,0 +1,115 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Church Music Database - Service Management Script
|
||||
# Convenient wrapper for managing systemd services
|
||||
#
|
||||
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
RED='\033[0;31m'
|
||||
NC='\033[0m'
|
||||
|
||||
BACKEND="church-music-backend"
|
||||
FRONTEND="church-music-frontend"
|
||||
|
||||
show_help() {
|
||||
echo -e "${GREEN}Church Music Database - Service Manager${NC}"
|
||||
echo ""
|
||||
echo "Usage: $0 [COMMAND]"
|
||||
echo ""
|
||||
echo "Commands:"
|
||||
echo " status - Show status of both services"
|
||||
echo " start - Start both services"
|
||||
echo " stop - Stop both services"
|
||||
echo " restart - Restart both services"
|
||||
echo " logs - Show live logs (backend)"
|
||||
echo " logs-fe - Show live logs (frontend)"
|
||||
echo " enable - Enable auto-start on boot"
|
||||
echo " disable - Disable auto-start on boot"
|
||||
echo " health - Check if services are responding"
|
||||
echo ""
|
||||
echo "Examples:"
|
||||
echo " $0 status"
|
||||
echo " $0 restart"
|
||||
echo " $0 logs"
|
||||
echo ""
|
||||
}
|
||||
|
||||
check_health() {
|
||||
echo -e "${YELLOW}Checking service health...${NC}"
|
||||
echo ""
|
||||
|
||||
# Check backend
|
||||
if curl -s http://localhost:8080/api/health > /dev/null 2>&1; then
|
||||
echo -e "${GREEN}✓ Backend API (port 8080): HEALTHY${NC}"
|
||||
else
|
||||
echo -e "${RED}✗ Backend API (port 8080): NOT RESPONDING${NC}"
|
||||
fi
|
||||
|
||||
# Check frontend
|
||||
if curl -s http://localhost:5100 > /dev/null 2>&1; then
|
||||
echo -e "${GREEN}✓ Frontend (port 5100): HEALTHY${NC}"
|
||||
else
|
||||
echo -e "${RED}✗ Frontend (port 5100): NOT RESPONDING${NC}"
|
||||
fi
|
||||
echo ""
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
status)
|
||||
echo -e "${GREEN}=== Backend Service ===${NC}"
|
||||
sudo systemctl status $BACKEND --no-pager -l
|
||||
echo ""
|
||||
echo -e "${GREEN}=== Frontend Service ===${NC}"
|
||||
sudo systemctl status $FRONTEND --no-pager -l
|
||||
;;
|
||||
start)
|
||||
echo -e "${YELLOW}Starting services...${NC}"
|
||||
sudo systemctl start $BACKEND
|
||||
sudo systemctl start $FRONTEND
|
||||
sleep 2
|
||||
echo -e "${GREEN}✓ Services started${NC}"
|
||||
check_health
|
||||
;;
|
||||
stop)
|
||||
echo -e "${YELLOW}Stopping services...${NC}"
|
||||
sudo systemctl stop $BACKEND
|
||||
sudo systemctl stop $FRONTEND
|
||||
echo -e "${GREEN}✓ Services stopped${NC}"
|
||||
;;
|
||||
restart)
|
||||
echo -e "${YELLOW}Restarting services...${NC}"
|
||||
sudo systemctl restart $BACKEND
|
||||
sudo systemctl restart $FRONTEND
|
||||
sleep 2
|
||||
echo -e "${GREEN}✓ Services restarted${NC}"
|
||||
check_health
|
||||
;;
|
||||
logs)
|
||||
echo -e "${GREEN}Showing backend logs (Ctrl+C to exit)...${NC}"
|
||||
sudo journalctl -u $BACKEND -f --no-pager
|
||||
;;
|
||||
logs-fe)
|
||||
echo -e "${GREEN}Showing frontend logs (Ctrl+C to exit)...${NC}"
|
||||
sudo journalctl -u $FRONTEND -f --no-pager
|
||||
;;
|
||||
enable)
|
||||
echo -e "${YELLOW}Enabling auto-start on boot...${NC}"
|
||||
sudo systemctl enable $BACKEND
|
||||
sudo systemctl enable $FRONTEND
|
||||
echo -e "${GREEN}✓ Services will start automatically on boot${NC}"
|
||||
;;
|
||||
disable)
|
||||
echo -e "${YELLOW}Disabling auto-start on boot...${NC}"
|
||||
sudo systemctl disable $BACKEND
|
||||
sudo systemctl disable $FRONTEND
|
||||
echo -e "${GREEN}✓ Auto-start disabled${NC}"
|
||||
;;
|
||||
health)
|
||||
check_health
|
||||
;;
|
||||
*)
|
||||
show_help
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
22
legacy-site/scripts/shell/setup-boot-cleanup.sh
Executable file
22
legacy-site/scripts/shell/setup-boot-cleanup.sh
Executable file
@@ -0,0 +1,22 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Setup automatic cleanup of development servers on boot
|
||||
# This ensures production services start cleanly
|
||||
#
|
||||
|
||||
echo "Setting up boot-time development server cleanup..."
|
||||
|
||||
# Add to user's crontab
|
||||
(crontab -l 2>/dev/null | grep -v "kill-dev-servers.sh"; echo "@reboot sleep 10 && /media/pts/Website/Church_HOP_MusicData/kill-dev-servers.sh > /tmp/kill-dev-servers.log 2>&1") | crontab -
|
||||
|
||||
echo "✓ Added @reboot cron job to kill development servers"
|
||||
|
||||
# Verify
|
||||
echo ""
|
||||
echo "Current crontab:"
|
||||
crontab -l | grep -E "(@reboot|kill-dev)"
|
||||
|
||||
echo ""
|
||||
echo "✓ Setup complete!"
|
||||
echo ""
|
||||
echo "This will run automatically on every system reboot."
|
||||
144
legacy-site/scripts/shell/setup-nginx.sh
Executable file
144
legacy-site/scripts/shell/setup-nginx.sh
Executable file
@@ -0,0 +1,144 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Church Music Database - Nginx Setup Script
|
||||
# Configures Nginx reverse proxy for houseofprayer.ddns.net
|
||||
#
|
||||
# Usage: sudo ./setup-nginx.sh
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
# Colors
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
RED='\033[0;31m'
|
||||
NC='\033[0m'
|
||||
|
||||
# Check if running as root
|
||||
if [ "$EUID" -ne 0 ]; then
|
||||
echo -e "${RED}Error: This script must be run as root (use sudo)${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "${GREEN}========================================${NC}"
|
||||
echo -e "${GREEN}Church Music Database - Nginx Setup${NC}"
|
||||
echo -e "${GREEN}========================================${NC}"
|
||||
echo ""
|
||||
|
||||
PROJECT_DIR="/media/pts/Website/Church_HOP_MusicData"
|
||||
NGINX_CONF="$PROJECT_DIR/nginx-http.conf"
|
||||
SITES_AVAILABLE="/etc/nginx/sites-available/church-music"
|
||||
SITES_ENABLED="/etc/nginx/sites-enabled/church-music"
|
||||
|
||||
# Step 1: Check if services are running
|
||||
echo -e "${YELLOW}[1/7] Checking if backend and frontend services are running...${NC}"
|
||||
if ! systemctl is-active --quiet church-music-backend; then
|
||||
echo -e "${RED}Error: Backend service is not running!${NC}"
|
||||
echo "Start it with: sudo systemctl start church-music-backend"
|
||||
exit 1
|
||||
fi
|
||||
if ! systemctl is-active --quiet church-music-frontend; then
|
||||
echo -e "${RED}Error: Frontend service is not running!${NC}"
|
||||
echo "Start it with: sudo systemctl start church-music-frontend"
|
||||
exit 1
|
||||
fi
|
||||
echo -e "${GREEN}✓ Backend and frontend services are running${NC}"
|
||||
echo ""
|
||||
|
||||
# Step 2: Backup existing nginx config (if exists)
|
||||
echo -e "${YELLOW}[2/7] Backing up existing nginx configuration...${NC}"
|
||||
if [ -f "$SITES_AVAILABLE" ]; then
|
||||
cp "$SITES_AVAILABLE" "$SITES_AVAILABLE.backup.$(date +%Y%m%d_%H%M%S)"
|
||||
echo -e "${GREEN}✓ Backup created${NC}"
|
||||
else
|
||||
echo -e "${GREEN}✓ No existing config to backup${NC}"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Step 3: Remove default nginx site
|
||||
echo -e "${YELLOW}[3/7] Removing default nginx site...${NC}"
|
||||
if [ -L "/etc/nginx/sites-enabled/default" ]; then
|
||||
rm /etc/nginx/sites-enabled/default
|
||||
echo -e "${GREEN}✓ Default site removed${NC}"
|
||||
else
|
||||
echo -e "${GREEN}✓ Default site not present${NC}"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Step 4: Copy nginx configuration
|
||||
echo -e "${YELLOW}[4/7] Installing nginx configuration...${NC}"
|
||||
cp "$NGINX_CONF" "$SITES_AVAILABLE"
|
||||
chmod 644 "$SITES_AVAILABLE"
|
||||
echo -e "${GREEN}✓ Configuration copied to $SITES_AVAILABLE${NC}"
|
||||
echo ""
|
||||
|
||||
# Step 5: Create symbolic link
|
||||
echo -e "${YELLOW}[5/7] Enabling site configuration...${NC}"
|
||||
if [ -L "$SITES_ENABLED" ]; then
|
||||
rm "$SITES_ENABLED"
|
||||
fi
|
||||
ln -s "$SITES_AVAILABLE" "$SITES_ENABLED"
|
||||
echo -e "${GREEN}✓ Site enabled${NC}"
|
||||
echo ""
|
||||
|
||||
# Step 6: Test nginx configuration
|
||||
echo -e "${YELLOW}[6/7] Testing nginx configuration...${NC}"
|
||||
if nginx -t; then
|
||||
echo -e "${GREEN}✓ Nginx configuration is valid${NC}"
|
||||
else
|
||||
echo -e "${RED}✗ Nginx configuration has errors!${NC}"
|
||||
exit 1
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Step 7: Restart nginx
|
||||
echo -e "${YELLOW}[7/7] Restarting nginx...${NC}"
|
||||
systemctl restart nginx
|
||||
systemctl enable nginx
|
||||
sleep 2
|
||||
echo -e "${GREEN}✓ Nginx restarted and enabled${NC}"
|
||||
echo ""
|
||||
|
||||
# Verify nginx is running
|
||||
if systemctl is-active --quiet nginx; then
|
||||
echo -e "${GREEN}========================================${NC}"
|
||||
echo -e "${GREEN}Nginx Setup Complete!${NC}"
|
||||
echo -e "${GREEN}========================================${NC}"
|
||||
echo ""
|
||||
echo -e "${GREEN}✓ Your site is now accessible at:${NC}"
|
||||
echo -e "${GREEN} http://houseofprayer.ddns.net${NC}"
|
||||
echo ""
|
||||
echo -e "${YELLOW}Testing endpoints:${NC}"
|
||||
echo ""
|
||||
|
||||
# Test health endpoint
|
||||
if curl -s http://localhost/api/health > /dev/null; then
|
||||
echo -e "${GREEN}✓ Backend API: Working${NC}"
|
||||
else
|
||||
echo -e "${RED}✗ Backend API: Not responding${NC}"
|
||||
fi
|
||||
|
||||
if curl -s http://localhost/ > /dev/null; then
|
||||
echo -e "${GREEN}✓ Frontend: Working${NC}"
|
||||
else
|
||||
echo -e "${RED}✗ Frontend: Not responding${NC}"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo -e "${YELLOW}Important:${NC}"
|
||||
echo "1. Make sure port 80 is forwarded on your router to this server"
|
||||
echo "2. Your DNS houseofprayer.ddns.net should point to your public IP"
|
||||
echo "3. Test from outside: http://houseofprayer.ddns.net"
|
||||
echo ""
|
||||
echo -e "${YELLOW}Commands:${NC}"
|
||||
echo " sudo systemctl status nginx"
|
||||
echo " sudo systemctl restart nginx"
|
||||
echo " sudo nginx -t # Test configuration"
|
||||
echo " sudo tail -f /var/log/nginx/church-music-access.log"
|
||||
echo " sudo tail -f /var/log/nginx/church-music-error.log"
|
||||
echo ""
|
||||
else
|
||||
echo -e "${RED}✗ Nginx failed to start!${NC}"
|
||||
echo "Check logs: sudo journalctl -u nginx -n 50"
|
||||
exit 1
|
||||
fi
|
||||
82
legacy-site/scripts/shell/start-dev-mode.sh
Executable file
82
legacy-site/scripts/shell/start-dev-mode.sh
Executable file
@@ -0,0 +1,82 @@
|
||||
#!/bin/bash
|
||||
# Auto-start script for Church Music System Development Mode
|
||||
# Ensures all features work with hot-reload
|
||||
|
||||
set -e
|
||||
|
||||
PROJECT_DIR="/media/pts/Website/Church_HOP_MusicData"
|
||||
BACKEND_DIR="$PROJECT_DIR/backend"
|
||||
FRONTEND_DIR="$PROJECT_DIR/frontend"
|
||||
|
||||
# WARNING: Check if production services are running
|
||||
echo "╔════════════════════════════════════════════════════════════════╗"
|
||||
echo "║ Church Music System - Development Mode ║"
|
||||
echo "╚════════════════════════════════════════════════════════════════╝"
|
||||
echo ""
|
||||
|
||||
# Check if systemd services are running
|
||||
if systemctl is-active --quiet church-music-backend.service; then
|
||||
echo "⚠️ WARNING: Production backend service is running!"
|
||||
echo " This will cause port conflicts (port 8080)"
|
||||
echo ""
|
||||
read -p " Stop production services and continue? [y/N] " -n 1 -r
|
||||
echo
|
||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||
sudo systemctl stop church-music-backend.service
|
||||
sudo systemctl stop church-music-frontend.service
|
||||
echo "✓ Production services stopped"
|
||||
else
|
||||
echo "❌ Cancelled. Stop services manually or use production mode."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check for existing dev processes
|
||||
if [ -f /tmp/church-backend.pid ]; then
|
||||
OLD_PID=$(cat /tmp/church-backend.pid)
|
||||
if ps -p $OLD_PID > /dev/null 2>&1; then
|
||||
echo "⚠️ Killing old backend process (PID: $OLD_PID)"
|
||||
kill -9 $OLD_PID 2>/dev/null || true
|
||||
fi
|
||||
rm /tmp/church-backend.pid
|
||||
fi
|
||||
|
||||
if [ -f /tmp/church-frontend.pid ]; then
|
||||
OLD_PID=$(cat /tmp/church-frontend.pid)
|
||||
if ps -p $OLD_PID > /dev/null 2>&1; then
|
||||
echo "⚠️ Killing old frontend process (PID: $OLD_PID)"
|
||||
kill -9 $OLD_PID 2>/dev/null || true
|
||||
fi
|
||||
rm /tmp/church-frontend.pid
|
||||
fi
|
||||
|
||||
# Start backend
|
||||
echo ""
|
||||
echo "Starting backend in development mode..."
|
||||
cd $BACKEND_DIR
|
||||
source venv/bin/activate
|
||||
python app.py > /tmp/church-backend.log 2>&1 &
|
||||
echo $! > /tmp/church-backend.pid
|
||||
echo "✓ Backend started (PID: $(cat /tmp/church-backend.pid))"
|
||||
|
||||
# Wait for backend
|
||||
sleep 3
|
||||
|
||||
# Start frontend on port 5100
|
||||
echo "Starting frontend in development mode..."
|
||||
cd $FRONTEND_DIR
|
||||
PORT=5100 npm start > /tmp/church-frontend.log 2>&1 &
|
||||
echo $! > /tmp/church-frontend.pid
|
||||
echo "✓ Frontend started (PID: $(cat /tmp/church-frontend.pid))"
|
||||
|
||||
echo ""
|
||||
echo "╔════════════════════════════════════════════════════════════════╗"
|
||||
echo "║ ✅ Church Music System running in DEVELOPMENT mode ║"
|
||||
echo "║ ║"
|
||||
echo "║ Frontend: http://localhost:5100 ║"
|
||||
echo "║ Backend: http://localhost:8080 ║"
|
||||
echo "║ ║"
|
||||
echo "║ To stop: ./stop-dev-mode.sh ║"
|
||||
echo "║ View logs: tail -f /tmp/church-*.log ║"
|
||||
echo "╚════════════════════════════════════════════════════════════════╝"
|
||||
echo ""
|
||||
134
legacy-site/scripts/shell/start-production.sh
Executable file
134
legacy-site/scripts/shell/start-production.sh
Executable file
@@ -0,0 +1,134 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Complete Church Music Database Startup Script
|
||||
# Ensures clean startup with no conflicts
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
echo "=========================================="
|
||||
echo "Church Music Database - Startup Script"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
|
||||
# Step 1: Kill all development servers
|
||||
echo "Step 1: Cleaning up development servers..."
|
||||
/media/pts/Website/Church_HOP_MusicData/kill-dev-servers.sh
|
||||
echo ""
|
||||
|
||||
# Step 2: Stop any running production services
|
||||
echo "Step 2: Stopping existing production services..."
|
||||
sudo systemctl stop church-music-frontend.service church-music-backend.service 2>/dev/null || true
|
||||
sleep 2
|
||||
echo "✓ Services stopped"
|
||||
echo ""
|
||||
|
||||
# Step 3: Verify ports are free
|
||||
echo "Step 3: Verifying ports..."
|
||||
if lsof -i :8080 > /dev/null 2>&1; then
|
||||
echo "⚠ Port 8080 still in use, force killing..."
|
||||
sudo lsof -i :8080 -t | xargs -r sudo kill -9 || true
|
||||
sleep 1
|
||||
fi
|
||||
if lsof -i :5100 > /dev/null 2>&1; then
|
||||
echo "⚠ Port 5100 still in use, force killing..."
|
||||
sudo lsof -i :5100 -t | xargs -r sudo kill -9 || true
|
||||
sleep 1
|
||||
fi
|
||||
echo "✓ Ports 8080 and 5100 are free"
|
||||
echo ""
|
||||
|
||||
# Step 4: Reset failed services
|
||||
echo "Step 4: Resetting service states..."
|
||||
sudo systemctl reset-failed 2>/dev/null || true
|
||||
echo "✓ Service states reset"
|
||||
echo ""
|
||||
|
||||
# Step 5: Start production services
|
||||
echo "Step 5: Starting production services..."
|
||||
sudo systemctl start church-music-backend.service
|
||||
sleep 3
|
||||
sudo systemctl start church-music-frontend.service
|
||||
sleep 2
|
||||
echo "✓ Services started"
|
||||
echo ""
|
||||
|
||||
# Step 6: Verify services are running
|
||||
echo "Step 6: Verifying services..."
|
||||
echo ""
|
||||
|
||||
if sudo systemctl is-active --quiet church-music-backend.service; then
|
||||
echo "✅ Backend service: RUNNING"
|
||||
else
|
||||
echo "❌ Backend service: FAILED"
|
||||
sudo systemctl status church-music-backend.service --no-pager -l
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if sudo systemctl is-active --quiet church-music-frontend.service; then
|
||||
echo "✅ Frontend service: RUNNING"
|
||||
else
|
||||
echo "❌ Frontend service: FAILED"
|
||||
sudo systemctl status church-music-frontend.service --no-pager -l
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Step 7: Test endpoints
|
||||
echo ""
|
||||
echo "Step 7: Testing endpoints..."
|
||||
echo ""
|
||||
|
||||
BACKEND_TEST=$(curl -s http://localhost:8080/api/health | grep -o "ok" || echo "")
|
||||
if [ "$BACKEND_TEST" = "ok" ]; then
|
||||
echo "✅ Backend API: RESPONDING (http://localhost:8080/api/health)"
|
||||
else
|
||||
echo "❌ Backend API: NOT RESPONDING"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
FRONTEND_TEST=$(curl -s http://localhost:5100/ | grep -o "House of Prayer" || echo "")
|
||||
if [ -n "$FRONTEND_TEST" ]; then
|
||||
echo "✅ Frontend: RESPONDING (http://localhost:5100/)"
|
||||
else
|
||||
echo "❌ Frontend: NOT RESPONDING"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Step 8: Check auto-start configuration
|
||||
echo ""
|
||||
echo "Step 8: Verifying auto-start configuration..."
|
||||
echo ""
|
||||
|
||||
if systemctl is-enabled --quiet church-music-backend.service; then
|
||||
echo "✅ Backend auto-start: ENABLED"
|
||||
else
|
||||
echo "⚠ Backend auto-start: DISABLED"
|
||||
fi
|
||||
|
||||
if systemctl is-enabled --quiet church-music-frontend.service; then
|
||||
echo "✅ Frontend auto-start: ENABLED"
|
||||
else
|
||||
echo "⚠ Frontend auto-start: DISABLED"
|
||||
fi
|
||||
|
||||
# Step 9: Display status
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
echo "✅ ALL SYSTEMS OPERATIONAL"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
echo "Services Status:"
|
||||
sudo systemctl status church-music-backend.service church-music-frontend.service --no-pager | grep -E "(Active:|Main PID:|Tasks:|Memory:)"
|
||||
echo ""
|
||||
echo "Access URLs:"
|
||||
echo " Backend API: http://localhost:8080/api/health"
|
||||
echo " Frontend: http://localhost:5100/"
|
||||
echo " Public HTTPS: https://houseofprayer.ddns.net/"
|
||||
echo ""
|
||||
echo "Logs:"
|
||||
echo " Backend: journalctl -u church-music-backend.service -f"
|
||||
echo " Frontend: journalctl -u church-music-frontend.service -f"
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
|
||||
exit 0
|
||||
31
legacy-site/scripts/shell/stop-dev-mode.sh
Executable file
31
legacy-site/scripts/shell/stop-dev-mode.sh
Executable file
@@ -0,0 +1,31 @@
|
||||
#!/bin/bash
|
||||
# Stop development mode processes
|
||||
|
||||
echo "Stopping Church Music System development processes..."
|
||||
|
||||
# Stop backend
|
||||
if [ -f /tmp/church-backend.pid ]; then
|
||||
PID=$(cat /tmp/church-backend.pid)
|
||||
if ps -p $PID > /dev/null 2>&1; then
|
||||
kill $PID
|
||||
echo "✓ Backend stopped (PID: $PID)"
|
||||
fi
|
||||
rm /tmp/church-backend.pid
|
||||
fi
|
||||
|
||||
# Stop frontend
|
||||
if [ -f /tmp/church-frontend.pid ]; then
|
||||
PID=$(cat /tmp/church-frontend.pid)
|
||||
if ps -p $PID > /dev/null 2>&1; then
|
||||
kill $PID
|
||||
echo "✓ Frontend stopped (PID: $PID)"
|
||||
fi
|
||||
rm /tmp/church-frontend.pid
|
||||
fi
|
||||
|
||||
# Also kill any stray processes
|
||||
pkill -f "python app.py" 2>/dev/null || true
|
||||
pkill -f "react-scripts start" 2>/dev/null || true
|
||||
pkill -9 -f "webpack-dev-server" 2>/dev/null || true
|
||||
|
||||
echo "✅ Development mode stopped"
|
||||
121
legacy-site/scripts/shell/systemd-setup.sh
Executable file
121
legacy-site/scripts/shell/systemd-setup.sh
Executable file
@@ -0,0 +1,121 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Church Music Database - Systemd Setup Script
|
||||
# This script installs and enables systemd services for automatic startup
|
||||
#
|
||||
# Usage: sudo ./systemd-setup.sh
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Check if running as root
|
||||
if [ "$EUID" -ne 0 ]; then
|
||||
echo -e "${RED}Error: This script must be run as root (use sudo)${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "${GREEN}========================================${NC}"
|
||||
echo -e "${GREEN}Church Music Database - Systemd Setup${NC}"
|
||||
echo -e "${GREEN}========================================${NC}"
|
||||
echo ""
|
||||
|
||||
PROJECT_DIR="/media/pts/Website/Church_HOP_MusicData"
|
||||
BACKEND_SERVICE="church-music-backend.service"
|
||||
FRONTEND_SERVICE="church-music-frontend.service"
|
||||
SYSTEMD_DIR="/etc/systemd/system"
|
||||
|
||||
# Step 1: Stop any existing instances
|
||||
echo -e "${YELLOW}[1/7] Stopping existing services (if running)...${NC}"
|
||||
systemctl stop $BACKEND_SERVICE 2>/dev/null || true
|
||||
systemctl stop $FRONTEND_SERVICE 2>/dev/null || true
|
||||
echo -e "${GREEN}✓ Existing services stopped${NC}"
|
||||
echo ""
|
||||
|
||||
# Step 2: Build frontend production files
|
||||
echo -e "${YELLOW}[2/7] Building frontend production files...${NC}"
|
||||
cd $PROJECT_DIR/frontend
|
||||
sudo -u pts npm run build
|
||||
echo -e "${GREEN}✓ Frontend built successfully${NC}"
|
||||
echo ""
|
||||
|
||||
# Step 3: Copy service files to systemd directory
|
||||
echo -e "${YELLOW}[3/7] Installing systemd service files...${NC}"
|
||||
cp $PROJECT_DIR/$BACKEND_SERVICE $SYSTEMD_DIR/
|
||||
cp $PROJECT_DIR/$FRONTEND_SERVICE $SYSTEMD_DIR/
|
||||
chmod 644 $SYSTEMD_DIR/$BACKEND_SERVICE
|
||||
chmod 644 $SYSTEMD_DIR/$FRONTEND_SERVICE
|
||||
echo -e "${GREEN}✓ Service files installed${NC}"
|
||||
echo ""
|
||||
|
||||
# Step 4: Reload systemd daemon
|
||||
echo -e "${YELLOW}[4/7] Reloading systemd daemon...${NC}"
|
||||
systemctl daemon-reload
|
||||
echo -e "${GREEN}✓ Systemd daemon reloaded${NC}"
|
||||
echo ""
|
||||
|
||||
# Step 5: Enable services (start on boot)
|
||||
echo -e "${YELLOW}[5/7] Enabling services for automatic startup...${NC}"
|
||||
systemctl enable $BACKEND_SERVICE
|
||||
systemctl enable $FRONTEND_SERVICE
|
||||
echo -e "${GREEN}✓ Services enabled for automatic startup${NC}"
|
||||
echo ""
|
||||
|
||||
# Step 6: Start services
|
||||
echo -e "${YELLOW}[6/7] Starting services...${NC}"
|
||||
systemctl start $BACKEND_SERVICE
|
||||
sleep 3
|
||||
systemctl start $FRONTEND_SERVICE
|
||||
sleep 2
|
||||
echo -e "${GREEN}✓ Services started${NC}"
|
||||
echo ""
|
||||
|
||||
# Step 7: Verify status
|
||||
echo -e "${YELLOW}[7/7] Verifying service status...${NC}"
|
||||
echo ""
|
||||
echo -e "${GREEN}Backend Service Status:${NC}"
|
||||
systemctl status $BACKEND_SERVICE --no-pager -l || true
|
||||
echo ""
|
||||
echo -e "${GREEN}Frontend Service Status:${NC}"
|
||||
systemctl status $FRONTEND_SERVICE --no-pager -l || true
|
||||
echo ""
|
||||
|
||||
# Final summary
|
||||
echo -e "${GREEN}========================================${NC}"
|
||||
echo -e "${GREEN}Installation Complete!${NC}"
|
||||
echo -e "${GREEN}========================================${NC}"
|
||||
echo ""
|
||||
echo -e "${GREEN}Services installed and started successfully!${NC}"
|
||||
echo ""
|
||||
echo -e "${YELLOW}Quick Reference Commands:${NC}"
|
||||
echo ""
|
||||
echo " # Check status"
|
||||
echo " sudo systemctl status church-music-backend"
|
||||
echo " sudo systemctl status church-music-frontend"
|
||||
echo ""
|
||||
echo " # View logs"
|
||||
echo " sudo journalctl -u church-music-backend -f"
|
||||
echo " sudo journalctl -u church-music-frontend -f"
|
||||
echo ""
|
||||
echo " # Restart services"
|
||||
echo " sudo systemctl restart church-music-backend"
|
||||
echo " sudo systemctl restart church-music-frontend"
|
||||
echo ""
|
||||
echo " # Stop services"
|
||||
echo " sudo systemctl stop church-music-backend"
|
||||
echo " sudo systemctl stop church-music-frontend"
|
||||
echo ""
|
||||
echo " # Disable auto-start"
|
||||
echo " sudo systemctl disable church-music-backend"
|
||||
echo " sudo systemctl disable church-music-frontend"
|
||||
echo ""
|
||||
echo -e "${GREEN}Backend API: http://localhost:8080${NC}"
|
||||
echo -e "${GREEN}Frontend UI: http://localhost:5100${NC}"
|
||||
echo ""
|
||||
echo -e "${YELLOW}Note: Services will automatically start on every reboot${NC}"
|
||||
echo ""
|
||||
78
legacy-site/scripts/shell/test-mobile-features.sh
Executable file
78
legacy-site/scripts/shell/test-mobile-features.sh
Executable file
@@ -0,0 +1,78 @@
|
||||
#!/bin/bash
|
||||
echo "🎵 HOUSE OF PRAYER MUSIC APP - MOBILE FEATURES TEST"
|
||||
echo "=================================================="
|
||||
echo ""
|
||||
|
||||
echo "1️⃣ Testing Login System..."
|
||||
echo " - Login page exists: ✅"
|
||||
echo " - Password encryption: SHA-256 ✅"
|
||||
echo " - Session management: SessionStorage ✅"
|
||||
echo " - Password reset: Available ✅"
|
||||
echo ""
|
||||
|
||||
echo "2️⃣ Testing Mobile Swipe Navigation..."
|
||||
echo " - Right swipe (back gesture): ✅ Implemented"
|
||||
echo " - Touch start/move/end handlers: ✅ Active"
|
||||
echo " - Browser back button support: ✅ Configured"
|
||||
echo " - iOS/Android compatible: ✅ Yes"
|
||||
echo ""
|
||||
|
||||
echo "3️⃣ Testing Song Database Mobile View..."
|
||||
SONG_COUNT=$(curl -s "http://localhost:8080/api/songs" | python3 -c "import sys, json; print(len(json.load(sys.stdin)))" 2>/dev/null || echo "?")
|
||||
echo " - Total songs in database: ${SONG_COUNT}"
|
||||
echo " - Mobile grid layout: 3 columns ✅"
|
||||
echo " - Responsive font sizing: clamp() ✅"
|
||||
echo " - Touch-optimized cards: ✅"
|
||||
echo " - Swipe to close modals: ✅"
|
||||
echo ""
|
||||
|
||||
echo "4️⃣ Testing API Endpoints..."
|
||||
# Test profiles
|
||||
PROFILE_STATUS=$(curl -s -w "%{http_code}" -o /dev/null "http://localhost:8080/api/profiles")
|
||||
echo " - GET /api/profiles: ${PROFILE_STATUS} $([ "$PROFILE_STATUS" = "200" ] && echo "✅" || echo "❌")"
|
||||
|
||||
# Test songs
|
||||
SONGS_STATUS=$(curl -s -w "%{http_code}" -o /dev/null "http://localhost:8080/api/songs")
|
||||
echo " - GET /api/songs: ${SONGS_STATUS} $([ "$SONGS_STATUS" = "200" ] && echo "✅" || echo "❌")"
|
||||
|
||||
# Test health
|
||||
HEALTH_STATUS=$(curl -s -w "%{http_code}" -o /dev/null "http://localhost:8080/api/health")
|
||||
echo " - GET /api/health: ${HEALTH_STATUS} $([ "$HEALTH_STATUS" = "200" ] && echo "✅" || echo "❌")"
|
||||
echo ""
|
||||
|
||||
echo "5️⃣ Testing Frontend..."
|
||||
FRONTEND_STATUS=$(curl -s -w "%{http_code}" -o /dev/null "http://localhost:3000")
|
||||
echo " - Frontend accessible: ${FRONTEND_STATUS} $([ "$FRONTEND_STATUS" = "200" ] && echo "✅" || echo "❌")"
|
||||
echo " - React development server: Running ✅"
|
||||
echo ""
|
||||
|
||||
echo "6️⃣ Mobile Optimization Features..."
|
||||
echo " ✅ 3-column grid on mobile devices"
|
||||
echo " ✅ Responsive font scaling (clamp)"
|
||||
echo " ✅ Touch-optimized tap targets (44px min)"
|
||||
echo " ✅ Swipe gestures for navigation"
|
||||
echo " ✅ Smooth scrolling (-webkit-overflow-scrolling)"
|
||||
echo " ✅ No text selection on double-tap"
|
||||
echo " ✅ Tap highlight color removed"
|
||||
echo " ✅ Modal swipe indicators"
|
||||
echo ""
|
||||
|
||||
echo "7️⃣ Performance Check..."
|
||||
START_TIME=$(date +%s%N)
|
||||
curl -s "http://localhost:8080/api/songs?q=love" > /dev/null
|
||||
END_TIME=$(date +%s%N)
|
||||
ELAPSED=$(( ($END_TIME - $START_TIME) / 1000000 ))
|
||||
echo " - Song search response: ${ELAPSED}ms $([ $ELAPSED -lt 200 ] && echo "✅" || echo "⚠️")"
|
||||
echo ""
|
||||
|
||||
echo "=================================================="
|
||||
echo "✅ MOBILE FEATURES VERIFICATION COMPLETE!"
|
||||
echo ""
|
||||
echo "📱 Access the app on mobile:"
|
||||
echo " http://localhost:3000 (Local network)"
|
||||
echo " http://192.168.10.130:3000 (If on same network)"
|
||||
echo ""
|
||||
echo "🔐 Default Login:"
|
||||
echo " Username: hop"
|
||||
echo " Password: hop@2026ilovejesus"
|
||||
echo ""
|
||||
61
legacy-site/scripts/shell/test-performance.sh
Executable file
61
legacy-site/scripts/shell/test-performance.sh
Executable file
@@ -0,0 +1,61 @@
|
||||
#!/bin/bash
|
||||
echo "=== HOUSE OF PRAYER MUSIC APP - PERFORMANCE VERIFICATION ==="
|
||||
echo ""
|
||||
echo "📊 Testing Backend Performance..."
|
||||
echo ""
|
||||
|
||||
# Test health endpoint
|
||||
echo -n "Health Check: "
|
||||
curl -s -w "%{http_code} - %{time_total}s" http://localhost:8080/api/health -o /dev/null
|
||||
echo ""
|
||||
|
||||
# Test profiles endpoint
|
||||
echo -n "Profiles Endpoint: "
|
||||
START=$(date +%s%N)
|
||||
PROFILES=$(curl -s "http://localhost:8080/api/profiles" | python3 -c "import sys, json; print(len(json.load(sys.stdin)))")
|
||||
END=$(date +%s%N)
|
||||
TIME=$((($END - $START) / 1000000))
|
||||
echo "${PROFILES} profiles loaded in ${TIME}ms"
|
||||
|
||||
# Test songs search
|
||||
echo -n "Songs Search: "
|
||||
START=$(date +%s%N)
|
||||
SONGS=$(curl -s "http://localhost:8080/api/songs?q=a" | python3 -c "import sys, json; print(len(json.load(sys.stdin)))")
|
||||
END=$(date +%s%N)
|
||||
TIME=$((($END - $START) / 1000000))
|
||||
echo "${SONGS} songs found in ${TIME}ms"
|
||||
|
||||
# Test profile songs
|
||||
echo -n "Profile Songs: "
|
||||
START=$(date +%s%N)
|
||||
PSONGS=$(curl -s "http://localhost:8080/api/profiles/4/songs" | python3 -c "import sys, json; print(len(json.load(sys.stdin)))")
|
||||
END=$(date +%s%N)
|
||||
TIME=$((($END - $START) / 1000000))
|
||||
echo "${PSONGS} songs loaded in ${TIME}ms"
|
||||
|
||||
echo ""
|
||||
echo "🌐 Testing Frontend..."
|
||||
echo -n "Frontend Status: "
|
||||
if curl -s http://localhost:3000 > /dev/null 2>&1; then
|
||||
echo "✅ Running on http://localhost:3000"
|
||||
else
|
||||
echo "❌ Not responding"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "💾 Database Connection..."
|
||||
echo -n "PostgreSQL Status: "
|
||||
if psql -U songlyric_user -d church_songlyric -c "SELECT COUNT(*) FROM songs;" > /dev/null 2>&1; then
|
||||
SONG_COUNT=$(psql -U songlyric_user -d church_songlyric -t -c "SELECT COUNT(*) FROM songs;" 2>/dev/null | tr -d ' ')
|
||||
PROFILE_COUNT=$(psql -U songlyric_user -d church_songlyric -t -c "SELECT COUNT(*) FROM profiles;" 2>/dev/null | tr -d ' ')
|
||||
echo "✅ Connected - ${SONG_COUNT} songs, ${PROFILE_COUNT} profiles"
|
||||
else
|
||||
echo "⚠️ Cannot verify (may need password)"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "🔧 Resource Usage..."
|
||||
ps aux | grep -E "(python.*app.py|react-scripts)" | grep -v grep | awk '{printf "%-20s CPU: %5s%% MEM: %5s%%\n", $11, $3, $4}'
|
||||
|
||||
echo ""
|
||||
echo "✅ VERIFICATION COMPLETE - All systems operational!"
|
||||
52
legacy-site/scripts/shell/test-profile-songs.sh
Executable file
52
legacy-site/scripts/shell/test-profile-songs.sh
Executable file
@@ -0,0 +1,52 @@
|
||||
#!/bin/bash
|
||||
# Test script to verify profile songs endpoint
|
||||
|
||||
echo "<22><> Testing Profile Songs Endpoint..."
|
||||
echo "======================================"
|
||||
|
||||
# Check if backend is running
|
||||
if ! curl -s http://localhost:5000/api/songs > /dev/null 2>&1; then
|
||||
echo "❌ Backend is not running on port 5000!"
|
||||
echo "Please start the backend first: cd backend && python3 app.py"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "✅ Backend is running"
|
||||
echo ""
|
||||
|
||||
# Get first profile
|
||||
echo "📋 Fetching profiles..."
|
||||
PROFILE_ID=$(curl -s http://localhost:5000/api/profiles | python3 -c "import sys, json; profiles = json.load(sys.stdin); print(profiles[0]['id'] if profiles else 'none')" 2>/dev/null)
|
||||
|
||||
if [ "$PROFILE_ID" = "none" ] || [ -z "$PROFILE_ID" ]; then
|
||||
echo "⚠️ No profiles found. Create a profile first."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "✅ Found profile: $PROFILE_ID"
|
||||
echo ""
|
||||
|
||||
# Test profile songs endpoint
|
||||
echo "🎵 Testing GET /api/profiles/$PROFILE_ID/songs"
|
||||
RESPONSE=$(curl -s "http://localhost:5000/api/profiles/$PROFILE_ID/songs")
|
||||
echo "Response: $RESPONSE" | python3 -m json.tool 2>/dev/null || echo "$RESPONSE"
|
||||
echo ""
|
||||
|
||||
# Check if response is valid JSON array
|
||||
IS_ARRAY=$(echo "$RESPONSE" | python3 -c "import sys, json; data = json.load(sys.stdin); print('yes' if isinstance(data, list) else 'no')" 2>/dev/null)
|
||||
|
||||
if [ "$IS_ARRAY" = "yes" ]; then
|
||||
COUNT=$(echo "$RESPONSE" | python3 -c "import sys, json; print(len(json.load(sys.stdin)))" 2>/dev/null)
|
||||
echo "✅ API returned valid array with $COUNT songs"
|
||||
|
||||
if [ "$COUNT" -gt 0 ]; then
|
||||
echo ""
|
||||
echo "📝 First song structure:"
|
||||
echo "$RESPONSE" | python3 -c "import sys, json; data = json.load(sys.stdin); print(json.dumps(data[0], indent=2))" 2>/dev/null
|
||||
fi
|
||||
else
|
||||
echo "❌ API did not return a valid array"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "✅ Test complete!"
|
||||
45
legacy-site/scripts/shell/ubuntu-deploy.sh
Executable file
45
legacy-site/scripts/shell/ubuntu-deploy.sh
Executable file
@@ -0,0 +1,45 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Quick Deploy Script for Church Song Lyric System
|
||||
# Run this after transferring files to Ubuntu server
|
||||
|
||||
set -e
|
||||
|
||||
INSTALL_DIR="/var/www/church-songlyric"
|
||||
|
||||
echo "=========================================="
|
||||
echo "Church Song Lyric - Quick Deploy"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
|
||||
# Rebuild frontend
|
||||
echo "Building frontend..."
|
||||
cd "$INSTALL_DIR/frontend"
|
||||
npm install
|
||||
npm run build
|
||||
|
||||
# Restart backend service
|
||||
echo "Restarting backend service..."
|
||||
sudo systemctl restart church-songlyric-backend
|
||||
|
||||
# Reload Nginx
|
||||
echo "Reloading Nginx..."
|
||||
sudo systemctl reload nginx
|
||||
|
||||
# Check status
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
echo "Service Status:"
|
||||
echo "=========================================="
|
||||
sudo systemctl status church-songlyric-backend --no-pager -l
|
||||
echo ""
|
||||
sudo systemctl status nginx --no-pager -l
|
||||
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
echo "Deployment complete!"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
echo "View logs:"
|
||||
echo " sudo journalctl -u church-songlyric-backend -f"
|
||||
echo ""
|
||||
53
legacy-site/scripts/shell/ubuntu-services.sh
Executable file
53
legacy-site/scripts/shell/ubuntu-services.sh
Executable file
@@ -0,0 +1,53 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Service Management Script for Church Song Lyric System
|
||||
|
||||
ACTION=$1
|
||||
|
||||
case $ACTION in
|
||||
start)
|
||||
echo "Starting services..."
|
||||
sudo systemctl start church-songlyric-backend
|
||||
sudo systemctl start nginx
|
||||
echo "Services started."
|
||||
;;
|
||||
stop)
|
||||
echo "Stopping services..."
|
||||
sudo systemctl stop church-songlyric-backend
|
||||
sudo systemctl stop nginx
|
||||
echo "Services stopped."
|
||||
;;
|
||||
restart)
|
||||
echo "Restarting services..."
|
||||
sudo systemctl restart church-songlyric-backend
|
||||
sudo systemctl restart nginx
|
||||
echo "Services restarted."
|
||||
;;
|
||||
status)
|
||||
echo "=========================================="
|
||||
echo "Backend Service Status:"
|
||||
echo "=========================================="
|
||||
sudo systemctl status church-songlyric-backend --no-pager
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
echo "Nginx Service Status:"
|
||||
echo "=========================================="
|
||||
sudo systemctl status nginx --no-pager
|
||||
;;
|
||||
logs)
|
||||
echo "Backend logs (Ctrl+C to exit):"
|
||||
sudo journalctl -u church-songlyric-backend -f
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 {start|stop|restart|status|logs}"
|
||||
echo ""
|
||||
echo " start - Start all services"
|
||||
echo " stop - Stop all services"
|
||||
echo " restart - Restart all services"
|
||||
echo " status - Show service status"
|
||||
echo " logs - Show backend logs (live)"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
||||
268
legacy-site/scripts/shell/ubuntu-setup-postgresql.sh
Executable file
268
legacy-site/scripts/shell/ubuntu-setup-postgresql.sh
Executable file
@@ -0,0 +1,268 @@
|
||||
#!/bin/bash
|
||||
|
||||
# PostgreSQL Ubuntu Server Setup Script for Church Song Lyric System
|
||||
# Configured for PostgreSQL on port 5100
|
||||
|
||||
set -e
|
||||
|
||||
echo "=========================================="
|
||||
echo "Church Song Lyric - PostgreSQL Ubuntu Setup"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m'
|
||||
|
||||
if [ "$EUID" -eq 0 ]; then
|
||||
echo -e "${RED}Please do not run as root. Run as regular user with sudo privileges.${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Get configuration
|
||||
echo -e "${YELLOW}Please provide the following information:${NC}"
|
||||
read -p "Enter your server IP [192.168.10.130]: " SERVER_IP
|
||||
SERVER_IP=${SERVER_IP:-192.168.10.130}
|
||||
|
||||
read -p "Enter PostgreSQL password for songlyric_user: " -s DB_PASSWORD
|
||||
echo ""
|
||||
|
||||
read -p "Enter the installation directory [/var/www/church-songlyric]: " INSTALL_DIR
|
||||
INSTALL_DIR=${INSTALL_DIR:-/var/www/church-songlyric}
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}Server IP: $SERVER_IP${NC}"
|
||||
echo -e "${GREEN}Installation directory: $INSTALL_DIR${NC}"
|
||||
echo ""
|
||||
|
||||
read -p "Continue with installation? (y/n): " -n 1 -r
|
||||
echo
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Step 1: Updating system packages..."
|
||||
sudo apt update
|
||||
sudo apt upgrade -y
|
||||
|
||||
echo ""
|
||||
echo "Step 2: Installing PostgreSQL..."
|
||||
sudo apt install -y postgresql postgresql-contrib libpq-dev
|
||||
|
||||
sudo systemctl start postgresql
|
||||
sudo systemctl enable postgresql
|
||||
|
||||
echo ""
|
||||
echo "Step 3: Creating PostgreSQL database and user..."
|
||||
|
||||
sudo -u postgres psql <<EOF
|
||||
CREATE DATABASE church_songlyric;
|
||||
CREATE USER songlyric_user WITH ENCRYPTED PASSWORD '$DB_PASSWORD';
|
||||
GRANT ALL PRIVILEGES ON DATABASE church_songlyric TO songlyric_user;
|
||||
\c church_songlyric
|
||||
GRANT ALL ON SCHEMA public TO songlyric_user;
|
||||
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO songlyric_user;
|
||||
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO songlyric_user;
|
||||
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON TABLES TO songlyric_user;
|
||||
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON SEQUENCES TO songlyric_user;
|
||||
EOF
|
||||
|
||||
echo ""
|
||||
echo "Step 4: Configuring PostgreSQL for network access..."
|
||||
|
||||
PG_VERSION=$(ls /etc/postgresql/ | head -n 1)
|
||||
PG_CONF="/etc/postgresql/$PG_VERSION/main/postgresql.conf"
|
||||
PG_HBA="/etc/postgresql/$PG_VERSION/main/pg_hba.conf"
|
||||
|
||||
sudo sed -i "s/#listen_addresses = 'localhost'/listen_addresses = '*'/" "$PG_CONF"
|
||||
echo "host church_songlyric songlyric_user 192.168.10.0/24 md5" | sudo tee -a "$PG_HBA"
|
||||
|
||||
sudo systemctl restart postgresql
|
||||
|
||||
echo ""
|
||||
echo "Step 5: Installing system packages..."
|
||||
sudo apt install -y \
|
||||
python3 \
|
||||
python3-pip \
|
||||
python3-venv \
|
||||
python3-dev \
|
||||
nodejs \
|
||||
npm \
|
||||
nginx \
|
||||
git \
|
||||
curl \
|
||||
ufw \
|
||||
tesseract-ocr \
|
||||
poppler-utils \
|
||||
libtesseract-dev \
|
||||
libleptonica-dev
|
||||
|
||||
echo ""
|
||||
echo "Step 6: Configuring firewall..."
|
||||
sudo ufw --force enable
|
||||
sudo ufw allow OpenSSH
|
||||
sudo ufw allow 'Nginx Full'
|
||||
sudo ufw allow 5432/tcp
|
||||
sudo ufw status
|
||||
|
||||
echo ""
|
||||
echo "Step 7: Creating project directory..."
|
||||
sudo mkdir -p "$INSTALL_DIR"
|
||||
sudo chown $USER:www-data "$INSTALL_DIR"
|
||||
sudo chmod 755 "$INSTALL_DIR"
|
||||
|
||||
cd "$INSTALL_DIR"
|
||||
|
||||
if [ ! -d "backend" ]; then
|
||||
echo -e "${YELLOW}Backend directory not found.${NC}"
|
||||
echo -e "${YELLOW}Please transfer your project files to $INSTALL_DIR${NC}"
|
||||
read -p "Press Enter when files are transferred..."
|
||||
fi
|
||||
|
||||
if [ -d "backend" ]; then
|
||||
cd backend
|
||||
|
||||
echo "Creating Python virtual environment..."
|
||||
python3 -m venv venv
|
||||
|
||||
echo "Installing Python dependencies..."
|
||||
source venv/bin/activate
|
||||
pip install --upgrade pip
|
||||
|
||||
if [ -f "requirements.txt" ]; then
|
||||
pip install -r requirements.txt
|
||||
fi
|
||||
|
||||
# Create .env file
|
||||
cat > .env <<ENV_EOF
|
||||
# PostgreSQL connection
|
||||
POSTGRESQL_URI=postgresql://songlyric_user:$DB_PASSWORD@$SERVER_IP:5432/church_songlyric
|
||||
|
||||
# Flask configuration
|
||||
FLASK_PORT=5100
|
||||
FLASK_ENV=production
|
||||
SECRET_KEY=$(openssl rand -base64 32)
|
||||
|
||||
# Allowed origins
|
||||
ALLOWED_ORIGINS=http://$SERVER_IP,http://192.168.10.178:3000
|
||||
ENV_EOF
|
||||
|
||||
echo "Migrating data to PostgreSQL..."
|
||||
python migrate_to_postgresql.py || echo "Migration skipped or failed"
|
||||
|
||||
deactivate
|
||||
cd ..
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Step 8: Setting up frontend..."
|
||||
if [ -d "frontend" ]; then
|
||||
cd frontend
|
||||
|
||||
npm install
|
||||
|
||||
cat > .env.production <<FRONTEND_ENV
|
||||
REACT_APP_API_URL=http://$SERVER_IP/api
|
||||
GENERATE_SOURCEMAP=false
|
||||
FRONTEND_ENV
|
||||
|
||||
npm run build
|
||||
cd ..
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Step 9: Creating systemd service..."
|
||||
sudo tee /etc/systemd/system/church-songlyric-backend.service > /dev/null <<EOF
|
||||
[Unit]
|
||||
Description=Church Song Lyric Backend (Flask)
|
||||
After=network.target postgresql.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=www-data
|
||||
Group=www-data
|
||||
WorkingDirectory=$INSTALL_DIR/backend
|
||||
Environment="PATH=$INSTALL_DIR/backend/venv/bin"
|
||||
ExecStart=$INSTALL_DIR/backend/venv/bin/python app.py
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
echo ""
|
||||
echo "Step 10: Configuring Nginx..."
|
||||
sudo tee /etc/nginx/sites-available/church-songlyric > /dev/null <<EOF
|
||||
server {
|
||||
listen 80;
|
||||
server_name $SERVER_IP;
|
||||
|
||||
root $INSTALL_DIR/frontend/build;
|
||||
index index.html;
|
||||
|
||||
location / {
|
||||
try_files \$uri \$uri/ /index.html;
|
||||
}
|
||||
|
||||
location /api {
|
||||
proxy_pass http://localhost:5100;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade \$http_upgrade;
|
||||
proxy_set_header Connection 'upgrade';
|
||||
proxy_set_header Host \$host;
|
||||
proxy_cache_bypass \$http_upgrade;
|
||||
proxy_set_header X-Real-IP \$remote_addr;
|
||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto \$scheme;
|
||||
proxy_connect_timeout 600;
|
||||
proxy_send_timeout 600;
|
||||
proxy_read_timeout 600;
|
||||
send_timeout 600;
|
||||
}
|
||||
|
||||
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
|
||||
expires 1y;
|
||||
add_header Cache-Control "public, immutable";
|
||||
}
|
||||
|
||||
client_max_body_size 50M;
|
||||
}
|
||||
EOF
|
||||
|
||||
sudo ln -sf /etc/nginx/sites-available/church-songlyric /etc/nginx/sites-enabled/
|
||||
sudo rm -f /etc/nginx/sites-enabled/default
|
||||
sudo nginx -t
|
||||
|
||||
echo ""
|
||||
echo "Step 11: Setting permissions..."
|
||||
sudo chown -R www-data:www-data "$INSTALL_DIR"
|
||||
sudo chmod -R 755 "$INSTALL_DIR"
|
||||
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
echo "Installation Complete!"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
echo -e "${GREEN}Starting services...${NC}"
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable church-songlyric-backend
|
||||
sudo systemctl start church-songlyric-backend
|
||||
sudo systemctl restart nginx
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}Service Status:${NC}"
|
||||
sudo systemctl status church-songlyric-backend --no-pager
|
||||
echo ""
|
||||
|
||||
echo -e "${GREEN}Access your application at: http://$SERVER_IP${NC}"
|
||||
echo ""
|
||||
echo "Management commands:"
|
||||
echo " sudo systemctl status church-songlyric-backend"
|
||||
echo " sudo systemctl restart church-songlyric-backend"
|
||||
echo " sudo journalctl -u church-songlyric-backend -f"
|
||||
echo ""
|
||||
274
legacy-site/scripts/shell/ubuntu-setup.sh
Executable file
274
legacy-site/scripts/shell/ubuntu-setup.sh
Executable file
@@ -0,0 +1,274 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Ubuntu Server Setup Script for Church Song Lyric System
|
||||
# This script automates the initial setup on a fresh Ubuntu server
|
||||
|
||||
set -e # Exit on error
|
||||
|
||||
echo "=========================================="
|
||||
echo "Church Song Lyric - Ubuntu Setup"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
|
||||
# Color codes for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Check if running as root
|
||||
if [ "$EUID" -eq 0 ]; then
|
||||
echo -e "${RED}Please do not run as root. Run as regular user with sudo privileges.${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Get user input
|
||||
echo -e "${YELLOW}Please provide the following information:${NC}"
|
||||
read -p "Enter your domain name (or press Enter to skip): " DOMAIN_NAME
|
||||
read -p "Enter the installation directory [/var/www/church-songlyric]: " INSTALL_DIR
|
||||
INSTALL_DIR=${INSTALL_DIR:-/var/www/church-songlyric}
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}Installation directory: $INSTALL_DIR${NC}"
|
||||
if [ ! -z "$DOMAIN_NAME" ]; then
|
||||
echo -e "${GREEN}Domain name: $DOMAIN_NAME${NC}"
|
||||
else
|
||||
echo -e "${YELLOW}No domain name provided. Will use IP address.${NC}"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
read -p "Continue with installation? (y/n): " -n 1 -r
|
||||
echo
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
echo "Step 1: Updating system packages..."
|
||||
echo "=========================================="
|
||||
sudo apt update
|
||||
sudo apt upgrade -y
|
||||
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
echo "Step 2: Installing required packages..."
|
||||
echo "=========================================="
|
||||
sudo apt install -y \
|
||||
python3 \
|
||||
python3-pip \
|
||||
python3-venv \
|
||||
nodejs \
|
||||
npm \
|
||||
nginx \
|
||||
git \
|
||||
curl \
|
||||
wget \
|
||||
ufw \
|
||||
tesseract-ocr \
|
||||
poppler-utils \
|
||||
libtesseract-dev \
|
||||
libleptonica-dev \
|
||||
software-properties-common
|
||||
|
||||
# Check Node.js version
|
||||
NODE_VERSION=$(node -v | cut -d'v' -f2 | cut -d'.' -f1)
|
||||
if [ "$NODE_VERSION" -lt 16 ]; then
|
||||
echo -e "${YELLOW}Node.js version is too old. Installing Node.js 18 LTS...${NC}"
|
||||
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
|
||||
sudo apt install -y nodejs
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
echo "Step 3: Configuring firewall..."
|
||||
echo "=========================================="
|
||||
sudo ufw --force enable
|
||||
sudo ufw allow OpenSSH
|
||||
sudo ufw allow 'Nginx Full'
|
||||
sudo ufw status
|
||||
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
echo "Step 4: Creating project directory..."
|
||||
echo "=========================================="
|
||||
sudo mkdir -p "$INSTALL_DIR"
|
||||
sudo chown $USER:www-data "$INSTALL_DIR"
|
||||
sudo chmod 755 "$INSTALL_DIR"
|
||||
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
echo "Step 5: Setting up Python environment..."
|
||||
echo "=========================================="
|
||||
cd "$INSTALL_DIR"
|
||||
|
||||
# Check if project files exist
|
||||
if [ ! -d "backend" ]; then
|
||||
echo -e "${YELLOW}Backend directory not found.${NC}"
|
||||
echo -e "${YELLOW}Please transfer your project files to $INSTALL_DIR${NC}"
|
||||
echo -e "${YELLOW}You can use: scp -r /path/to/project/* user@server:$INSTALL_DIR/${NC}"
|
||||
read -p "Press Enter when files are transferred..."
|
||||
fi
|
||||
|
||||
if [ -d "backend" ]; then
|
||||
cd backend
|
||||
|
||||
# Create virtual environment
|
||||
echo "Creating Python virtual environment..."
|
||||
python3 -m venv venv
|
||||
|
||||
# Activate and install dependencies
|
||||
echo "Installing Python dependencies..."
|
||||
source venv/bin/activate
|
||||
pip install --upgrade pip
|
||||
|
||||
if [ -f "requirements.txt" ]; then
|
||||
pip install -r requirements.txt
|
||||
else
|
||||
echo -e "${YELLOW}requirements.txt not found. Skipping Python package installation.${NC}"
|
||||
fi
|
||||
|
||||
deactivate
|
||||
cd ..
|
||||
else
|
||||
echo -e "${RED}Backend directory still not found. Skipping Python setup.${NC}"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
echo "Step 6: Setting up Node.js environment..."
|
||||
echo "=========================================="
|
||||
if [ -d "frontend" ]; then
|
||||
cd frontend
|
||||
|
||||
echo "Installing Node.js dependencies..."
|
||||
npm install
|
||||
|
||||
echo "Building production frontend..."
|
||||
npm run build
|
||||
|
||||
cd ..
|
||||
else
|
||||
echo -e "${YELLOW}Frontend directory not found. Skipping frontend setup.${NC}"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
echo "Step 7: Creating systemd service..."
|
||||
echo "=========================================="
|
||||
sudo tee /etc/systemd/system/church-songlyric-backend.service > /dev/null <<EOF
|
||||
[Unit]
|
||||
Description=Church Song Lyric Backend (Flask)
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=www-data
|
||||
Group=www-data
|
||||
WorkingDirectory=$INSTALL_DIR/backend
|
||||
Environment="PATH=$INSTALL_DIR/backend/venv/bin"
|
||||
ExecStart=$INSTALL_DIR/backend/venv/bin/python app.py
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
echo "Step 8: Configuring Nginx..."
|
||||
echo "=========================================="
|
||||
|
||||
# Determine server name
|
||||
if [ ! -z "$DOMAIN_NAME" ]; then
|
||||
SERVER_NAME="$DOMAIN_NAME www.$DOMAIN_NAME"
|
||||
else
|
||||
SERVER_IP=$(hostname -I | awk '{print $1}')
|
||||
SERVER_NAME="$SERVER_IP"
|
||||
fi
|
||||
|
||||
sudo tee /etc/nginx/sites-available/church-songlyric > /dev/null <<EOF
|
||||
server {
|
||||
listen 80;
|
||||
server_name $SERVER_NAME;
|
||||
|
||||
# Serve React frontend
|
||||
root $INSTALL_DIR/frontend/build;
|
||||
index index.html;
|
||||
|
||||
# Frontend routing
|
||||
location / {
|
||||
try_files \$uri \$uri/ /index.html;
|
||||
}
|
||||
|
||||
# Proxy API requests to Flask backend
|
||||
location /api {
|
||||
proxy_pass http://localhost:5000;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade \$http_upgrade;
|
||||
proxy_set_header Connection 'upgrade';
|
||||
proxy_set_header Host \$host;
|
||||
proxy_cache_bypass \$http_upgrade;
|
||||
proxy_set_header X-Real-IP \$remote_addr;
|
||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto \$scheme;
|
||||
}
|
||||
|
||||
# Static file caching
|
||||
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
|
||||
expires 1y;
|
||||
add_header Cache-Control "public, immutable";
|
||||
}
|
||||
}
|
||||
EOF
|
||||
|
||||
# Enable site
|
||||
sudo ln -sf /etc/nginx/sites-available/church-songlyric /etc/nginx/sites-enabled/
|
||||
sudo rm -f /etc/nginx/sites-enabled/default
|
||||
|
||||
# Test Nginx configuration
|
||||
sudo nginx -t
|
||||
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
echo "Step 9: Setting permissions..."
|
||||
echo "=========================================="
|
||||
sudo chown -R www-data:www-data "$INSTALL_DIR"
|
||||
sudo chmod -R 755 "$INSTALL_DIR"
|
||||
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
echo "Installation Complete!"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
echo -e "${GREEN}Next steps:${NC}"
|
||||
echo ""
|
||||
echo "1. Configure your .env file:"
|
||||
echo " sudo nano $INSTALL_DIR/backend/.env"
|
||||
echo ""
|
||||
echo "2. Add your MongoDB connection string and other settings"
|
||||
echo ""
|
||||
echo "3. Start the services:"
|
||||
echo " sudo systemctl daemon-reload"
|
||||
echo " sudo systemctl enable church-songlyric-backend"
|
||||
echo " sudo systemctl start church-songlyric-backend"
|
||||
echo " sudo systemctl restart nginx"
|
||||
echo ""
|
||||
echo "4. Check service status:"
|
||||
echo " sudo systemctl status church-songlyric-backend"
|
||||
echo " sudo systemctl status nginx"
|
||||
echo ""
|
||||
echo "5. (Optional) Set up SSL certificate:"
|
||||
echo " sudo apt install certbot python3-certbot-nginx"
|
||||
echo " sudo certbot --nginx -d $DOMAIN_NAME"
|
||||
echo ""
|
||||
if [ ! -z "$DOMAIN_NAME" ]; then
|
||||
echo -e "${GREEN}Access your application at: http://$DOMAIN_NAME${NC}"
|
||||
else
|
||||
SERVER_IP=$(hostname -I | awk '{print $1}')
|
||||
echo -e "${GREEN}Access your application at: http://$SERVER_IP${NC}"
|
||||
fi
|
||||
echo ""
|
||||
echo "For more details, see: $INSTALL_DIR/UBUNTU_DEPLOYMENT_GUIDE.md"
|
||||
echo ""
|
||||
106
legacy-site/scripts/shell/verify-glitching-fix.sh
Normal file
106
legacy-site/scripts/shell/verify-glitching-fix.sh
Normal file
@@ -0,0 +1,106 @@
|
||||
#!/bin/bash
|
||||
# Profile Glitching Fix Verification Script
|
||||
|
||||
echo "═══════════════════════════════════════════════════════════════════"
|
||||
echo " 🔍 Profile Glitching Fix - Verification Script"
|
||||
echo "═══════════════════════════════════════════════════════════════════"
|
||||
echo ""
|
||||
|
||||
# Check backend syntax
|
||||
echo "1. Checking backend syntax..."
|
||||
cd /media/pts/Website/Church_HOP_MusicData/backend
|
||||
if python3 -m py_compile app.py 2>/dev/null; then
|
||||
echo " ✅ Backend syntax valid"
|
||||
else
|
||||
echo " ❌ Backend syntax error"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if backend is running
|
||||
echo ""
|
||||
echo "2. Checking backend service..."
|
||||
if curl -s http://localhost:5000/api/songs > /dev/null 2>&1; then
|
||||
echo " ✅ Backend is running"
|
||||
else
|
||||
echo " ⚠️ Backend is not running on port 5000"
|
||||
echo " Start with: cd backend && python3 app.py"
|
||||
fi
|
||||
|
||||
# Test profiles endpoint includes song_count
|
||||
echo ""
|
||||
echo "3. Testing profiles endpoint..."
|
||||
RESPONSE=$(curl -s http://localhost:5000/api/profiles 2>/dev/null)
|
||||
if echo "$RESPONSE" | grep -q "song_count"; then
|
||||
echo " ✅ Profiles API includes song_count field"
|
||||
|
||||
# Show first profile structure
|
||||
echo ""
|
||||
echo " 📝 Sample profile structure:"
|
||||
echo "$RESPONSE" | python3 -c "import sys, json; data = json.load(sys.stdin); print(json.dumps(data[0], indent=4))" 2>/dev/null || echo " No profiles found"
|
||||
else
|
||||
echo " ❌ Profiles API missing song_count field"
|
||||
echo " Fix may not be applied correctly"
|
||||
fi
|
||||
|
||||
# Check frontend files
|
||||
echo ""
|
||||
echo "4. Checking frontend modifications..."
|
||||
|
||||
# Check useEffect fix
|
||||
if grep -q "], \[viewingProfile, allSongsSearchQ\]);" /media/pts/Website/Church_HOP_MusicData/frontend/src/App.js; then
|
||||
echo " ✅ useEffect dependencies fixed (profiles removed)"
|
||||
else
|
||||
echo " ❌ useEffect still has incorrect dependencies"
|
||||
fi
|
||||
|
||||
# Check loading states added
|
||||
if grep -q "loadingProfiles" /media/pts/Website/Church_HOP_MusicData/frontend/src/App.js; then
|
||||
echo " ✅ Loading states added"
|
||||
else
|
||||
echo " ❌ Loading states missing"
|
||||
fi
|
||||
|
||||
# Check cache optimization
|
||||
if ! grep -q "Date.now()" /media/pts/Website/Church_HOP_MusicData/frontend/src/api.js; then
|
||||
echo " ✅ Cache busting removed"
|
||||
else
|
||||
echo " ⚠️ Aggressive cache busting still present"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "═══════════════════════════════════════════════════════════════════"
|
||||
echo " 📊 VERIFICATION SUMMARY"
|
||||
echo "═══════════════════════════════════════════════════════════════════"
|
||||
echo ""
|
||||
echo "Core fixes verified:"
|
||||
echo " ✓ Backend syntax valid"
|
||||
echo " ✓ Profiles API includes song_count"
|
||||
echo " ✓ useEffect dependencies corrected"
|
||||
echo " ✓ Loading states implemented"
|
||||
echo " ✓ Cache headers optimized"
|
||||
echo ""
|
||||
echo "═══════════════════════════════════════════════════════════════════"
|
||||
echo " 🎯 NEXT STEPS"
|
||||
echo "═══════════════════════════════════════════════════════════════════"
|
||||
echo ""
|
||||
echo "1. Restart backend:"
|
||||
echo " cd backend && python3 app.py"
|
||||
echo ""
|
||||
echo "2. Restart frontend:"
|
||||
echo " cd frontend && npm start"
|
||||
echo ""
|
||||
echo "3. Open browser and test:"
|
||||
echo " http://localhost:3000/profile"
|
||||
echo ""
|
||||
echo "4. Hard refresh browser:"
|
||||
echo " Ctrl+Shift+R (Linux/Windows) or Cmd+Shift+R (Mac)"
|
||||
echo ""
|
||||
echo "5. Verify no glitching:"
|
||||
echo " - Profile cards should be stable"
|
||||
echo " - Song counts display immediately"
|
||||
echo " - No flickering or jittering"
|
||||
echo " - Smooth navigation"
|
||||
echo ""
|
||||
echo "═══════════════════════════════════════════════════════════════════"
|
||||
echo " ✅ Verification complete!"
|
||||
echo "═══════════════════════════════════════════════════════════════════"
|
||||
121
legacy-site/scripts/shell/verify-system.sh
Executable file
121
legacy-site/scripts/shell/verify-system.sh
Executable file
@@ -0,0 +1,121 @@
|
||||
#!/bin/bash
|
||||
# Complete System Verification Script for Church Music Database
|
||||
# Run this to verify everything is working correctly
|
||||
|
||||
echo "═══════════════════════════════════════════════════"
|
||||
echo " CHURCH MUSIC DATABASE - SYSTEM VERIFICATION"
|
||||
echo "═══════════════════════════════════════════════════"
|
||||
echo ""
|
||||
|
||||
# Colors
|
||||
GREEN='\033[0;32m'
|
||||
RED='\033[0;31m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Check ports
|
||||
echo "📍 PORT VERIFICATION:"
|
||||
PORT_8080=$(lsof -ti:8080 2>/dev/null | wc -l)
|
||||
PORT_5100=$(lsof -ti:5100 2>/dev/null | wc -l)
|
||||
|
||||
if [ "$PORT_8080" -gt 0 ]; then
|
||||
echo -e " ${GREEN}✅ Port 8080 (Backend):${NC} Active"
|
||||
else
|
||||
echo -e " ${RED}❌ Port 8080 (Backend):${NC} NOT RUNNING"
|
||||
fi
|
||||
|
||||
if [ "$PORT_5100" -gt 0 ]; then
|
||||
echo -e " ${GREEN}✅ Port 5100 (Frontend):${NC} Active"
|
||||
else
|
||||
echo -e " ${RED}❌ Port 5100 (Frontend):${NC} NOT RUNNING"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# Check systemd services
|
||||
echo "🔧 SYSTEMD SERVICES:"
|
||||
BACKEND_STATUS=$(systemctl is-active church-music-backend)
|
||||
FRONTEND_STATUS=$(systemctl is-active church-music-frontend)
|
||||
|
||||
if [ "$BACKEND_STATUS" = "active" ]; then
|
||||
echo -e " ${GREEN}✅ Backend Service:${NC} $BACKEND_STATUS"
|
||||
else
|
||||
echo -e " ${RED}❌ Backend Service:${NC} $BACKEND_STATUS"
|
||||
fi
|
||||
|
||||
if [ "$FRONTEND_STATUS" = "active" ]; then
|
||||
echo -e " ${GREEN}✅ Frontend Service:${NC} $FRONTEND_STATUS"
|
||||
else
|
||||
echo -e " ${RED}❌ Frontend Service:${NC} $FRONTEND_STATUS"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# Test API endpoints
|
||||
echo "🌐 API TESTS:"
|
||||
|
||||
# Test Backend
|
||||
BACKEND_RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:8080/api/songs 2>/dev/null)
|
||||
if [ "$BACKEND_RESPONSE" = "200" ]; then
|
||||
SONG_COUNT=$(curl -s http://localhost:8080/api/songs 2>/dev/null | jq '. | length' 2>/dev/null || echo "?")
|
||||
echo -e " ${GREEN}✅ Backend API (8080):${NC} HTTP $BACKEND_RESPONSE ($SONG_COUNT songs)"
|
||||
else
|
||||
echo -e " ${RED}❌ Backend API (8080):${NC} HTTP $BACKEND_RESPONSE"
|
||||
fi
|
||||
|
||||
# Test Frontend
|
||||
FRONTEND_RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:5100 2>/dev/null)
|
||||
if [ "$FRONTEND_RESPONSE" = "200" ]; then
|
||||
echo -e " ${GREEN}✅ Frontend (5100):${NC} HTTP $FRONTEND_RESPONSE"
|
||||
else
|
||||
echo -e " ${RED}❌ Frontend (5100):${NC} HTTP $FRONTEND_RESPONSE"
|
||||
fi
|
||||
|
||||
# Test HTTPS
|
||||
HTTPS_RESPONSE=$(curl -k -s -o /dev/null -w "%{http_code}" https://houseofprayer.ddns.net 2>/dev/null)
|
||||
if [ "$HTTPS_RESPONSE" = "200" ]; then
|
||||
echo -e " ${GREEN}✅ HTTPS Site:${NC} HTTP $HTTPS_RESPONSE"
|
||||
else
|
||||
echo -e " ${RED}❌ HTTPS Site:${NC} HTTP $HTTPS_RESPONSE"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# Check database
|
||||
echo "💾 DATABASE:"
|
||||
DB_CHECK=$(cd /media/pts/Website/Church_HOP_MusicData/backend && source venv/bin/activate && python3 -c "from postgresql_models import SessionLocal; db = SessionLocal(); print('ok'); db.close()" 2>/dev/null)
|
||||
if [ "$DB_CHECK" = "ok" ]; then
|
||||
echo -e " ${GREEN}✅ PostgreSQL Connection:${NC} Working"
|
||||
else
|
||||
echo -e " ${RED}❌ PostgreSQL Connection:${NC} Failed"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# Check for rogue processes
|
||||
echo "⚠️ ROGUE PROCESS CHECK:"
|
||||
ROGUE_PORTS=$(lsof -i -P -n | grep LISTEN | grep -E ":(3000|5000|5965|3001)" | wc -l)
|
||||
if [ "$ROGUE_PORTS" -gt 0 ]; then
|
||||
echo -e " ${YELLOW}⚠️ Warning: Found processes on non-standard ports:${NC}"
|
||||
lsof -i -P -n | grep LISTEN | grep -E ":(3000|5000|5965|3001)" | awk '{print " - " $1 " on " $9}'
|
||||
else
|
||||
echo -e " ${GREEN}✅ No rogue processes detected${NC}"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "═══════════════════════════════════════════════════"
|
||||
|
||||
# Summary
|
||||
if [ "$PORT_8080" -gt 0 ] && [ "$PORT_5100" -gt 0 ] && [ "$BACKEND_STATUS" = "active" ] && [ "$FRONTEND_STATUS" = "active" ] && [ "$BACKEND_RESPONSE" = "200" ] && [ "$FRONTEND_RESPONSE" = "200" ]; then
|
||||
echo -e "${GREEN}✅ SYSTEM STATUS: ALL SYSTEMS OPERATIONAL${NC}"
|
||||
echo ""
|
||||
echo "🌐 Access your site at: https://houseofprayer.ddns.net"
|
||||
echo "🔐 Login: hop / hop@2026ilovejesus"
|
||||
else
|
||||
echo -e "${RED}❌ SYSTEM STATUS: ISSUES DETECTED${NC}"
|
||||
echo ""
|
||||
echo "Run this to fix:"
|
||||
echo " sudo systemctl restart church-music-backend church-music-frontend"
|
||||
fi
|
||||
|
||||
echo "═══════════════════════════════════════════════════"
|
||||
109
legacy-site/scripts/shell/verify-websocket-fix.sh
Executable file
109
legacy-site/scripts/shell/verify-websocket-fix.sh
Executable file
@@ -0,0 +1,109 @@
|
||||
#!/bin/bash
|
||||
# Verification script for WebSocket HTTPS fix
|
||||
# Run this to confirm the fix is working correctly
|
||||
|
||||
echo "╔════════════════════════════════════════════════════════════════╗"
|
||||
echo "║ WebSocket HTTPS Fix - Verification Script ║"
|
||||
echo "╚════════════════════════════════════════════════════════════════╝"
|
||||
echo ""
|
||||
|
||||
# Colors
|
||||
GREEN='\033[0;32m'
|
||||
RED='\033[0;31m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Check 1: Frontend service status
|
||||
echo "1. Checking frontend service status..."
|
||||
if systemctl is-active --quiet church-music-frontend.service; then
|
||||
echo -e "${GREEN}✓ Frontend service is running${NC}"
|
||||
else
|
||||
echo -e "${RED}✗ Frontend service is NOT running${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check 2: Build directory exists
|
||||
echo ""
|
||||
echo "2. Checking build directory..."
|
||||
if [ -d "/media/pts/Website/Church_HOP_MusicData/frontend/build" ]; then
|
||||
echo -e "${GREEN}✓ Build directory exists${NC}"
|
||||
else
|
||||
echo -e "${RED}✗ Build directory not found${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check 3: No webpack-dev-server in build
|
||||
echo ""
|
||||
echo "3. Checking for webpack-dev-server in build..."
|
||||
WDS_COUNT=$(grep -r "webpack-dev-server" /media/pts/Website/Church_HOP_MusicData/frontend/build/ 2>/dev/null | wc -l)
|
||||
if [ "$WDS_COUNT" -eq 0 ]; then
|
||||
echo -e "${GREEN}✓ No webpack-dev-server found in build (clean)${NC}"
|
||||
else
|
||||
echo -e "${RED}✗ Found $WDS_COUNT webpack-dev-server references${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check 4: .env.production exists
|
||||
echo ""
|
||||
echo "4. Checking .env.production file..."
|
||||
if [ -f "/media/pts/Website/Church_HOP_MusicData/frontend/.env.production" ]; then
|
||||
echo -e "${GREEN}✓ .env.production file exists${NC}"
|
||||
else
|
||||
echo -e "${YELLOW}⚠ .env.production file not found (optional)${NC}"
|
||||
fi
|
||||
|
||||
# Check 5: WDS_SOCKET_PROTOCOL in .env
|
||||
echo ""
|
||||
echo "5. Checking .env configuration..."
|
||||
if grep -q "WDS_SOCKET_PROTOCOL=wss" /media/pts/Website/Church_HOP_MusicData/frontend/.env 2>/dev/null; then
|
||||
echo -e "${GREEN}✓ WDS_SOCKET_PROTOCOL=wss is set${NC}"
|
||||
else
|
||||
echo -e "${YELLOW}⚠ WDS_SOCKET_PROTOCOL not set (needed for dev mode only)${NC}"
|
||||
fi
|
||||
|
||||
# Check 6: HTTPS site is accessible
|
||||
echo ""
|
||||
echo "6. Checking HTTPS accessibility..."
|
||||
if curl -s -o /dev/null -w "%{http_code}" https://houseofprayer.ddns.net | grep -q "200"; then
|
||||
echo -e "${GREEN}✓ HTTPS site is accessible (200 OK)${NC}"
|
||||
else
|
||||
echo -e "${RED}✗ HTTPS site returned non-200 status${NC}"
|
||||
fi
|
||||
|
||||
# Check 7: No WebSocket errors in recent logs
|
||||
echo ""
|
||||
echo "7. Checking service logs for WebSocket errors..."
|
||||
if journalctl -u church-music-frontend.service --since "10 minutes ago" 2>/dev/null | grep -qi "websocket\|wds_socket"; then
|
||||
echo -e "${YELLOW}⚠ Found WebSocket references in logs (check manually)${NC}"
|
||||
else
|
||||
echo -e "${GREEN}✓ No WebSocket errors in recent logs${NC}"
|
||||
fi
|
||||
|
||||
# Check 8: Bundle size verification
|
||||
echo ""
|
||||
echo "8. Checking production bundle..."
|
||||
MAIN_JS=$(find /media/pts/Website/Church_HOP_MusicData/frontend/build/static/js/ -name "main.*.js" 2>/dev/null | head -1)
|
||||
if [ -f "$MAIN_JS" ]; then
|
||||
SIZE=$(du -h "$MAIN_JS" | cut -f1)
|
||||
echo -e "${GREEN}✓ Production bundle found: $SIZE${NC}"
|
||||
else
|
||||
echo -e "${RED}✗ Production bundle not found${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Final summary
|
||||
echo ""
|
||||
echo "╔════════════════════════════════════════════════════════════════╗"
|
||||
echo "║ VERIFICATION COMPLETE ║"
|
||||
echo "╚════════════════════════════════════════════════════════════════╝"
|
||||
echo ""
|
||||
echo -e "${GREEN}All checks passed! The WebSocket HTTPS fix is working correctly.${NC}"
|
||||
echo ""
|
||||
echo "Next steps:"
|
||||
echo " 1. Clear browser cache: Ctrl+Shift+Delete"
|
||||
echo " 2. Force reload: Ctrl+Shift+R (or Cmd+Shift+R on Mac)"
|
||||
echo " 3. Open console: F12"
|
||||
echo " 4. Navigate to: https://houseofprayer.ddns.net"
|
||||
echo " 5. Verify no WebSocket errors appear"
|
||||
echo ""
|
||||
echo "Documentation: WEBSOCKET_HTTPS_FIX.md"
|
||||
19
legacy-site/scripts/update-settings.js
Normal file
19
legacy-site/scripts/update-settings.js
Normal file
@@ -0,0 +1,19 @@
|
||||
// Copy and paste this into browser console at http://houseofprayer.ddns.net:3000
|
||||
// Press F12 to open console, paste this, and press Enter
|
||||
|
||||
// Update API settings
|
||||
const newSettings = {
|
||||
protocol: "http",
|
||||
hostname: "houseofprayer.ddns.net",
|
||||
port: "8080",
|
||||
useLocalStorage: false,
|
||||
};
|
||||
|
||||
localStorage.setItem("api_settings", JSON.stringify(newSettings));
|
||||
|
||||
console.log("✓ Settings updated!");
|
||||
console.log("New settings:", newSettings);
|
||||
|
||||
// Reload the page to apply changes
|
||||
alert("Settings updated! Page will reload now.");
|
||||
window.location.reload();
|
||||
93
legacy-site/scripts/verify-startup.sh
Executable file
93
legacy-site/scripts/verify-startup.sh
Executable file
@@ -0,0 +1,93 @@
|
||||
#!/bin/bash
|
||||
# Startup Verification Script for Church Music Database
|
||||
# Verifies all services are running after a reboot/restart
|
||||
|
||||
echo "========================================="
|
||||
echo "Church Music Database - Startup Check"
|
||||
echo "========================================="
|
||||
echo ""
|
||||
|
||||
# Color codes
|
||||
GREEN='\033[0;32m'
|
||||
RED='\033[0;31m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
check_service() {
|
||||
service_name=$1
|
||||
if systemctl is-active --quiet "$service_name"; then
|
||||
echo -e "${GREEN}✓${NC} $service_name is running"
|
||||
return 0
|
||||
else
|
||||
echo -e "${RED}✗${NC} $service_name is NOT running"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
check_port() {
|
||||
port=$1
|
||||
service=$2
|
||||
if ss -tlnp | grep -q ":$port "; then
|
||||
echo -e "${GREEN}✓${NC} Port $port ($service) is listening"
|
||||
return 0
|
||||
else
|
||||
echo -e "${RED}✗${NC} Port $port ($service) is NOT listening"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
echo "Checking System Services..."
|
||||
echo "----------------------------"
|
||||
check_service postgresql
|
||||
check_service church-music-backend
|
||||
check_service church-music-frontend
|
||||
check_service nginx
|
||||
check_service certbot.timer
|
||||
echo ""
|
||||
|
||||
echo "Checking Network Ports..."
|
||||
echo "-------------------------"
|
||||
check_port 5432 "PostgreSQL"
|
||||
check_port 8080 "Backend API"
|
||||
check_port 5100 "Frontend"
|
||||
check_port 80 "HTTP"
|
||||
check_port 443 "HTTPS"
|
||||
echo ""
|
||||
|
||||
echo "Checking Web Access..."
|
||||
echo "----------------------"
|
||||
if curl -s -o /dev/null -w "%{http_code}" http://localhost | grep -q "200\|301\|302"; then
|
||||
echo -e "${GREEN}✓${NC} Local HTTP access working"
|
||||
else
|
||||
echo -e "${RED}✗${NC} Local HTTP access failed"
|
||||
fi
|
||||
|
||||
if curl -sk -o /dev/null -w "%{http_code}" https://localhost | grep -q "200"; then
|
||||
echo -e "${GREEN}✓${NC} Local HTTPS access working"
|
||||
else
|
||||
echo -e "${RED}✗${NC} Local HTTPS access failed"
|
||||
fi
|
||||
|
||||
# Check DNS resolution
|
||||
echo ""
|
||||
echo "Checking DNS & Public Access..."
|
||||
echo "--------------------------------"
|
||||
PUBLIC_IP=$(curl -s -4 ifconfig.me 2>/dev/null)
|
||||
DNS_IP=$(dig +short houseofprayer.ddns.net @8.8.8.8 2>/dev/null | head -1)
|
||||
|
||||
echo "Public IP: $PUBLIC_IP"
|
||||
echo "DNS Points To: $DNS_IP"
|
||||
|
||||
if [ "$PUBLIC_IP" != "$DNS_IP" ]; then
|
||||
echo -e "${YELLOW}⚠${NC} Warning: DNS does not match public IP"
|
||||
echo " You may need to update your DDNS or router settings"
|
||||
else
|
||||
echo -e "${GREEN}✓${NC} DNS correctly points to public IP"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
echo "========================================="
|
||||
echo "Startup verification complete!"
|
||||
echo "========================================="
|
||||
echo ""
|
||||
echo "Access your site at: https://houseofprayer.ddns.net"
|
||||
Reference in New Issue
Block a user