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:
PTah
2026-05-29 16:30:07 +10:00
parent 4167687dec
commit 415d863b3b
17 changed files with 734 additions and 8 deletions
@@ -159,7 +159,25 @@ def format_generic_event_html(event: Event) -> str:
return msg.rstrip()
def format_daily_report_html(event: Event) -> str:
details = _details_dict(event)
report_html = details.get("report_html")
if isinstance(report_html, str) and report_html.strip():
# Уже HTML от агента или SAC
return report_html.strip()
body = _detail(details, "report_body", default=event.summary)
if body != "-":
escaped = html.escape(body)
return (
f"<b>📊 {html_escape(event.title)}</b>\n"
f'<div class="agent-report">{escaped.replace(chr(10), "<br>")}</div>'
)
return format_generic_event_html(event)
def format_event_telegram_html(event: Event) -> str:
if event.type in ("report.daily.ssh", "report.daily.rdp"):
return format_daily_report_html(event)
if event.type in ("rdp.login.success", "rdp.login.failed"):
return format_rdp_login_html(event)
if event.type in ("ssh.login.success", "ssh.login.failed"):