feat: SAC daily reports from DB aggregation (notif-32)

- Aggregate report.daily.ssh/rdp from 24h ingest; job and systemd timer

- notify_daily_report bypasses NOTIFY_MIN_SEVERITY; ingest routes agent reports

- HTML templates, env SAC_DAILY_REPORT_*, docs and tests (56 cases)

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-05-29 16:30:07 +10:00
parent 4167687dec
commit 415d863b3b
17 changed files with 734 additions and 8 deletions
+25
View File
@@ -108,3 +108,28 @@ def test_ingest_invalid_payload_422(client, auth_headers):
)
assert r.status_code == 422
assert "schema_errors" in r.json()["detail"]
def test_ingest_daily_report_calls_notify_daily_report(client, auth_headers):
from unittest.mock import patch
from app.api.v1 import events as events_api
event_id = str(uuid.uuid4())
payload = {
**VALID_EVENT,
"event_id": event_id,
"category": "report",
"type": "report.daily.ssh",
"severity": "info",
"title": "Daily SSH report",
"summary": "stats",
"details": {"generated_by": "agent", "report_body": "line1"},
}
with patch.object(events_api, "notify_daily_report") as mock_daily:
with patch.object(events_api, "notify_event") as mock_event:
r = client.post("/api/v1/events", json=payload, headers=auth_headers)
assert r.status_code == 201
mock_daily.assert_called_once()
mock_event.assert_not_called()