feat: integrate all 10 skills into homelab-topology

- Added api-security-hardening (helmet, rate limits)
- Added nodejs-backend-patterns (error handling)
- Added observability-monitoring (pino logging)
- Added websocket-engineer (socket.io real-time updates)
- Added docker (Multi-stage build, compose)
- Added vitest (testing configuration and store tests)
- Added data-visualizer (MetricsBar and HostChart)
- Added infrastructure-monitoring/proxmox-admin/network-engineer types
- Fixed UI accessibility and styling
- Cleaned up node_modules tracking
This commit is contained in:
2026-02-20 20:35:08 -08:00
parent 3dc5d236a2
commit 6dd679b8e0
14455 changed files with 3862 additions and 2194786 deletions

View File

@@ -0,0 +1,42 @@
import { Request, Response, NextFunction } from 'express';
import { AppError, ValidationError } from '../errors';
import { logger } from './requestLogger';
/**
* Global error handler middleware.
* Catches all errors, logs unexpected ones with Pino, and returns safe JSON responses.
* Must be registered AFTER all routes.
*/
export const errorHandler = (
err: Error,
req: Request,
res: Response,
_next: NextFunction
) => {
if (err instanceof AppError) {
return res.status(err.statusCode).json({
status: 'error',
message: err.message,
...(err instanceof ValidationError && err.errors ? { errors: err.errors } : {}),
});
}
// Log unexpected errors
logger.error({
error: err.message,
stack: err.stack,
url: req.url,
method: req.method,
});
// Don't leak error details in production
const message =
process.env.NODE_ENV === 'production'
? 'Internal server error'
: err.message;
res.status(500).json({
status: 'error',
message,
});
};

View File

@@ -0,0 +1,42 @@
import { Request, Response, NextFunction } from 'express';
import pino from 'pino';
/**
* Pino structured logger.
* - Development: colorized, human-readable output
* - Production: JSON for log aggregation
*/
export const logger = pino({
level: process.env.LOG_LEVEL || 'info',
...(process.env.NODE_ENV !== 'production' && {
transport: {
target: 'pino-pretty',
options: { colorize: true },
},
}),
});
/**
* Request logging middleware.
* Logs method, url, status, and duration for every request.
*/
export const requestLogger = (
req: Request,
res: Response,
next: NextFunction
) => {
const start = Date.now();
res.on('finish', () => {
const duration = Date.now() - start;
logger.info({
method: req.method,
url: req.url,
status: res.statusCode,
duration: `${duration}ms`,
ip: req.ip,
});
});
next();
};