Dieser Commit ist enthalten in:
Claude Project Manager
2025-12-28 21:36:45 +00:00
Commit ab1e5be9a9
146 geänderte Dateien mit 65525 neuen und 0 gelöschten Zeilen

158
backend/routes/health.js Normale Datei
Datei anzeigen

@ -0,0 +1,158 @@
/**
* TASKMATE - Health Check Routes
* ==============================
* Server-Status und Health-Check Endpoints
*/
const express = require('express');
const router = express.Router();
const fs = require('fs');
const path = require('path');
const { getDb } = require('../database');
const backup = require('../utils/backup');
/**
* GET /api/health
* Einfacher Health-Check
*/
router.get('/', (req, res) => {
try {
// Datenbank-Check
const db = getDb();
db.prepare('SELECT 1').get();
res.json({
status: 'healthy',
timestamp: new Date().toISOString()
});
} catch (error) {
res.status(503).json({
status: 'unhealthy',
error: error.message,
timestamp: new Date().toISOString()
});
}
});
/**
* GET /api/health/detailed
* Detaillierter Health-Check (mit Auth)
*/
router.get('/detailed', (req, res) => {
try {
const db = getDb();
// Datenbank-Statistiken
const userCount = db.prepare('SELECT COUNT(*) as count FROM users').get().count;
const projectCount = db.prepare('SELECT COUNT(*) as count FROM projects WHERE archived = 0').get().count;
const taskCount = db.prepare('SELECT COUNT(*) as count FROM tasks WHERE archived = 0').get().count;
// Disk-Space für Uploads
const uploadsDir = process.env.UPLOAD_DIR || path.join(__dirname, '..', 'uploads');
let uploadsSize = 0;
let uploadCount = 0;
if (fs.existsSync(uploadsDir)) {
const getDirectorySize = (dir) => {
let size = 0;
let count = 0;
const files = fs.readdirSync(dir);
for (const file of files) {
const filePath = path.join(dir, file);
const stats = fs.statSync(filePath);
if (stats.isDirectory()) {
const subResult = getDirectorySize(filePath);
size += subResult.size;
count += subResult.count;
} else {
size += stats.size;
count++;
}
}
return { size, count };
};
const result = getDirectorySize(uploadsDir);
uploadsSize = result.size;
uploadCount = result.count;
}
// Letzte Backups
const backups = backup.listBackups().slice(0, 5);
// Memory Usage
const memUsage = process.memoryUsage();
res.json({
status: 'healthy',
timestamp: new Date().toISOString(),
uptime: Math.floor(process.uptime()),
database: {
users: userCount,
projects: projectCount,
tasks: taskCount
},
storage: {
uploadCount,
uploadsSizeMB: Math.round(uploadsSize / 1024 / 1024 * 100) / 100
},
backups: backups.map(b => ({
name: b.name,
sizeMB: Math.round(b.size / 1024 / 1024 * 100) / 100,
created: b.created
})),
memory: {
heapUsedMB: Math.round(memUsage.heapUsed / 1024 / 1024 * 100) / 100,
heapTotalMB: Math.round(memUsage.heapTotal / 1024 / 1024 * 100) / 100,
rssMB: Math.round(memUsage.rss / 1024 / 1024 * 100) / 100
},
environment: process.env.NODE_ENV || 'development'
});
} catch (error) {
res.status(503).json({
status: 'unhealthy',
error: error.message,
timestamp: new Date().toISOString()
});
}
});
/**
* POST /api/health/backup
* Manuelles Backup auslösen
*/
router.post('/backup', (req, res) => {
try {
const backupPath = backup.createBackup();
if (backupPath) {
res.json({
message: 'Backup erfolgreich erstellt',
path: path.basename(backupPath)
});
} else {
res.status(500).json({ error: 'Backup fehlgeschlagen' });
}
} catch (error) {
res.status(500).json({ error: error.message });
}
});
/**
* GET /api/health/backups
* Liste aller Backups
*/
router.get('/backups', (req, res) => {
try {
const backups = backup.listBackups();
res.json(backups.map(b => ({
name: b.name,
sizeMB: Math.round(b.size / 1024 / 1024 * 100) / 100,
created: b.created
})));
} catch (error) {
res.status(500).json({ error: error.message });
}
});
module.exports = router;