Phase 5: Audit-Spur pro Quelle (ausklappbares Modal)

Backend
- routers/audit.py: GET /api/audit-log nimmt jetzt resource_id als Filter
  (zusätzlich zu resource_type, action, admin_id, from_ts/to_ts).

Frontend
- dashboard.html: modalAudit (Modal) für die Audit-Spur einer Ressource.
- style.css: audit-entry Styles (action-Badge mit Farbcode pro Action-Typ,
  Diff als <details>-Block mit JSON-Pre).
- sources.js:
  - showSourceAudit(id, name) öffnet Modal, lädt /audit-log?resource_type=source&resource_id=...
  - renderAuditEntries: pro Eintrag Action-Badge + Meta (ts/admin/ip) +
    optional ausklappbarer Diff (before/after-JSON)
  - formatDateTime Helper
  - Audit-Button in der Aktionen-Spalte der Grundquellen-Tabelle
Dieser Commit ist enthalten in:
claude-dev
2026-05-09 03:19:32 +00:00
Ursprung 2001815e19
Commit 6b70a7195e
4 geänderte Dateien mit 131 neuen und 0 gelöschten Zeilen

Datei anzeigen

@@ -24,6 +24,7 @@ def _parse_json(s: Optional[str]):
async def list_audit(
action: Optional[str] = None,
resource_type: Optional[str] = None,
resource_id: Optional[int] = None,
admin_id: Optional[int] = None,
from_ts: Optional[str] = None,
to_ts: Optional[str] = None,
@@ -46,6 +47,9 @@ async def list_audit(
if resource_type:
where.append("resource_type = ?")
params.append(resource_type)
if resource_id is not None:
where.append("resource_id = ?")
params.append(resource_id)
if admin_id is not None:
where.append("admin_id = ?")
params.append(admin_id)