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:
@@ -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)
|
||||
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren