diff --git a/backend/app/api/v1/events.py b/backend/app/api/v1/events.py
index 890f0ce..ad006a5 100644
--- a/backend/app/api/v1/events.py
+++ b/backend/app/api/v1/events.py
@@ -154,8 +154,10 @@ def list_events(
stmt = stmt.where(Event.severity == severity)
count_stmt = count_stmt.where(Event.severity == severity)
if type:
- stmt = stmt.where(Event.type == type)
- count_stmt = count_stmt.where(Event.type == type)
+ normalized = type.strip()
+ if normalized:
+ stmt = stmt.where(Event.type.ilike(f"{normalized}%"))
+ count_stmt = count_stmt.where(Event.type.ilike(f"{normalized}%"))
if host_id is not None:
stmt = stmt.where(Event.host_id == host_id)
count_stmt = count_stmt.where(Event.host_id == host_id)
diff --git a/backend/app/services/rdg_display.py b/backend/app/services/rdg_display.py
index 14e9049..f00eb86 100644
--- a/backend/app/services/rdg_display.py
+++ b/backend/app/services/rdg_display.py
@@ -69,7 +69,7 @@ def _windows_event_label(event: Event) -> str:
if win_id is None:
return ""
text = str(win_id).strip()
- return f"Win{text}" if text else ""
+ return f"event {text}" if text else ""
def _action_label(event: Event) -> str:
diff --git a/backend/app/version.py b/backend/app/version.py
index 5d62f10..576e16c 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.3.1"
+APP_VERSION = "0.3.2"
APP_VERSION_LABEL = f"{APP_NAME} v.{APP_VERSION}"
diff --git a/backend/tests/test_events_list_filter.py b/backend/tests/test_events_list_filter.py
new file mode 100644
index 0000000..f9d48d1
--- /dev/null
+++ b/backend/tests/test_events_list_filter.py
@@ -0,0 +1,54 @@
+"""Tests for GET /api/v1/events filters."""
+
+import uuid
+
+VALID_RDG = {
+ "schema_version": "1.0",
+ "occurred_at": "2026-05-27T10:00:00+03:00",
+ "source": {"product": "rdp-login-monitor", "product_version": "1.2.3-SAC"},
+ "host": {"hostname": "gw-filter-test", "os_family": "windows"},
+ "category": "auth",
+ "severity": "info",
+ "title": "RDG",
+ "summary": "pytest",
+}
+
+
+def _ingest(client, auth_headers, *, event_type: str) -> str:
+ event_id = str(uuid.uuid4())
+ payload = {**VALID_RDG, "event_id": event_id, "type": event_type}
+ assert client.post("/api/v1/events", json=payload, headers=auth_headers).status_code == 201
+ return event_id
+
+
+def test_events_type_filter_prefix(client, auth_headers, jwt_headers):
+ success_id = _ingest(client, auth_headers, event_type="rdg.connection.success")
+ disconnected_id = _ingest(client, auth_headers, event_type="rdg.connection.disconnected")
+ other_id = _ingest(client, auth_headers, event_type="rdp.login.success")
+
+ listed = client.get(
+ "/api/v1/events",
+ headers=jwt_headers,
+ params={"type": "rdg.connection", "hostname": "gw-filter-test", "page_size": 50},
+ )
+ assert listed.status_code == 200
+ body = listed.json()
+ ids = {row["event_id"] for row in body["items"]}
+ assert success_id in ids
+ assert disconnected_id in ids
+ assert other_id not in ids
+
+
+def test_events_type_filter_exact_still_works(client, auth_headers, jwt_headers):
+ success_id = _ingest(client, auth_headers, event_type="rdg.connection.success")
+ disconnected_id = _ingest(client, auth_headers, event_type="rdg.connection.disconnected")
+
+ listed = client.get(
+ "/api/v1/events",
+ headers=jwt_headers,
+ params={"type": "rdg.connection.success", "hostname": "gw-filter-test", "page_size": 50},
+ )
+ assert listed.status_code == 200
+ ids = {row["event_id"] for row in listed.json()["items"]}
+ assert success_id in ids
+ assert disconnected_id not in ids
diff --git a/backend/tests/test_health.py b/backend/tests/test_health.py
index b792ae5..5442deb 100644
--- a/backend/tests/test_health.py
+++ b/backend/tests/test_health.py
@@ -4,6 +4,6 @@ from app.version import APP_NAME, APP_VERSION, APP_VERSION_LABEL
def test_version_constants():
- assert APP_VERSION == "0.3.1"
+ assert APP_VERSION == "0.3.2"
assert APP_NAME == "Security Alert Center"
- assert APP_VERSION_LABEL == "Security Alert Center v.0.3.1"
+ assert APP_VERSION_LABEL == "Security Alert Center v.0.3.2"
diff --git a/backend/tests/test_rdg_display.py b/backend/tests/test_rdg_display.py
index 791446b..5d13fc7 100644
--- a/backend/tests/test_rdg_display.py
+++ b/backend/tests/test_rdg_display.py
@@ -85,6 +85,7 @@ def test_build_rdg_display_title_and_path(db_session, monkeypatch):
assert display.qwinsta_enabled is True
assert "papatramp" in display.summary
assert "шлюз K6A-DC3" in display.summary
+ assert "event 302" in display.title
def test_event_to_summary_enriches_rdg(db_session, monkeypatch):
diff --git a/frontend/src/version.ts b/frontend/src/version.ts
index 3da26e5..ce9ef64 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.3.1";
+export const APP_VERSION = "0.3.2";
export const APP_VERSION_LABEL = `${APP_NAME} v.${APP_VERSION}`;
diff --git a/frontend/src/views/EventsView.vue b/frontend/src/views/EventsView.vue
index 76a452f..b93ca4d 100644
--- a/frontend/src/views/EventsView.vue
+++ b/frontend/src/views/EventsView.vue
@@ -9,7 +9,7 @@
-
+