Promote develop → main (2026-05-13 22:38 UTC) #25

Zusammengeführt
IntelSight_Admin hat 20 Commits von develop nach main 2026-05-14 00:38:19 +02:00 zusammengeführt

20 Commits

Autor SHA1 Nachricht Datum
52a631921e Release-Notes: Oberfläche vollständig in Ihrer Sprache verfügbar 2026-05-14 00:38:16 +02:00
Claude Code
892af55269 feat(i18n): Export-Modal + Quellenverwaltung + Chat-Widget + Stats-Bar
- Export-Modal: Titel, Bereiche, Format, alle Checkboxes (Zusammenfassung,
  Recherchebericht / Lagebild, Faktencheck, Quellen), PDF/DOCX, Abbrechen,
  Exportieren.
- Quellenverwaltung-Modal: Title, 8 Filter-Labels (sr-only) + 8 Alle-*
  Default-Optionen, Search-Placeholder + Label, + Quelle-Button, Add-
  Form (URL/Erkennen/Name/Kategorie/Typ/RSS-URL/Domain/Notizen +
  Placeholder), Speichern/Abbrechen, Loading-State.
- Stats-Bar (app.js): RSS-Feeds/Web-Quellen/Ausgeschlossen-Labels.
- components.js: source-excluded-badge.
- Chat-Widget: Title, alle 5 Buttons mit title+aria, Input-Placeholder.
- Chat-Begruessung in chat.js auf T() umgestellt.
- 50+ neue i18n-Keys. Cache-Buster components.js + chat.js + app.js
  auf v=20260514e gebumpt.
2026-05-13 22:22:07 +00:00
Claude Code
ea630cd31b feat(i18n): grosser Sweep -- Toasts, Confirms, Notification-Center, Map, Empty-States, Lizenz-Hinweise
29 Stellen im Frontend lokalisiert (Toasts: Lage aktualisiert/geloescht/
archiviert/wiederhergestellt, Recherche abgebrochen, Daten aktualisiert,
Quelle hinzugefuegt/aktualisiert, Bericht heruntergeladen, kein RSS;
Confirms: Lage loeschen, Recherche abbrechen; Button-States: Wird
gestartet/abgebrochen/erstellt/gesendet, Suche Feeds, Quelle speichern;
Lizenz: abgelaufen/keine/Org-deaktiviert -- Nur Lesezugriff;
Notification-Center: Titel, Alle gelesen, Keine Benachrichtigungen;
Empty-States: Kein Vorfall ausgewaehlt; Map: Orte einlesen + Tooltip,
Keine Orte erkannt; Modal-Hint: Nur deutschsprachige Quellen). 30+
neue i18n-Keys. Cache-Buster app.js auf v=20260514c.
2026-05-13 22:16:42 +00:00
Claude Code
4fc3212e2c fix(i18n): Notify-Summary-Toggle wird beim Lage-Edit ueberschrieben
app.js:1037-1043 setzte den Text der notify-summary-Checkbox dynamisch
auf Neues Lagebild / Neuer Recherchebericht und damit das data-i18n-
Attribut zurueck. Jetzt ueber T() mit Forschungs-/Lagebild-Varianten.
Neuer Key modal.notify.summary_research.
2026-05-13 22:09:06 +00:00
Claude Code
3a68097b4f feat(i18n): Aktions-Buttons dynamisch + komplettes Neue-Lage/Bearbeiten-Modal
- _updateRefreshButton + _updateArchiveButton (app.js) nutzen T() statt
  Hardcode -- Aktualisieren/Laeuft/Wiederherstellen/Archivieren/Lesemodus.
- Modal-Title-Setter (Lage bearbeiten / Neue Lage anlegen) lokalisiert
  an drei Stellen (init / openEdit / closeModal).
- updateVisibilityHint und toggleTypeDefaults: dynamischer Text via T().
- HTML: ~31 data-i18n + data-i18n-attr im modal-new (Art der Lage,
  Optionen, Type-Hint, Quellen-Toggles, Sichtbarkeit, Aktualisierung,
  Intervall-Einheiten, Aufbewahrung, E-Mail-Toggles, Abbrechen).
