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 <cursoragent@cursor.com>
This commit is contained in:
@@ -82,7 +82,13 @@ def dashboard_summary(
|
|||||||
db.scalar(select(func.count()).select_from(Problem).where(Problem.status == "open")) or 0
|
db.scalar(select(func.count()).select_from(Problem).where(Problem.status == "open")) or 0
|
||||||
)
|
)
|
||||||
problems_opened_24h = (
|
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 = (
|
problems_resolved_24h = (
|
||||||
db.scalar(
|
db.scalar(
|
||||||
|
|||||||
@@ -202,9 +202,9 @@ def list_problems(
|
|||||||
|
|
||||||
since = datetime.now(timezone.utc) - timedelta(hours=created_within_hours)
|
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:
|
if resolved_within_hours is not None:
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
"""Единый источник версии SAC (API, health, логи, OpenAPI)."""
|
"""Единый источник версии SAC (API, health, логи, OpenAPI)."""
|
||||||
|
|
||||||
APP_NAME = "Security Alert Center"
|
APP_NAME = "Security Alert Center"
|
||||||
APP_VERSION = "0.9.6"
|
APP_VERSION = "0.9.7"
|
||||||
APP_VERSION_LABEL = f"{APP_NAME} v.{APP_VERSION}"
|
APP_VERSION_LABEL = f"{APP_NAME} v.{APP_VERSION}"
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ def test_dashboard_summary_top_and_problems_24h(client, db_session, jwt_headers)
|
|||||||
body = r.json()
|
body = r.json()
|
||||||
assert body["events_last_24h"] == 5
|
assert body["events_last_24h"] == 5
|
||||||
assert body["problems_open"] == 1
|
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["problems_resolved_24h"] == 1
|
||||||
assert body["top_hosts"][0]["hostname"] == "web-01"
|
assert body["top_hosts"][0]["hostname"] == "web-01"
|
||||||
assert body["top_hosts"][0]["count"] == 3
|
assert body["top_hosts"][0]["count"] == 3
|
||||||
|
|||||||
@@ -119,6 +119,38 @@ def test_problems_created_within_hours(client, db_session, jwt_headers):
|
|||||||
assert body["items"][0]["title"] == "recent"
|
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):
|
def test_problems_resolved_within_hours(client, db_session, jwt_headers):
|
||||||
now = datetime.now(timezone.utc)
|
now = datetime.now(timezone.utc)
|
||||||
h = Host(
|
h = Host(
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/** Fallback до загрузки /health; при релизе держите в sync с backend/app/version.py */
|
/** Fallback до загрузки /health; при релизе держите в sync с backend/app/version.py */
|
||||||
export const APP_NAME = "Security Alert Center";
|
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}`;
|
export const APP_VERSION_LABEL = `${APP_NAME} v.${APP_VERSION}`;
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ const actingId = ref<number | null>(null);
|
|||||||
|
|
||||||
const timeFilterHint = computed(() => {
|
const timeFilterHint = computed(() => {
|
||||||
if (createdWithinHours.value) {
|
if (createdWithinHours.value) {
|
||||||
return `Показаны проблемы, созданные за последние ${createdWithinHours.value} ч (любой статус).`;
|
return `Показаны активные проблемы, созданные за последние ${createdWithinHours.value} ч (без закрытых).`;
|
||||||
}
|
}
|
||||||
if (resolvedWithinHours.value) {
|
if (resolvedWithinHours.value) {
|
||||||
return `Показаны проблемы, закрытые за последние ${resolvedWithinHours.value} ч.`;
|
return `Показаны проблемы, закрытые за последние ${resolvedWithinHours.value} ч.`;
|
||||||
|
|||||||
Reference in New Issue
Block a user