feat: redesign Overview with active threats, severity donut, top processes bar
- Add /api/active-anomalies endpoint — latest snapshot per PID where is_anomaly=1 - Active threats card with pulsing indicator, CPU/RAM/TCP per process - Alerts by severity donut chart (high/medium/low) - Top processes horizontal bar chart weighted by alert count
This commit is contained in:
@@ -227,6 +227,24 @@ async def get_system_metrics(limit: int = 60) -> list[dict]:
|
||||
return list(reversed([dict(r) for r in rows]))
|
||||
|
||||
|
||||
@app.get("/api/active-anomalies", summary="Currently anomalous processes")
|
||||
async def get_active_anomalies() -> list[dict]:
|
||||
"""Latest snapshot per PID — only rows where is_anomaly=1."""
|
||||
async with aiosqlite.connect(DB_PATH) as db:
|
||||
db.row_factory = aiosqlite.Row
|
||||
async with db.execute("""
|
||||
SELECT m.*
|
||||
FROM metrics m
|
||||
INNER JOIN (
|
||||
SELECT pid, MAX(id) AS max_id FROM metrics GROUP BY pid
|
||||
) latest ON m.id = latest.max_id
|
||||
WHERE m.is_anomaly = 1
|
||||
ORDER BY m.cpu_percent DESC
|
||||
LIMIT 20
|
||||
""") as cur:
|
||||
return [dict(r) for r in await cur.fetchall()]
|
||||
|
||||
|
||||
@app.get("/api/file-events", summary="Recent filesystem events")
|
||||
async def get_file_events(limit: int = 100) -> list[dict]:
|
||||
"""Return the most recent *limit* filesystem events."""
|
||||
|
||||
Reference in New Issue
Block a user