docs: enterprise refactor plan with ralph specs
This commit is contained in:
93
dist/server/routes/anomalies.js
vendored
Normal file
93
dist/server/routes/anomalies.js
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.createAnomalyRouter = createAnomalyRouter;
|
||||
const express_1 = require("express");
|
||||
const fs_1 = __importDefault(require("fs"));
|
||||
function createAnomalyRouter(store, enrichmentService) {
|
||||
const router = (0, express_1.Router)();
|
||||
// GET /api/anomalies — list all anomalies (optionally filtered)
|
||||
router.get('/', (req, res) => {
|
||||
const sessionId = req.query['sessionId'];
|
||||
const severity = req.query['severity'];
|
||||
const anomalies = store.getAllAnomalies(sessionId, severity);
|
||||
const mapped = anomalies.map((a) => ({
|
||||
id: a.id,
|
||||
sessionId: store.findSessionForAnomaly(a.id),
|
||||
type: a.type,
|
||||
severity: a.severity,
|
||||
description: a.description,
|
||||
timestamp: a.timestamp,
|
||||
screenshotUrl: a.evidence.screenshotPath
|
||||
? `/api/anomalies/${a.id}/screenshot`
|
||||
: undefined,
|
||||
}));
|
||||
res.json(mapped);
|
||||
});
|
||||
// GET /api/anomalies/:anomalyId — full anomaly detail
|
||||
router.get('/:anomalyId', (req, res) => {
|
||||
const anomalyId = req.params['anomalyId'];
|
||||
const anomaly = store.getAnomaly(anomalyId);
|
||||
if (!anomaly) {
|
||||
res.status(404).json({ error: 'Anomaly not found' });
|
||||
return;
|
||||
}
|
||||
res.json({
|
||||
...anomaly,
|
||||
sessionId: store.findSessionForAnomaly(anomaly.id),
|
||||
screenshotUrl: anomaly.evidence.screenshotPath
|
||||
? `/api/anomalies/${anomaly.id}/screenshot`
|
||||
: undefined,
|
||||
});
|
||||
});
|
||||
// GET /api/anomalies/:anomalyId/screenshot — serve PNG
|
||||
router.get('/:anomalyId/screenshot', (req, res) => {
|
||||
const anomalyId = req.params['anomalyId'];
|
||||
const filePath = store.screenshotPath(anomalyId);
|
||||
if (!filePath || !fs_1.default.existsSync(filePath)) {
|
||||
res.status(404).json({ error: 'Screenshot not found' });
|
||||
return;
|
||||
}
|
||||
res.setHeader('Content-Type', 'image/png');
|
||||
fs_1.default.createReadStream(filePath).pipe(res);
|
||||
});
|
||||
// POST /api/anomalies/:anomalyId/replay — trigger replay
|
||||
router.post('/:anomalyId/replay', async (req, res) => {
|
||||
const anomalyId = req.params['anomalyId'];
|
||||
try {
|
||||
const replayId = await store.replayAnomaly(anomalyId);
|
||||
res.json({ replayId, status: 'running' });
|
||||
}
|
||||
catch (err) {
|
||||
const msg = err instanceof Error ? err.message : String(err);
|
||||
res.status(404).json({ error: msg });
|
||||
}
|
||||
});
|
||||
// POST /api/anomalies/:anomalyId/enrich — AI enrichment
|
||||
router.post('/:anomalyId/enrich', async (req, res) => {
|
||||
const anomalyId = req.params['anomalyId'];
|
||||
const anomaly = store.getAnomaly(anomalyId);
|
||||
if (!anomaly) {
|
||||
res.status(404).json({ error: 'Anomaly not found' });
|
||||
return;
|
||||
}
|
||||
if (!enrichmentService?.hasProvider()) {
|
||||
res.status(503).json({ error: 'No AI provider configured (set ABE_AI_PROVIDER)' });
|
||||
return;
|
||||
}
|
||||
const context = {
|
||||
domSnapshot: '',
|
||||
httpLog: anomaly.evidence.httpLog ?? [],
|
||||
consoleErrors: anomaly.evidence.rawErrors ?? [],
|
||||
actionTrace: anomaly.actionTrace,
|
||||
pageTitle: '',
|
||||
url: anomaly.actionTrace[anomaly.actionTrace.length - 1]?.url ?? '',
|
||||
};
|
||||
// Run async — emit WS event when done
|
||||
void enrichmentService.enrich(anomaly, context);
|
||||
res.json({ status: 'enriching', anomalyId });
|
||||
});
|
||||
return router;
|
||||
}
|
||||
Reference in New Issue
Block a user