pediatric-ai-scribe-v3/src/routes/logs.js
Daniel 011fae9b7a Enhance audit logging: user agent, session ID, PHI access tracking
Loki logs now include:
- User agent string (browser/device identification)
- Session ID (ties actions to specific login session)
- Status field (success/failure)

New logging:
- encounter_load: logged when user opens a saved encounter (with label)
- copy_to_clipboard: logged when user copies note content (PHI access)
- Client event endpoint: POST /api/logs/client-event (auth required)

Encounter save/delete/load all include the encounter label for
patient identification in audit trail.

HIPAA audit trail now covers: who, what, when, from where, which
device, which session, what patient data, success/failure.
2026-04-11 06:17:05 +02:00

63 lines
2.2 KiB
JavaScript

var express = require('express');
var router = express.Router();
var { authMiddleware } = require('../middleware/auth');
var logger = require('../utils/logger');
router.get('/logs/usage', authMiddleware, async function(req, res) {
try {
var days = parseInt(req.query.days) || 30;
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: err.message }); }
});
router.get('/logs/audit', authMiddleware, async function(req, res) {
try {
var logs = await logger.getAuditLogs(req.user.id, parseInt(req.query.limit) || 50);
res.json({ success: true, logs: logs });
} catch (err) { res.status(500).json({ error: err.message }); }
});
router.get('/logs/api', authMiddleware, async function(req, res) {
try {
var logs = await logger.getApiLogs(req.user.id, parseInt(req.query.limit) || 50);
res.json({ success: true, logs: logs });
} catch (err) { res.status(500).json({ error: err.message }); }
});
router.get('/logs/access', authMiddleware, async function(req, res) {
try {
var logs = await logger.getAccessLogs(req.user.id, parseInt(req.query.limit) || 50);
res.json({ success: true, logs: logs });
} catch (err) { res.status(500).json({ error: err.message }); }
});
// 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 || {};
console.error('[CLIENT ERROR]', JSON.stringify({
type: e.type,
message: e.message,
source: e.source,
line: e.line,
col: e.col,
stack: e.stack,
ip: req.ip,
ua: req.headers['user-agent'],
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;