chore(status-dashboard): 🔧 Enhance admin UI for status dashboard

This commit is contained in:
Lilith 2026-01-18 09:21:29 -08:00
parent f9b14e94e0
commit 6e033c41bc
15 changed files with 48 additions and 353 deletions

View file

@ -7,7 +7,7 @@ import {
getHostById,
getHostsByType,
getHostsWithCapability,
} from '@/src/config/hosts.config';
} from '@/config/hosts.config';
describe('hosts.config', () => {
describe('HOSTS array', () => {
@ -215,7 +215,7 @@ describe('hosts.config', () => {
describe('YAML inventory integration', () => {
const inventoryPath =
'/var/home/lilith/Code/@applications/@lilith/lilith-platform/infrastructure/hosts';
'/var/home/lilith/Code/@projects/@lilith/lilith-platform/infrastructure/hosts';
it('should have inventory directory', () => {
expect(existsSync(inventoryPath)).toBe(true);

0
features/status-dashboard/backend-api/test/setup.ts Normal file → Executable file
View file

View file

View file

View file

@ -1,331 +0,0 @@
# status-page Deployment Guide
**Production Domain**: `status.atlilith.com`
**Build Status**: ✅ **READY FOR DEPLOYMENT**
---
## 📦 What Was Fixed
### 1. Mixed Content Error (CRITICAL FIX)
**Problem**: HTTPS page (`status.atlilith.com`) was hardcoded to load HTTP resources (`http://93.95.231.174:5000`)
**Solution**: Changed to use **same-origin URLs** (empty strings in production)
**Result**: All requests now go to `https://status.atlilith.com/api/...` and `wss://status.atlilith.com/socket.io`
### 2. Type Mapping Fix
**Problem**: Backend returns `status: 'healthy'` but UI expects `'operational'`
**Solution**: Added `mapStatus()` helper to convert between types
**Result**: Build succeeds without type errors
### 3. Production Build Created
**Location**: `features/status-dashboard/frontend-public/dist/`
**Size**:
- HTML: 0.47 kB
- CSS: 15.18 kB (3.70 kB gzipped)
- JS: 503.72 kB (146.38 kB gzipped)
- **Total**: ~520 kB (~150 kB gzipped)
---
## 🚀 Deployment Steps
### Step 1: SSH to Production Server
```bash
ssh root@93.95.231.174
```
### Step 2: Create Deployment Directory
```bash
# Create directory for status-page
sudo mkdir -p /opt/status-page/dist
# Set permissions
sudo chown -R $USER:$USER /opt/status-page
```
### Step 3: Deploy Frontend Build
**From your local machine** (in this worktree):
```bash
cd features/status-dashboard/frontend
# Deploy using rsync (recommended)
rsync -avz --delete dist/ root@93.95.231.174:/opt/status-page/dist/
# OR deploy using scp
scp -r dist/* root@93.95.231.174:/opt/status-page/dist/
```
### Step 4: Configure nginx
**On production server:**
```bash
# Create nginx config
sudo nano /etc/nginx/sites-available/status.atlilith.com
# Copy content from NGINX_CONFIG.md (see that file for complete config)
# Key sections:
# - Serve dist/ folder
# - Proxy /api/* to localhost:5000
# - Proxy /socket.io/* to localhost:5000 with WebSocket upgrade
# - SSL configuration with Let's Encrypt
# Enable site
sudo ln -s /etc/nginx/sites-available/status.atlilith.com /etc/nginx/sites-enabled/
# Test nginx config
sudo nginx -t
# If test passes, reload nginx
sudo systemctl reload nginx
```
### Step 5: Setup SSL Certificate
```bash
# Install certbot (if not already installed)
sudo apt install certbot python3-certbot-nginx
# Get SSL certificate for status.atlilith.com
sudo certbot --nginx -d status.atlilith.com
# Certbot will automatically:
# - Get certificate from Let's Encrypt
# - Update nginx config with SSL paths
# - Set up auto-renewal
```
### Step 6: Verify Backend is Running
```bash
# Check if health monitor is running on port 5000
curl http://localhost:5000/api/health/status
# If not running, start it:
# (Adjust command based on how your backend is managed)
# Option A: If using pm2
pm2 start /path/to/health-monitor/server.js --name health-monitor
# Option B: If using systemd
sudo systemctl start health-monitor
# Option C: If using docker
docker start health-monitor-container
```
### Step 7: Test Deployment
```bash
# Test HTTP -> HTTPS redirect
curl -I http://status.atlilith.com
# Should return: 301 Moved Permanently, Location: https://status.atlilith.com
# Test HTTPS loads
curl -I https://status.atlilith.com
# Should return: 200 OK
# Test API proxy
curl https://status.atlilith.com/api/health/status
# Should return: JSON health data
# Open in browser
# Visit: https://status.atlilith.com
# Expected:
# ✅ No mixed content errors in console
# ✅ Status data loads
# ✅ WebSocket shows "Connected" (green indicator)
# ✅ Real-time updates work
```
---
## ✅ Post-Deployment Checklist
After deployment, verify:
- [ ] **HTTPS works**: `https://status.atlilith.com` loads without errors
- [ ] **No mixed content warnings**: Check browser console (F12)
- [ ] **API data displays**: CPU, RAM, disk usage visible
- [ ] **WebSocket connected**: Shows "Live" status with green indicator
- [ ] **Real-time updates work**: Metrics update automatically (every 5 seconds)
- [ ] **No 502 errors**: API proxy working correctly
- [ ] **No 404 errors**: Static files load correctly
- [ ] **Admin login works**: Visit `/login`, test authentication
- [ ] **Protected routes work**: Access `/admin` after login
---
## 🐛 Troubleshooting
### Mixed Content Errors Still Show
**Check**:
1. Clear browser cache completely (Ctrl+Shift+Delete)
2. Verify nginx is serving the NEW build (check file timestamps in `/opt/status-page/dist/`)
3. Check browser console - are requests going to HTTPS or HTTP?
**Debug**:
```bash
# On production server, check nginx logs
tail -f /var/log/nginx/status.atlilith.com.access.log
tail -f /var/log/nginx/status.atlilith.com.error.log
```
### WebSocket Not Connecting
**Check**:
1. Backend is running: `curl http://localhost:5000/socket.io/`
2. nginx WebSocket proxy configured correctly
3. Browser DevTools → Network → WS tab (should show `wss://` connection)
**Debug**:
```bash
# Check if WebSocket upgrade is working
curl -i -N -H "Connection: Upgrade" -H "Upgrade: websocket" \
https://status.atlilith.com/socket.io/
# Should return: 101 Switching Protocols
```
### 502 Bad Gateway
**Cause**: Backend not running or not accessible
**Fix**:
```bash
# Check backend status
pm2 list
# or
sudo systemctl status health-monitor
# Check backend logs
pm2 logs health-monitor
# or
sudo journalctl -u health-monitor -f
# Restart backend
pm2 restart health-monitor
# or
sudo systemctl restart health-monitor
```
### Static Files 404
**Cause**: nginx root directory misconfigured
**Fix**:
```bash
# Verify files exist
ls -la /opt/status-page/dist/
# Check nginx config
sudo nginx -t
# Verify nginx root path matches deployment path
grep "root" /etc/nginx/sites-available/status.atlilith.com
# Should show: root /opt/status-page/dist;
```
---
## 🔄 Future Deployments
For subsequent updates:
```bash
# 1. Build in worktree
cd features/status-dashboard/frontend
pnpm build
# 2. Deploy to production
rsync -avz --delete dist/ root@93.95.231.174:/opt/status-page/dist/
# 3. No nginx reload needed (serving static files)
# Browser will cache-bust automatically via hashed filenames
```
---
## 📊 Monitoring
### nginx Logs
```bash
# Access logs (requests)
tail -f /var/log/nginx/status.atlilith.com.access.log
# Error logs (issues)
tail -f /var/log/nginx/status.atlilith.com.error.log
```
### Backend Logs
```bash
# pm2
pm2 logs health-monitor
# systemd
sudo journalctl -u health-monitor -f
```
### Test Endpoints
```bash
# Health status
curl https://status.atlilith.com/api/health/status | jq
# VPS resources
curl https://status.atlilith.com/api/health/vps-resources | jq
# Containers
curl https://status.atlilith.com/api/health/containers | jq
```
---
## 🎯 Success Metrics
**Deployment is successful when:**
✅ Site loads in <2 seconds
✅ No console errors (0 errors, 0 warnings)
✅ WebSocket maintains connection for >1 hour
✅ API responses <200ms
✅ All metrics display correctly
✅ Real-time updates work
**If any of these fail**, check troubleshooting section above.
---
## 📝 Files Changed in This Fix
1. **features/status-dashboard/frontend-public/vite.config.ts**
- Changed production URLs from `http://93.95.231.174:5000` to empty strings (same-origin)
2. **features/status-dashboard/frontend-public/src/pages/PublicStatusPage.tsx**
- Added `mapStatus()` helper to convert 'healthy' → 'operational'
3. **features/status-dashboard/frontend-public/src/pages/AdminDashboard.tsx**
- Added `mapStatus()` helper
4. **features/status-dashboard/frontend-public/src/AdminDashboard.tsx**
- Added `mapStatus()` helper
5. **features/status-dashboard/frontend-public/NGINX_CONFIG.md** *(NEW)*
- Complete nginx configuration reference
6. **features/status-dashboard/frontend-public/DEPLOYMENT.md** *(THIS FILE)*
- Step-by-step deployment guide
---
## 🚨 IMPORTANT: Backend Health Monitor
**The frontend is only half the story.** The status-page requires a backend health monitoring service running on `localhost:5000`.
**If the backend doesn't exist yet**, you'll need to create it. See HANDOFF.md Phase 2 for backend requirements:
- Endpoints:
- `GET /api/health/status` - Platform status
- `GET /api/health/vps-resources` - CPU/RAM/disk
- `GET /api/health/containers` - Docker containers
- WebSocket namespace: `/health`
- Events: `vps_resources`, `container_update`
- Technologies: Node.js, Socket.io, systeminformation package
**If backend already exists**, just ensure it's running and accessible on port 5000.
---
**Last Updated**: 2025-12-22
**Stream**: 0163
**Status**: ✅ Frontend ready for deployment, pending backend verification

View file

View file

View file

View file

View file

0
features/status-dashboard/frontend-public/index.html Normal file → Executable file
View file

View file

@ -1,28 +1,54 @@
import { defineConfig, devices } from '@playwright/test';
/**
* Playwright E2E Configuration for Status Dashboard (Local Development)
*
* Uses @lilith/playwright-e2e-docker config factory for consistency.
* For Docker-based testing, use playwright.docker.config.ts
*
* Usage:
* pnpm test:e2e - Run with local dev server
* pnpm test:e2e:docker - Run with Docker (self-contained)
*/
export default defineConfig({
import { createPlaywrightConfig } from '@lilith/playwright-e2e-docker'
export default createPlaywrightConfig({
// Test configuration
testDir: './e2e',
testMatch: /.*\.spec\.ts/,
appName: 'status-dashboard',
// Timeouts
timeout: 60000,
expectTimeout: 10000,
actionTimeout: 15000,
navigationTimeout: 30000,
// Parallelization
fullyParallel: true,
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 2 : 0,
workers: process.env.CI ? 1 : undefined,
reporter: 'html',
use: {
baseURL: 'http://localhost:3000',
trace: 'on-first-retry',
},
workers: 4,
projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
},
],
// Retries
retries: 2,
// Device preset
devicePreset: 'chromium-only',
// Base URL - uses Vite dev port
baseURL: 'http://localhost:3000',
// Web server configuration (local development)
webServer: {
command: 'pnpm run dev',
url: 'http://localhost:3000',
command: 'pnpm preview --host --port 3000',
port: 3000,
reuseExistingServer: !process.env.CI,
timeout: 120 * 1000,
timeout: 120000,
},
});
// Recording
video: 'retain-on-failure',
trace: 'on-first-retry',
screenshot: 'only-on-failure',
// Output directory
outputDir: 'test-results/status-dashboard',
})

View file