Admin-Dashboard (Modell / Budget / Usage)

Steuer- & Sichtfläche für die LLM-Kostengovernance aus ADR-0017. Entscheidung: ADR-0024. Gleichwertig als UI + API + MCP (AI-Parität, ADR-0018) — die Logik liegt einmalig in lib/llm/* (Single Source). Frage: siehst Du das?

Was man kann

  • Modell je Aufgabe wählen (classification, embedding, standardReport, premiumReport, pdfExtraction, toolUse, bulkParse) — Override schlägt ENV/Default, sofort wirksam (Cache-Invalidierung).
  • Budget-Cap (USD Tag/Monat) setzen — die Engine bremst fail-open bei Überschreitung (ADR-0017).
  • Ist-Kosten sehen: heute / Monat + je Task+Modell (Calls/Tokens/$).

Benutzerverwaltung & Impersonation

Eigener Admin-Bereich (ab Dashboard-Nav verlinkt), proxy.ts-gated (platform_admin + 2FA) und zusätzlich server-seitig geprüft.

  • /admin/users — Nutzerliste mit Suche (E-Mail/Name) + Rollen-Filter; pro Zeile Auge-Button (Session-Takeover, ADR-0026 v2 — wechselt in die Sicht des Nutzers mit dessen Rolle/Rechten; orange Leiste oben zeigt den Modus, dort auch „Beenden"), Kontext (read-only Inspektion via ?inspect=, auditiert) und Detail. Unten: Admin-Audit + Impersonation-Audit.
  • /admin/users/[id]Plattform-Rolle ändern (user / support / platform_admin) und Konto DSGVO-konform löschen (gleiche Erasure-Kaskade wie die Selbst-Löschung).
  • /admin/impersonate — nur noch Redirect auf /admin/users (Konsole dort integriert); die Headless-API GET/POST /api/v1/admin/impersonate bleibt unverändert.

Sicherheit (fail-closed): nur verifizierte platform_admin, nicht aus einer Impersonation heraus; kein Self-Target; kein Degradieren des letzten Admins (Lockout-Schutz); kein Löschen eines anderen Admins; Org-Owner-Guard vor der Löschung; striktes Audit vor der Löschung. Rollen-/Lösch-Eingriffe landen in admin_audit_log, Impersonation weiter in impersonation_log. Rollen-Änderungen wirken für den Ziel-Nutzer erst ab dessen nächstem Login/Token-Refresh (JWT-Sessions).

Zugänge

ZugangAuthFür
UI /adminAuth.js platform_admin + 2FA (ADR-0006, Gate in proxy.ts)Menschen
API /api/v1/admin/*API-Key mit admin-ScopeSkripte/KI
MCP get_usage/set_model/set_budgetdito (LANDNUTZEN_API_KEY)KI-Ops

Kein/ungültiger Key → 401, gültiger Key ohne Scope → 403.

Endpunkte

MethodePfadZweck
GET/api/v1/admin/usageUsage je Task+Modell + Spend + Budget
GET/api/v1/admin/modeleffektives Modell je Task
PUT/api/v1/admin/model{ task, model } setzen
GET/api/v1/admin/budgetBudget + Ist
PUT/api/v1/admin/budget{ dailyUsd, monthlyUsd } (null = kein Limit)

Admin-Key erzeugen

node scripts/create-admin-key.mjs "Label"

Speichert nur den Hash (SHA-256(key+secret)); der Klartext wird einmalig ausgegeben (nicht wiederherstellbar). Scope {report, admin}. Verwendung:

curl -H "Authorization: Bearer ln_…" \
  https://landnutzen.vercel.app/api/v1/admin/usage

Sicherheit

Admin-Key ist mächtig: nur Hash gespeichert, Scope-getrennt, Rate-Limit/Audit wie jeder Key (ADR-0019/0023), Rotation manuell (neuen Key erzeugen, alten via revoked_at sperren). UI zusätzlich durch 2FA-Gate geschützt.