- Cache-Buster app.js auf v=20260514a.
2026-05-13 22:05:31 +00:00
Claude Code
90f0731a86 feat(i18n): Aktionsleiste + Sidebar (Quellen, Feedback, Archiv, Stats, Empty-States)
- 5 Action-Buttons im Header (Aktualisieren/Bearbeiten/Bericht
  exportieren/Archivieren/Loeschen) via data-i18n.
- Sidebar Archiv-Section, Quellen-Button, Feedback-Button, title-
  Attribute via data-i18n + data-i18n-attr.
- Sidebar-Stats 0 Quellen / 0 Artikel: app.js.updateSidebarStats
  baut die Suffixe ueber T() zusammen.
- Empty-States Kein Live-Monitoring / Keine Deep-Research (inkl.
  eigene-Filter-Varianten) lokalisiert.
- Cache-Buster app.js auf v=20260513g.
2026-05-13 22:00:00 +00:00
Claude Code
917c260298 fix(i18n): Tab-Labels werden dynamisch ueberschrieben -- T() statt hardcode
LayoutManager.applyTypeLabels(layout.js:58-65) und App-Render
(app.js:1063,1081) ueberschreiben die Tab-Texte je nach Lage-Typ.
Beides nutzt jetzt T() mit DE-Fallback. Neue Keys tab.summary_short
und tab.summary_report. Cache-Buster layout.js + app.js gebumpt.
2026-05-13 21:51:49 +00:00
Claude Code
a2d290df6d feat(i18n): Tab-Buttons und Card-Titel der Lage-Ansicht lokalisieren
7 Tab-Buttons (Neueste Entwicklungen, Lagebild, Ereignis-Timeline,
Geografische Verteilung, Faktencheck, Analysepipeline, Quellenuebersicht)
sowie 6 Card-Titel + Map-Fullscreen-Titel bekommen data-i18n. Neue
Keys tab.* und card.* in de.json + en.json. Cache-Buster app.js
auf v=20260513e gebumpt.
2026-05-13 21:48:23 +00:00
Claude Code
9e3c9559d9 feat(i18n): Progress-Popup + Pipeline-Stati lokalisieren
- components._getStepLabel und progress-popup-title nutzen T()
  fuer Erste Recherche laeuft / Aktualisierung laeuft / In Warteschlange
  / Wird abgebrochen.
- pipeline._formatHeader / _relativeTime / _formatCount lokalisiert:
  Status-Texte (erledigt/laeuft/Fehler), Zeitangaben (gerade eben,
  vor X Min/Std/Tagen), Aktualisierung-laeuft-Header.
- dashboard.html: data-i18n auf pipeline-empty, progress-popup-title,
  progress-check-label (4 Stueck).
- Cache-Buster fuer components.js + pipeline.js auf v=20260513d.
2026-05-13 21:45:18 +00:00
Claude Code
b214249a34 fix(i18n): Beschreibung-generieren-Button + Fehler-Toasts uebersetzbar
- Button-Span enhance-btn-text bekommt data-i18n.
- app.js: Loading-State Wird generiert... / Generating... per T().
- Vier Fehler-Toasts (Default, 503, 429, 504) per T() lokalisiert.
- Neue Keys enhance.* in de.json + en.json.
- Cache-Buster app.js auf v=20260513c gebumpt.
2026-05-13 21:39:36 +00:00
Claude Code
10805dff15 fix(frontend): app.js Cache-Buster bumpen damit I18N.load() greift
Bei Phase 6 wurde components.js und i18n.js gebumpt, app.js aber nicht.
Browser zogen die alte app.js ohne I18N-Init aus dem Cache, sodass
eng_demo-Nutzer eine deutsche Oberflaeche sahen.
2026-05-13 21:34:19 +00:00
Claude Code
cdcf5e487a fix(auth): Org-Switcher auch auf Staging anzeigen
STAGING_MODE deaktivierte bisher den Org-Switcher im Frontend, weil keine
Demo-Besucher zwischen Mandanten hoppen sollten. Mit eng_demo brauchen
wir aber bewussten Zugriff auf alle Sprach-Mandanten via Switcher. Der
Token-Budget-Schutz (license_service._staging_mode) bleibt unveraendert.
2026-05-13 21:32:50 +00:00
Claude Code
3f0e680446 feat(frontend): Light-i18n + Org-Sprache durch /auth/me
Backend:
- UserMeResponse um output_language (de | en) erweitert.
- /auth/me liefert die Org-Sprache aus organization_settings.

