Token-Budget Hard-Stop + Banner bei aufgebrauchtem Budget
- check_license() liefert jetzt unlimited_budget, credits_total, credits_used, read_only_reason. Bei nicht-unlimited UND credits_used >= credits_total wird status=budget_exceeded, read_only=True gesetzt. - require_writable_license blockiert mit 403 + X-License-Status-Header je nach Reason. - /api/auth/me liefert read_only_reason und unlimited_budget; credits_percent_used wird nicht mehr auf 100 gekappt (echte Prozente). - Frontend: Banner-Text dynamisch je nach reason (budget_exceeded/expired/...). Refresh-Button bei read_only deaktiviert + Tooltip. Globaler 403-Handler in api.js: bei X-License-Status -> Banner + Toast aktualisieren.
Dieser Commit ist enthalten in:
@@ -67,6 +67,29 @@ const API = {
|
||||
} else if (typeof detail === 'object' && detail !== null) {
|
||||
detail = JSON.stringify(detail);
|
||||
}
|
||||
|
||||
// Lizenz-Status aus Header auslesen (vom Backend gesetzt bei 403)
|
||||
const licStatus = response.headers.get('X-License-Status');
|
||||
if (response.status === 403 && licStatus && typeof App !== 'undefined') {
|
||||
if (!App.user) App.user = {};
|
||||
App.user.read_only = true;
|
||||
App.user.read_only_reason = licStatus;
|
||||
const warningEl = document.getElementById('header-license-warning');
|
||||
if (warningEl) {
|
||||
let text = 'Nur Lesezugriff';
|
||||
if (licStatus === 'budget_exceeded') text = 'Token-Budget aufgebraucht – nur Lesezugriff. Bitte Verwaltung kontaktieren.';
|
||||
else if (licStatus === 'expired') text = 'Lizenz abgelaufen – nur Lesezugriff';
|
||||
else if (licStatus === 'no_license') text = 'Keine aktive Lizenz – nur Lesezugriff';
|
||||
else if (licStatus === 'org_disabled') text = 'Organisation deaktiviert – nur Lesezugriff';
|
||||
warningEl.textContent = text;
|
||||
warningEl.classList.add('visible');
|
||||
}
|
||||
if (typeof App._updateRefreshButton === 'function') App._updateRefreshButton(false);
|
||||
if (typeof UI !== 'undefined' && UI.showToast) {
|
||||
UI.showToast(detail || 'Lizenz-Beschränkung – nur Lesezugriff', 'error');
|
||||
}
|
||||
}
|
||||
|
||||
throw new ApiError(response.status, detail);
|
||||
}
|
||||
|
||||
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren