diff --git a/server/routes.ts b/server/routes.ts index 9d0e21d..09b9884 100644 --- a/server/routes.ts +++ b/server/routes.ts @@ -63,8 +63,17 @@ export async function registerRoutes(app: Express): Promise { // Detections app.get("/api/detections", async (req, res) => { try { - const limit = parseInt(req.query.limit as string) || 100; - const detections = await storage.getAllDetections(limit); + const limit = req.query.limit ? parseInt(req.query.limit as string) : 500; + const anomalyType = req.query.anomalyType as string | undefined; + const minScore = req.query.minScore ? parseFloat(req.query.minScore as string) : undefined; + const maxScore = req.query.maxScore ? parseFloat(req.query.maxScore as string) : undefined; + + const detections = await storage.getAllDetections({ + limit, + anomalyType, + minScore, + maxScore + }); res.json(detections); } catch (error) { console.error('[DB ERROR] Failed to fetch detections:', error); @@ -181,7 +190,7 @@ export async function registerRoutes(app: Express): Promise { app.get("/api/stats", async (req, res) => { try { const routers = await storage.getAllRouters(); - const detections = await storage.getAllDetections(1000); + const detections = await storage.getAllDetections({ limit: 1000 }); const recentLogs = await storage.getRecentLogs(1000); const whitelist = await storage.getAllWhitelist(); const latestTraining = await storage.getLatestTraining(); diff --git a/server/storage.ts b/server/storage.ts index e6c5b63..45b028b 100644 --- a/server/storage.ts +++ b/server/storage.ts @@ -35,7 +35,12 @@ export interface IStorage { getLogsForTraining(limit: number, minTimestamp?: Date): Promise; // Detections - getAllDetections(limit: number): Promise; + getAllDetections(options: { + limit?: number; + anomalyType?: string; + minScore?: number; + maxScore?: number; + }): Promise; getDetectionByIp(sourceIp: string): Promise; createDetection(detection: InsertDetection): Promise; updateDetection(id: string, detection: Partial): Promise; @@ -140,12 +145,40 @@ export class DatabaseStorage implements IStorage { } // Detections - async getAllDetections(limit: number): Promise { - return await db + async getAllDetections(options: { + limit?: number; + anomalyType?: string; + minScore?: number; + maxScore?: number; + }): Promise { + const { limit = 500, anomalyType, minScore, maxScore } = options; + + // Build WHERE conditions + const conditions = []; + + if (anomalyType) { + conditions.push(eq(detections.anomalyType, anomalyType)); + } + + if (minScore !== undefined) { + conditions.push(gte(detections.riskScore, minScore.toString())); + } + + if (maxScore !== undefined) { + conditions.push(sql`${detections.riskScore}::numeric <= ${maxScore}`); + } + + const query = db .select() .from(detections) .orderBy(desc(detections.detectedAt)) .limit(limit); + + if (conditions.length > 0) { + return await query.where(and(...conditions)); + } + + return await query; } async getDetectionByIp(sourceIp: string): Promise {