From fed21c536bcff7ba7e76abae7d9737944530388e Mon Sep 17 00:00:00 2001 From: PTah Date: Thu, 11 Jun 2026 10:24:12 +1000 Subject: [PATCH] fix: exclude resolved problems from new-in-24h metrics (0.9.7) Dashboard and created_within_hours list only show open/acknowledged problems created in the last 24 hours; closed items appear under resolved only. Co-authored-by: Cursor --- backend/app/api/v1/dashboards.py | 8 +++++++- backend/app/api/v1/problems.py | 4 ++-- backend/app/version.py | 2 +- backend/tests/test_dashboard.py | 2 +- backend/tests/test_problems.py | 32 +++++++++++++++++++++++++++++ frontend/src/version.ts | 2 +- frontend/src/views/ProblemsView.vue | 2 +- 7 files changed, 45 insertions(+), 7 deletions(-) diff --git a/backend/app/api/v1/dashboards.py b/backend/app/api/v1/dashboards.py index 7bd35d8..8774762 100644 --- a/backend/app/api/v1/dashboards.py +++ b/backend/app/api/v1/dashboards.py @@ -82,7 +82,13 @@ def dashboard_summary( db.scalar(select(func.count()).select_from(Problem).where(Problem.status == "open")) or 0 ) problems_opened_24h = ( - db.scalar(select(func.count()).select_from(Problem).where(Problem.created_at >= since)) or 0 + db.scalar( + select(func.count()).select_from(Problem).where( + Problem.created_at >= since, + Problem.status != "resolved", + ) + ) + or 0 ) problems_resolved_24h = ( db.scalar( diff --git a/backend/app/api/v1/problems.py b/backend/app/api/v1/problems.py index 4e9bd14..2aa9ad8 100644 --- a/backend/app/api/v1/problems.py +++ b/backend/app/api/v1/problems.py @@ -202,9 +202,9 @@ def list_problems( since = datetime.now(timezone.utc) - timedelta(hours=created_within_hours) - stmt = stmt.where(Problem.created_at >= since) + stmt = stmt.where(Problem.created_at >= since, Problem.status != "resolved") - count_stmt = count_stmt.where(Problem.created_at >= since) + count_stmt = count_stmt.where(Problem.created_at >= since, Problem.status != "resolved") if resolved_within_hours is not None: diff --git a/backend/app/version.py b/backend/app/version.py index 8fb610f..09637d6 100644 --- a/backend/app/version.py +++ b/backend/app/version.py @@ -1,5 +1,5 @@ """Единый источник версии SAC (API, health, логи, OpenAPI).""" APP_NAME = "Security Alert Center" -APP_VERSION = "0.9.6" +APP_VERSION = "0.9.7" APP_VERSION_LABEL = f"{APP_NAME} v.{APP_VERSION}" diff --git a/backend/tests/test_dashboard.py b/backend/tests/test_dashboard.py index 9ef1737..3f4dbba 100644 --- a/backend/tests/test_dashboard.py +++ b/backend/tests/test_dashboard.py @@ -83,7 +83,7 @@ def test_dashboard_summary_top_and_problems_24h(client, db_session, jwt_headers) body = r.json() assert body["events_last_24h"] == 5 assert body["problems_open"] == 1 - assert body["problems_opened_24h"] == 2 + assert body["problems_opened_24h"] == 1 assert body["problems_resolved_24h"] == 1 assert body["top_hosts"][0]["hostname"] == "web-01" assert body["top_hosts"][0]["count"] == 3 diff --git a/backend/tests/test_problems.py b/backend/tests/test_problems.py index 59d997a..62c862b 100644 --- a/backend/tests/test_problems.py +++ b/backend/tests/test_problems.py @@ -119,6 +119,38 @@ def test_problems_created_within_hours(client, db_session, jwt_headers): assert body["items"][0]["title"] == "recent" +def test_problems_created_within_hours_excludes_resolved(client, db_session, jwt_headers): + now = datetime.now(timezone.utc) + h = Host( + hostname="p-host2", + os_family="linux", + product="ssh-monitor", + last_seen_at=now, + ) + db_session.add(h) + db_session.flush() + db_session.add( + Problem( + host_id=h.id, + title="closed recently", + summary="s", + severity="warning", + status="resolved", + rule_id="rule:test", + fingerprint="fp-closed-recent", + event_count=1, + last_seen_at=now, + created_at=now - timedelta(hours=1), + updated_at=now - timedelta(minutes=30), + ) + ) + db_session.commit() + + r = client.get("/api/v1/problems?created_within_hours=24", headers=jwt_headers) + assert r.status_code == 200 + assert r.json()["total"] == 0 + + def test_problems_resolved_within_hours(client, db_session, jwt_headers): now = datetime.now(timezone.utc) h = Host( diff --git a/frontend/src/version.ts b/frontend/src/version.ts index a245fa9..b93357c 100644 --- a/frontend/src/version.ts +++ b/frontend/src/version.ts @@ -1,4 +1,4 @@ /** Fallback до загрузки /health; при релизе держите в sync с backend/app/version.py */ export const APP_NAME = "Security Alert Center"; -export const APP_VERSION = "0.9.6"; +export const APP_VERSION = "0.9.7"; export const APP_VERSION_LABEL = `${APP_NAME} v.${APP_VERSION}`; diff --git a/frontend/src/views/ProblemsView.vue b/frontend/src/views/ProblemsView.vue index cd37068..b264378 100644 --- a/frontend/src/views/ProblemsView.vue +++ b/frontend/src/views/ProblemsView.vue @@ -113,7 +113,7 @@ const actingId = ref(null); const timeFilterHint = computed(() => { if (createdWithinHours.value) { - return `Показаны проблемы, созданные за последние ${createdWithinHours.value} ч (любой статус).`; + return `Показаны активные проблемы, созданные за последние ${createdWithinHours.value} ч (без закрытых).`; } if (resolvedWithinHours.value) { return `Показаны проблемы, закрытые за последние ${resolvedWithinHours.value} ч.`;