fix(sources): Feinschliff nach Konsistenz-Pruefung + UI-Rueckmeldungen

Echte Fehler:
- esc() maskiert jetzt auch Anfuehrungszeichen. Quellennamen mit
  Apostroph (z.B. LExpress) brachen sonst die Zeilen-Knoepfe.
- formatDateTime parst SQLite-UTC-Zeitstempel jetzt als UTC statt
  Lokalzeit (Zeiten waren um den Zeitzonen-Offset verschoben).
- Audit-Filter Bis-Datum schliesst den gewaehlten Tag jetzt komplett ein.

UI-Rueckmeldungen:
- Beschreibung in der Vorschlags-Tabelle bricht mehrzeilig um statt
  abgeschnitten zu werden.
- Bestaetigen-Knopf im Dialog ist standardmaessig Gold, Rot nur noch bei
  destruktiven Aktionen (Org/Nutzer/Quelle loeschen, X-Konto entfernen).
- Alle >= 0.85 genehmigen ist ausgegraut, solange keine Klassifikationen
  ausstehen.

Konsistenz:
- GET /suggestions deckelt pending nicht mehr auf 50 (Badge und Tabelle
  liefen auseinander), bearbeitete weiterhin letzte 50.
- /stats zaehlt jetzt alle Quellen wie die Liste (nicht nur aktive),
  Grundquellen/Kundenquellen-Aufteilung wird immer angezeigt.
- Health-Spalte sortiert nach Schweregrad statt alphabetisch.
- Aufgaben-Badge laedt schon beim Seitenstart, nicht erst beim Reiterklick.
- Loesung-suchen-Knopf stellt nach Fehler das Icon wieder her, native
  confirm()-Dialoge durch showConfirm ersetzt.
- Tote Endpoints GET /health (Alt-Liste) und GET /classification/stats
  entfernt, tote CSS-Bloecke (activity-*, badge-health-*,
  review-conf-filter) geloescht.
- Smoke-Test deckt jetzt alle Klassifikations-/Upload-/Sync-Endpoints ab.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Dieser Commit ist enthalten in:
claude-dev
2026-07-25 18:48:16 +00:00
Ursprung bc3b0bb9ee
Commit c5f63b1d14
9 geänderte Dateien mit 100 neuen und 219 gelöschten Zeilen

Datei anzeigen

@@ -437,7 +437,8 @@ function confirmDeleteOrg() {
} catch (err) {
showToast(err.message, "error");
}
}
},
{ danger: true }
);
}
@@ -533,7 +534,8 @@ function confirmDeleteUser(userId, email) {
} catch (err) {
showToast(err.message, "error");
}
}
},
{ danger: true }
);
}
@@ -834,9 +836,19 @@ let confirmCallback = null;
let confirmResolver = null;
function showConfirm(title, text, callback) {
function showConfirm(title, text, callback, opts) {
// Promise-Stil erlaubt opts als dritten Parameter: showConfirm(t, x, {danger:true})
if (callback && typeof callback === "object") { opts = callback; callback = null; }
opts = opts || {};
document.getElementById("confirmTitle").textContent = title;
document.getElementById("confirmText").textContent = text;
// Bestätigen-Knopf ist standardmäßig Gold. Rot nur für destruktive
// Aktionen (Löschen, Entfernen), per opts.danger = true.
const okBtn = document.getElementById("confirmOkBtn");
if (okBtn) {
okBtn.classList.toggle("btn-danger", !!opts.danger);
okBtn.classList.toggle("btn-primary", !opts.danger);
}
// Backward-compat: legacy Callback wird bei OK aufgerufen
confirmCallback = callback || null;
openModal("modalConfirm");
@@ -889,7 +901,10 @@ function esc(str) {
if (!str) return "";
const div = document.createElement("div");
div.textContent = str;
return div.innerHTML;
// Auch Anführungszeichen maskieren. Viele Templates setzen esc() in
// HTML-Attribute (onclick='...', title="...") ein, dort bricht ein
// Apostroph im Quellennamen (z.B. L'Express) sonst das Markup.
return div.innerHTML.replace(/"/g, "&quot;").replace(/'/g, "&#39;");
}
function formatDate(iso) {