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
Mitwirkender

Automatischer Promote-Trigger via AegisSight Promote-UI. Commits: 20

Automatischer Promote-Trigger via AegisSight Promote-UI. Commits: 20
IntelSight_Admin hat 20 Commits 2026-05-14 00:38:18 +02:00 hinzugefügt
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.
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.
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).
- 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).
- 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).
- 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).
- 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).
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).
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.
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.
- 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.
- 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.
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.
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.
- 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.
- _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.
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.
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.
- 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.
IntelSight_Admin hat Commit 3f97aa63e9 in main 2026-05-14 00:38:19 +02:00 gemerged
Anmelden, um an der Diskussion teilzunehmen.
Keine Reviewer
Kein Label
1 Beteiligte
Nachrichten
Fällig am
Kein Fälligkeitsdatum gesetzt.
Abhängigkeiten

Keine Abhängigkeiten gesetzt.

Referenz: AegisSight/AegisSight-Monitor#25