Frontend:
- Neu: static/js/i18n.js mit T(key)-Helper, I18N.load(lang) und
  applyDom() ueber data-i18n + data-i18n-attr.
- Neu: static/i18n/de.json + en.json (sichtbare Bereiche: Sidebar,
  Header, Modal-Titel, Faktencheck-Status, Refresh-Hinweise).
- dashboard.html: i18n.js Script-Tag vor api.js, data-i18n auf den
  prominenten Strings (Abmelden, + Neuer Fall, Alle/Eigene, Sidebar-
  Sektionen, Bericht exportieren, Faktencheck-Tab, Lage anlegen).
  Tutorial.init() entfernt aus DOMContentLoaded.
- components.js: factCheckLabels/Tooltips/ChipLabels als Getter ueber
  T() mit DE-Fallbacks.
- app.js: vor Setup wird I18N.load(user.output_language) aufgerufen und
  applyDom() ausgefuehrt. Tutorial.init() laeuft nur bei lang === de.

Phase 6 von 8 (eng_demo / Org-Sprache).
2026-05-13 21:14:56 +00:00
Claude Code
4e51834163 feat(emails): zweisprachige E-Mail-Templates + Notification-Texte org-relativ
- email_utils/templates.magic_link_login_email + incident_notification_email
  nehmen jetzt lang Parameter (de | en).
- routers/auth.request_magic_link zieht Sprache aus der Org des Users und
  uebergibt sie ans Template.
- agents/orchestrator._send_email_notifications_for_incident lokalisiert
  ebenfalls und gibt lang an incident_notification_email durch.
- DB-Notification-Texte (refresh_summary, new_articles) sind in der
  Pipeline org-sprach-relativ (englische Variante: "3 new articles", etc.).
  Status-Change-Notifications: Codes (confirmed/contradicted) bleiben, FE
  uebersetzt sie in Phase 6.

Phase 5 von 8 (eng_demo / Org-Sprache).
2026-05-13 21:08:32 +00:00
Claude Code
a2d4c77813 feat(backend): Lokalisierung der weiteren Pipeline-Bereiche
- incidents.enhance_description: ENHANCE_PROMPT_RESEARCH/ADHOC nun pro
  Sprache (DE/EN), Auswahl via _enhance_template(type, org_lang_iso).
- pipeline_tracker.get_pipeline_steps(lang_iso) liefert die Schritt-
  Definition lokalisiert. /api/incidents/{id}/pipeline reicht Org-Sprache
  durch.
- chat._build_prompt(output_language): SYSTEM_PROMPT laesst sich per
  format() in Org-Sprache rendern (nur Output-Anweisung). Chat-Router
  zieht Sprache aus Org-Setting.
- report_generator: FC_STATUS_LABELS_DE/EN + _fc_labels(lang_iso).
  PDF-Template bleibt vorerst deutsch (Phase 9).

Bewusst draussen (Phase 4): entity_extractor (Backend-intern, keine UI),
source_suggester (Admin in Verwaltung), geoparsing (liefert bereits
englische Ortsnamen).

Phase 4 von 8 (eng_demo / Org-Sprache).
2026-05-13 21:04:20 +00:00
Claude Code
9754dcb4ef feat(sources): primary_language Spalte + ISO-Backfill + org-relativer Feed-Bucket
- Neue Spalte sources.primary_language (ISO-2-Code) mit Backfill aus dem
  Freitext-Feld language (Erste Sprache vor /-Trennung). Edge-Cases wie
  Iran Military Magazine (English) [Farsi/Arabisch] landen als fa und
  koennen ueber das Verwaltungsportal manuell justiert werden.
- get_source_rules(tenant_id) bestimmt die Org-Sprache und bucketed Feeds
  nach primary (=Org-Sprache) / international (=alle anderen) / behoerden
  (Kategorie behoerde). Bei tenant_id=None oder Helper-Fehler default de.
