feat: initial project scaffold

- React 19 + Vite + TailwindCSS frontend
- Express + TypeScript backend API
- PostgreSQL schema and migrations
- Docker Compose orchestration
- Drone CI/CD pipeline
- Pages: Dashboard, Servers, Containers, Services, Logs, Metrics, Settings
This commit is contained in:
Ernie Butcher
2026-03-18 17:09:08 -04:00
commit 65471c2a70
54 changed files with 7304 additions and 0 deletions

98
backend/src/db/migrate.ts Normal file
View File

@@ -0,0 +1,98 @@
import pool from './index';
export const runMigrations = async () => {
const client = await pool.connect();
try {
await client.query('BEGIN');
// Create servers table
await client.query(`
CREATE TABLE IF NOT EXISTS servers (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name VARCHAR(255) NOT NULL,
hostname VARCHAR(255) NOT NULL,
ip_address VARCHAR(45) NOT NULL,
port INTEGER DEFAULT 22,
username VARCHAR(100),
ssh_key_path TEXT,
status VARCHAR(50) DEFAULT 'unknown',
tags JSONB DEFAULT '[]',
metadata JSONB DEFAULT '{}',
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);
`);
// Create containers table
await client.query(`
CREATE TABLE IF NOT EXISTS containers (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
server_id UUID REFERENCES servers(id) ON DELETE CASCADE,
container_id VARCHAR(255) NOT NULL,
name VARCHAR(255) NOT NULL,
image VARCHAR(255),
status VARCHAR(50),
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);
`);
// Create services table
await client.query(`
CREATE TABLE IF NOT EXISTS services (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
server_id UUID REFERENCES servers(id) ON DELETE CASCADE,
name VARCHAR(255) NOT NULL,
type VARCHAR(50) NOT NULL,
status VARCHAR(50),
port INTEGER,
config JSONB DEFAULT '{}',
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);
`);
// Create metrics table
await client.query(`
CREATE TABLE IF NOT EXISTS metrics (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
server_id UUID REFERENCES servers(id) ON DELETE CASCADE,
cpu_usage DECIMAL(5,2),
memory_usage DECIMAL(5,2),
disk_usage DECIMAL(5,2),
network_rx BIGINT,
network_tx BIGINT,
timestamp TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);
`);
// Create index on metrics for faster queries
await client.query(`
CREATE INDEX IF NOT EXISTS idx_metrics_server_timestamp
ON metrics(server_id, timestamp DESC);
`);
await client.query('COMMIT');
console.log('✅ Database migrations completed successfully');
} catch (error) {
await client.query('ROLLBACK');
console.error('❌ Migration error:', error);
throw error;
} finally {
client.release();
}
};
// Run migrations if this file is executed directly
if (require.main === module) {
runMigrations()
.then(() => {
console.log('Migration complete');
process.exit(0);
})
.catch((error) => {
console.error('Migration failed:', error);
process.exit(1);
});
}