feat(activity): one Activity page — runs, admin actions, server log and quota under one filter bar

The audit log, the server log and the admin quota view were three pages (the quota one a Stats tab),
each with its own filters, and the background runs had no list at all. Now one page ("Napló" /
"Activity") reads all four, each still its own table on the server: a shared bar (text, a period of
1 h to 90 days defaulting to 7, an account) and each tab's own filters, the whole view in the URL.
The old page ids open their tab.

Server side: the audit log and the new run list (`/api/admin/runs`) filter and page like the server
log, through one keyset helper (`routes/_keyset`) the log now shares; an audit row keeps the request
it was made in (migration 0111), so its log lines are a pivot away, as a run's are (`lrun`). The
quota breakdown takes since/until and one account. The Scheduler rows get a history button to their
job's runs.

Also fixed on the way: re-saving the value in force on the Configuration page staged its override
without committing it (the commit sat inside the audit branch), so the save was lost.
This commit is contained in:
2026-10-18 03:45:18 +02:00
parent d13483a593
commit 24448e7c6f
66 changed files with 2723 additions and 1119 deletions
+7 -5
View File
@@ -572,11 +572,12 @@ class QuotaEvent(Base):
class AuditLog(Base):
"""Append-only admin/scheduler audit trail: who did what, when, and (where it applies)
the before->after values. `actor_id` is the acting admin; NULL means the scheduler /
background did it (SET NULL on user delete keeps the trail). Logged at ACTION / job-run
granularity — never per-row — so a scheduler run that touches thousands of videos is ONE
row summarising the outcome. `before`/`after` are small JSON snapshots (secrets excluded)."""
"""Append-only admin audit trail: who did what, when, and (where it applies) the before->after
values. `actor_id` is the acting admin; NULL means the background did it (SET NULL on user
delete keeps the trail). Logged per ACTION, never per row; a background run is not an action
and has its own history (`JobRun`). `before`/`after` are small JSON snapshots (secrets
excluded). `request_id` is the request that made the change, so its log lines are one click
away (NULL for rows written outside a request, and for rows older than the column)."""
__tablename__ = "audit_log"
@@ -593,6 +594,7 @@ class AuditLog(Base):
created_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True), server_default=func.now(), index=True
)
request_id: Mapped[str | None] = mapped_column(String(64), index=True)
class LogEvent(Base):