feat: events date filter and preserve list page in URL (SAC 0.7.1)

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
PTah
2026-06-01 10:32:24 +10:00
parent de29270a25
commit 06a8ed8614
8 changed files with 230 additions and 36 deletions
+12 -4
View File
@@ -1,5 +1,5 @@
import logging
from datetime import datetime
from datetime import datetime, timezone
from typing import Any
from fastapi import APIRouter, Body, Depends, HTTPException, Query
@@ -100,10 +100,18 @@ def post_event(
return JSONResponse(status_code=status_code, content=body.model_dump(mode="json"))
def _parse_optional_dt(value: str | None) -> datetime | None:
def _parse_optional_dt(value: str | None, *, end_of_day: bool = False) -> datetime | None:
if not value:
return None
return datetime.fromisoformat(value.replace("Z", "+00:00"))
raw = value.strip()
if len(raw) == 10 and raw[4] == "-" and raw[7] == "-":
dt = datetime.fromisoformat(raw)
if dt.tzinfo is None:
dt = dt.replace(tzinfo=timezone.utc)
if end_of_day:
return dt.replace(hour=23, minute=59, second=59, microsecond=999999)
return dt.replace(hour=0, minute=0, second=0, microsecond=0)
return datetime.fromisoformat(raw.replace("Z", "+00:00"))
@router.get("", response_model=EventListResponse)
@@ -137,7 +145,7 @@ def list_events(
stmt = stmt.where(Host.hostname.ilike(like) | Host.display_name.ilike(like))
count_stmt = count_stmt.where(Host.hostname.ilike(like) | Host.display_name.ilike(like))
dt_from = _parse_optional_dt(from_time)
dt_to = _parse_optional_dt(to_time)
dt_to = _parse_optional_dt(to_time, end_of_day=True)
if dt_from:
stmt = stmt.where(Event.occurred_at >= dt_from)
count_stmt = count_stmt.where(Event.occurred_at >= dt_from)
+1 -1
View File
@@ -1,5 +1,5 @@
"""Единый источник версии SAC (API, health, логи, OpenAPI)."""
APP_NAME = "Security Alert Center"
APP_VERSION = "0.7.0"
APP_VERSION = "0.7.1"
APP_VERSION_LABEL = f"{APP_NAME} v.{APP_VERSION}"