- rss_parser.search_feeds unveraendert in Logik (international=False
  laesst weiterhin alle ausser dem international-Bucket durch), Kommentare
  generischer formuliert.

Phase 3 von 8 (eng_demo / Org-Sprache).
2026-05-13 20:57:51 +00:00
Claude Code
f68d25dbce feat(pipeline): output_language pro Org durch die Pipeline reichen
- OUTPUT_LANGUAGE Konstante aus config.py entfernt (jetzt pro Org in
  organization_settings).
- Orchestrator laedt output_language einmal pro Refresh aus der Org-Sprache.
- researcher.search(), analyzer.analyze/.analyze_incremental/.generate_latest_developments,
  factchecker.check/.check_incremental/.check_incremental_twophase bekommen
  output_language als Parameter (Default Deutsch).
- LANG_INTERNATIONAL / LANG_GERMAN_ONLY (+ Deep-Varianten) sind Funktionen,
  die je nach output_language die Sprachanweisung erzeugen (Deutsch | English
  | Fallback).
- Sprachfilter in researcher.search ist org-relativ: bei nicht-international
  werden Artikel mit Sprache != output_language_iso gefiltert.

Phase 2 von 8 (eng_demo / Org-Sprache). Bestandsorgs unveraendert, weil
Default-Setting weiterhin de (siehe Phase-1-Migration).
2026-05-13 20:54:28 +00:00
Claude Code
d27d586003 feat(settings): organization_settings KV-Tabelle + org_settings Helper
Neue Tabelle organization_settings (organization_id, key, value) als KV-Store
fuer Org-spezifische Konfiguration. Erster Use-Case: output_language (de|en).
Bestandsorgs werden per Migration auf de gesetzt.

Helper services/org_settings.py mit get_org_setting / set_org_setting /
get_org_language / language_display. In-Memory-Cache TTL 60s.

Phase 1 von 8 (eng_demo / Org-Sprache).
2026-05-13 20:46:04 +00:00
Claude (info@aegis-sight.de)
5ec4480598 fix(incidents): refresh_mode beim Edit nicht durch toggleTypeDefaults überschreiben
Beim Öffnen des Bearbeiten-Dialogs einer Recherche-Lage (type=research) hat
toggleTypeDefaults() den Aktualisierungs-Select hartcodiert auf manual gesetzt
und damit den tatsächlichen DB-Wert im UI verdeckt. User glaubte, manuell sei
gewählt, in der DB stand aber auto und die Lage lief weiter im Auto-Refresh.

Fix: toggleTypeDefaults erhält einen optionalen Parameter preserveMode.
handleEdit ruft mit preserveMode=true auf, damit der DB-Wert respektiert
wird; bei Typ-Wechsel und Neuanlage bleibt der Default-Reset auf manual
für research erhalten.

Cache-Buster app.js: 20260501h -> 20260512a.
2026-05-12 21:02:04 +00:00
Claude Code
b90e47ff3f refactor(klassifikation): Klassifikation aus Monitor entfernt — Pflege jetzt in der Verwaltung
Endpoints unter /api/sources/classification/* weg, Service-Module (source_classifier, external_reputation) gelöscht. Quellen-Modal verliert Tab Klassifikations-Review, Klassifikations-Section in der Edit-Form, alle Bulk-Buttons (Sync, Klassifikation starten, Bulk-Approve). API-Methoden in api.js entfernt, alignment-Helper raus, saveSource entschlackt.

Read-Only bleibt: Filter-Dropdowns über der Quellenliste (Politik, Medientyp, Reliability, Externe Reputation, Alignment) und Inline-Badges (_renderClassificationBadges + Label-Maps in components.js). Kunde sieht nur freigegebene Werte.

GET /api/sources liefert weiter Klassifikations-Felder + alignments für die Anzeige; SourceCreate/SourceUpdate akzeptieren keine Klassifikations-Felder mehr.

Bulk-Klassifikations-Skripte entfernt — Pflege läuft über Verwaltungs-UI.
2026-05-09 22:01:20 +00:00