Files
task-team/api/src/routes/system.js
Claude CLI Agent 4fae1c5a06 i18n complete: all 16 components translated (CZ/HE/RU/UA)
- Custom i18n provider with React Context + localStorage
- Hebrew RTL support (dir=rtl on html)
- All pages + components use t() calls
- FullCalendar + dates locale-aware
- Language selector in Settings wired to context

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 13:19:02 +00:00

78 lines
2.8 KiB
JavaScript

// System health & monitoring routes — 2026-03-29
module.exports = async function systemRoutes(app, opts) {
const os = require('os');
// GET /api/v1/system/health — comprehensive system status
app.get('/system/health', async (request, reply) => {
// System info
const system = {
hostname: os.hostname(),
uptime: Math.floor(os.uptime()),
loadavg: os.loadavg(),
cpus: os.cpus().length,
memory: {
total: Math.round(os.totalmem() / 1024 / 1024),
free: Math.round(os.freemem() / 1024 / 1024),
used_pct: Math.round((1 - os.freemem() / os.totalmem()) * 100)
}
};
// DB check
let db_status = { status: 'error' };
try {
const { rows } = await app.db.query('SELECT NOW() as time, pg_database_size(current_database()) as size');
db_status = {
status: 'ok',
time: rows[0].time,
size_mb: Math.round(rows[0].size / 1024 / 1024)
};
} catch (e) {
db_status = { status: 'error', message: e.message };
}
// Redis check
let redis_status = { status: 'error' };
try {
const pong = await app.redis.ping();
const info = await app.redis.info('memory');
const usedMem = info.match(/used_memory_human:(.+)/)?.[1]?.trim();
redis_status = {
status: pong === 'PONG' ? 'ok' : 'error',
memory: usedMem
};
} catch (e) {
redis_status = { status: 'error', message: e.message };
}
// Task stats
let task_stats = {};
try {
const { rows } = await app.db.query(`
SELECT status, count(*)::int as count FROM tasks GROUP BY status
UNION ALL SELECT 'total', count(*)::int FROM tasks
UNION ALL SELECT 'users', count(*)::int FROM users
UNION ALL SELECT 'goals', count(*)::int FROM goals
`);
task_stats = Object.fromEntries(rows.map(r => [r.status, r.count]));
} catch (e) {
task_stats = { error: e.message };
}
// Determine overall status
const overall = (db_status.status === 'ok' && redis_status.status === 'ok') ? 'ok' : 'degraded';
return {
status: overall,
timestamp: new Date().toISOString(),
system,
database: db_status,
redis: redis_status,
tasks: task_stats,
version: require('../../package.json').version || '1.0.0'
};
});
// GET /api/v1/system/ping — lightweight liveness check
app.get('/system/ping', async () => ({ pong: true, ts: Date.now() }));
};