2026-06-15 00:30:34 +02:00
{
"feed" : "Feed" ,
"searchPlaceholder" : "Deine Abos durchsuchen…" ,
2026-07-01 04:22:39 +02:00
"clearSearch" : "Suche löschen" ,
2026-06-29 02:01:44 +02:00
"searchYoutube" : "Auf YouTube suchen" ,
"searchYoutubeTip" : "Live auf YouTube nach diesem Begriff suchen (verbraucht gemeinsames API-Kontingent). Du kannst auch Enter drücken." ,
2026-07-13 02:28:06 +02:00
"go" : "Los" ,
"goTip" : "Suchen (oder Enter drücken)" ,
"prevModule" : "Vorheriges Modul" ,
"nextModule" : "Nächstes Modul" ,
2026-06-15 00:30:34 +02:00
"channelManager" : "Kanalverwaltung" ,
"usageStats" : "Nutzung & Statistik" ,
2026-06-16 14:38:51 +02:00
"scheduler" : "Planer" ,
2026-06-19 12:23:00 +02:00
"configuration" : "Konfiguration" ,
2026-06-19 14:16:48 +02:00
"users" : "Benutzer" ,
2026-06-15 04:06:22 +02:00
"scope" : {
"label" : "Feed-Quelle" ,
"my" : "Meine" ,
"myTip" : "Nur Videos aus deinen eigenen Abos" ,
"all" : "Bibliothek" ,
"allTip" : "Alle Videos im gemeinsamen Katalog"
} ,
2026-06-15 00:30:34 +02:00
"account" : {
"admin" : "Admin" ,
"feed" : "Feed" ,
"channels" : "Kanäle" ,
2026-06-15 14:45:18 +02:00
"playlists" : "Wiedergabelisten" ,
2026-06-15 00:30:34 +02:00
"stats" : "Statistik" ,
2026-06-16 14:38:51 +02:00
"scheduler" : "Planer" ,
2026-06-19 12:23:00 +02:00
"config" : "Konfiguration" ,
2026-06-19 14:16:48 +02:00
"users" : "Benutzer" ,
2026-06-15 00:30:34 +02:00
"settings" : "Einstellungen" ,
"about" : "Über" ,
2026-06-16 02:05:38 +02:00
"signOut" : "Abmelden" ,
"addAccount" : "Weiteres Konto hinzufügen" ,
feat(audit): admin audit log (Notification P3)
Append-only who/what/when trail for admin actions + scheduler run summaries,
generalizing QuotaEvent. Logged at ACTION / run-summary granularity — never
per-row (a scheduler run touching thousands of videos is ONE row).
Backend:
- migration 0054_audit_log + AuditLog model (actor_id FK SET NULL, action,
target_type/id, summary, before/after JSON, created_at).
- app/audit.py: AuditAction constants (single source of truth, i18n'd on the
client) + record() (adds to the caller's txn) + gc(retention_days).
- producers wired: role change / suspend / delete / invite approve-deny-add /
demo add-remove-reset / discovery purge (admin.py); config set/reset — secret
VALUES never logged, key only (config.py); scheduler interval + maintenance
tune (scheduler routes); sync pause/resume (sync.py); and the scheduler _job()
choke point writes ONE run-summary row per run — manual runs + errors always,
automatic runs only when they changed something (no no-op-poll spam).
- retention: audit_gc scheduler job prunes rows older than audit_retention_days
(sysconfig, default 180; 0 = keep forever).
- admin API routes/audit.py (/api/admin/audit): recent-window list (actor emails
resolved, System for background) + clear (leaves one tamper-evidence row).
Frontend:
- new admin-only "Audit log" nav page (ScrollText) using the shared DataTable
(first admin page to reuse it) — sort/filter/paginate/persist, action select
filter, actor text filter, before→after detail, Clear-all with confirm.
- AuditLog.tsx + auditColumns.tsx + api.adminAudit/clearAudit + AuditRow type.
- trilingual audit + auditActions namespaces (HU/EN/DE) + nav + config-group +
scheduler job labels; Audit config group (retention days).
2026-07-12 07:32:41 +02:00
"switchTo" : "Zu {{name}} wechseln" ,
"audit" : "Audit-Protokoll"
2026-06-15 00:30:34 +02:00
} ,
"sync" : {
"yours" : "deine" ,
"total" : "gesamt" ,
"countTooltip" : "Videos aus deinen Abos im Vergleich zur Gesamtzahl im gemeinsamen Katalog, den die Abos aller Nutzer gefüllt haben." ,
"paused" : "pausiert" ,
"syncing" : "{{count}} werden synchronisiert" ,
2026-06-15 04:30:27 +02:00
"backfillingHistory" : "Verlauf wird geladen" ,
2026-06-19 02:57:45 +02:00
"working" : "Synchronisierung…" ,
"recentQueued" : "{{count}} in Warteschlange" ,
2026-06-15 00:30:34 +02:00
"allSynced" : "alles synchronisiert" ,
"withoutFullHistory" : "{{count}} ohne vollständigen Verlauf" ,
"fullHistoryTooltip" : "Einige deiner Kanäle haben nur ihre neuesten Uploads. Klicke, um die Kanalverwaltung (auf diese gefiltert) zu öffnen und ihren vollständigen Katalog anzufordern." ,
"pause" : "Hintergrund-Synchronisierung pausieren" ,
"resume" : "Hintergrund-Synchronisierung fortsetzen"
} ,
"banner" : {
"updated" : "Aktualisiert auf v{{version}} — sieh, was sich geändert hat." ,
"releaseNotes" : "Versionshinweise" ,
"dismiss" : "Schließen"
}
}