pediatric-ai-scribe-v3/src/routes/logs.js
2026-05-08 19:08:19 +02:00

76 lines
2.7 KiB
JavaScript

var express = require('express');
var router = express.Router();
var { authMiddleware } = require('../middleware/auth');
var logger = require('../utils/logger');
var { redact } = require('../utils/redact');
function clampLimit(value, fallback, max) {
var n = parseInt(value, 10);
if (!Number.isFinite(n)) n = fallback;
return Math.min(Math.max(n, 1), max);
}
function trimField(value, max) {
if (value == null) return '';
var s = String(value);
return s.length > max ? s.slice(0, max) + '…' : s;
}
router.get('/logs/usage', authMiddleware, async function(req, res) {
try {
var days = clampLimit(req.query.days, 30, 365);
var summary = await logger.getUsageSummary(req.user.id, days);
res.json({ success: true, summary: summary, period: days + ' days' });
} catch (err) { res.status(500).json({ error: 'Request failed' }); }
});
router.get('/logs/audit', authMiddleware, async function(req, res) {
try {
var logs = await logger.getAuditLogs(req.user.id, clampLimit(req.query.limit, 50, 200));
res.json({ success: true, logs: logs });
} catch (err) { res.status(500).json({ error: 'Request failed' }); }
});
router.get('/logs/api', authMiddleware, async function(req, res) {
try {
var logs = await logger.getApiLogs(req.user.id, clampLimit(req.query.limit, 50, 200));
res.json({ success: true, logs: logs });
} catch (err) { res.status(500).json({ error: 'Request failed' }); }
});
router.get('/logs/access', authMiddleware, async function(req, res) {
try {
var logs = await logger.getAccessLogs(req.user.id, clampLimit(req.query.limit, 50, 200));
res.json({ success: true, logs: logs });
} catch (err) { res.status(500).json({ error: 'Request failed' }); }
});
// Client-side error receiver — no auth required (sendBeacon can't send auth headers)
router.post('/logs/client-error', function(req, res) {
try {
var e = req.body || {};
logger.warn('client_error', {
type: trimField(e.type, 80),
message: redact(trimField(e.message, 500)),
source: redact(trimField(e.source, 300)),
line: e.line,
col: e.col,
stack: redact(trimField(e.stack, 1200)),
ip: req.ip,
ua: trimField(req.headers['user-agent'], 255),
time: new Date().toISOString()
});
res.status(204).end();
} catch(err) { res.status(204).end(); }
});
// Client-side event logging (copy, export — PHI access tracking)
router.post('/logs/client-event', authMiddleware, function(req, res) {
try {
var e = req.body || {};
logger.audit(req.user.id, e.action || 'client_event', e.target || '', req, { category: 'phi_access' });
res.status(204).end();
} catch(err) { res.status(204).end(); }
});
module.exports = router;