Commit graph

17 Commits

Autor SHA1 Nachricht Datum
0d6ad8ea90 Incident-Response: sources_json nur noch via Lazy-Endpunkt, Sidebar schlank
Backend:
- IncidentResponse: sources_json-Feld entfernt (Detail-GET liefert es
  nicht mehr mit).
- Neues Schema IncidentListItem fuer GET /incidents (Sidebar):
  Ohne summary, ohne sources_json. Ein has_summary-Bit fuer
  Erster-Refresh-Erkennung, description bleibt fuer das Edit-Modal.
- list_incidents selektiert nur die noetigen Spalten (kein SELECT *)
  — spart bei grossen Lagen Speicher + Serialisierung.
- Neuer Endpunkt GET /incidents/{id}/sources liefert geparstes
  Sources-Array fuer Zitate-Lookups (Lazy).

Frontend:
- api.js: getIncidentSources(id).
- app.js: loadIncidentDetail laedt /sources parallel, speichert Array
  in _currentSources. Alle renderSummary/Zusammenfassung/
  LatestDevelopments-Aufrufe bekommen jetzt _currentSources statt
  incident.sources_json. inc.summary-Checks -> inc.has_summary.
- components.js: _parseSources(input) akzeptiert Array ODER String
  (Rueckwaertskompatibilitaet). renderZusammenfassung, renderSummary,
  renderLatestDevelopments nutzen den Helper.

Hintergrund: Die Sidebar-Liste lieferte bei 17 Lagen 1,23 MB
(Iran allein 386 KB wegen sources_json + summary). Detail-Endpunkt
lieferte sources_json (324 KB bei Iran) bei jedem Oeffnen mit.
Beides jetzt radikal kleiner — die 324 KB Sources gibt's nur
einmalig auf Anfrage.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 00:07:46 +02:00
claude-dev
5127e0a42d Podcast-Integration Phase 1: Feed-Tag + Senderseiten
Podcasts werden wie normale RSS-Quellen behandelt (source_type=podcast_feed).
Kein externer bezahlter Dienst, keine lokale Transkription — Monitor nutzt
ausschliesslich vorhandene Transkripte.

Kaskade fuer Transkript-Bezug:
 1. Podcasting-2.0-Tag <podcast:transcript> im Feed (SRT/VTT/HTML/JSON)
 2. Redaktionelles Manuskript auf der Episodenseite
    (Adapter: Dlf, SZ, Spiegel, NDR)
 3. YouTube-Captions — Phase 2, optional per yt-dlp

Kein Stufen-Treffer -> Episode verworfen (graceful, kein Error).

Neu:
- src/feeds/podcast_parser.py (eigener Parser, RSS-Heisspfad unveraendert)
- src/feeds/transcript_extractors/ (Plugin-Muster):
    __init__.py        Dispatcher, Cache-Lookup gegen podcast_transcripts
    _common.py         HTML-Extraktion, Domain-Matching, httpx-Helper
    rss_native.py      Stufe 1: Feed-Tag-Parser (SRT/VTT/JSON/HTML)
    website_dlf.py     Stufe 2: deutschlandfunk.de + Schwester-Domains
    website_sz.py      Stufe 2: sz.de / sueddeutsche.de
    website_spiegel.py Stufe 2: spiegel.de / manager-magazin.de
    website_ndr.py     Stufe 2: ndr.de

Geaendert:
- src/database.py: idempotente Migration, Tabelle podcast_transcripts als
  URL-Cache gegen Mehrfach-Scrape zwischen Lagen
- src/models.py: Pydantic-Pattern von source_type um podcast_feed erweitert
- src/source_rules.py: get_feeds_with_metadata() nimmt source_type-Parameter,
  Default rss_feed (RSS-Pfad unveraendert)
- src/agents/orchestrator.py: neue _podcast_pipeline() parallel zu RSS,
  WebSearch und Telegram; nur fuer adhoc-Lagen; ohne Podcast-Quellen dormant

Verifikation:
- Migration auf Live-DB erfolgreich (Log: Tabelle podcast_transcripts angelegt)
- Import-/Instanziierungs-Test aller Module bestanden
- can_handle-Tests pro Sender-Adapter positiv + negativ OK
- Live-Scrape gegen Dlf: 22710 Zeichen, gegen SZ: 24918 Zeichen
- Dormant-Test: 0 Podcast-Quellen -> keine neue Codezeile im Refresh

Verwerfbarkeit: rein additiv, RSS-Pfad unberuehrt, Rollback in drei
Schritten (Quellen disablen, git revert, DROP TABLE podcast_transcripts).
2026-04-18 12:06:54 +00:00
claude-dev
d6c541cb95 Neueste Entwicklungen: Kachel fuer adhoc-Lagen
- DB-Migration: Spalte latest_developments (TEXT) in incidents
- Analyzer: neuer Prompt LATEST_DEVELOPMENTS_PROMPT_TEMPLATE und
  Methode generate_latest_developments() liefert chronologische
  Bullet-Liste (max. 8, neueste oben, Zeitstempel DD.MM. HH:MM)
- Orchestrator: nach Analyse+Faktencheck ein Extra-Schritt nur fuer
  incident_type=adhoc, der die neue Kachel fortschreibt
- Analyzer-Prompts (Erst- und inkrementell): erzeugen KEINE
  Zusammenfassung-Sektion mehr im Lagebild (vermeidet Duplikat mit
  der neuen Kachel)
- models.IncidentResponse um latest_developments erweitert
- Frontend: Rendering der Kachel in app.js
2026-04-18 11:47:10 +00:00
Claude Dev
c22ae854fe feat: Global-Admin Org-Switcher fuer info@aegis-sight.de
Ermoeglicht dem Global Admin (is_global_admin Flag) zwischen
Organisationen zu wechseln. Neue Endpoints: GET /api/auth/organizations,
POST /api/auth/switch-org. Org-Dropdown im Header-Menue, nur fuer
Global Admin sichtbar. Komplett herausnehmbar (Flag + Code-Bloecke).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 22:25:41 +02:00
Claude Dev
d3e8c0adc7 feat: Slot-basierter Auto-Refresh mit konfigurierbarer Startzeit
Auto-Refresh nutzt jetzt eine feste Anker-Uhrzeit (refresh_start_time) statt
reinem Intervall-basiertem Driften. Verpasste Slots werden max. 1x aufgeholt.
Bestehendes Intervall-Verhalten bleibt als Fallback erhalten (ohne Startzeit).

Migration: Bestehende Auto-Lagen erhalten 07:00 als Startzeit.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 13:14:34 +02:00
Claude Dev
6913c1e683 feat: Beschreibung generieren Button im Neuer-Fall-Modal
KI-gestütztes Prompt Enhancement: Button generiert per Haiku aus dem
Titel eine strukturierte Beschreibung. Unterscheidet zwischen
Live-Monitoring (kompakte Vorfallsbeschreibung) und Recherche
(strukturiertes Briefing mit Schwerpunkten und Suchbegriffen).

- Neuer Endpoint POST /api/incidents/enhance-description
- Button erscheint für beide Lage-Typen, aktiv ab 3 Zeichen Titel
- Info-Hinweis wechselt je nach Typ mit Beispiel
- Spinner-Animation während der Generierung
2026-03-27 23:31:05 +01:00
Claude Dev
8f1a45c1a9 Auth: Nur noch Magic Link, Code-Verifizierung entfernt
- /api/auth/verify-code Endpoint entfernt
- generate_magic_code() und VerifyCodeRequest entfernt
- VerifyCodeLimiter (Brute-Force-Schutz) entfernt (nicht mehr noetig)
- E-Mail-Template: Nur noch Anmelde-Link, kein 6-stelliger Code
- Login-Seite: Zeigt nach E-Mail-Eingabe Hinweis statt Code-Feld
- Magic Link Token-Verifikation via URL bleibt bestehen
2026-03-25 00:01:19 +01:00
Claude Dev
7bfa1d29cf feat: Credits-System mit Verbrauchsanzeige im User-Dropdown
- DB-Migration: credits_total/credits_used/cost_per_credit auf licenses, token_usage_monthly Tabelle
- Orchestrator: Monatliche Token-Aggregation + Credits-Abzug nach Refresh
- Auth: Credits-Daten im /me Endpoint + Bugfix fehlende Klammer in get()
- Frontend: Credits-Balken im User-Dropdown mit Farbwechsel

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 23:53:19 +01:00
Claude Dev
d031fb28d6 feat: Info-Button mit Tooltip (Typ, Sprache, Ausrichtung) in Quellenverwaltung
- DB-Migration: language und bias Spalten zur sources-Tabelle hinzugefuegt
- Alle 254 Quellen mit Metadaten befuellt (Sprache, politische Ausrichtung)
- SourceResponse-Modell um language/bias Felder erweitert
- Info-Icon (i) mit Hover-Tooltip nach source-group-name eingefuegt
- Tooltip zeigt Typ, Sprache und Ausrichtung der jeweiligen Quelle

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 10:28:57 +01:00
Claude Dev
0019d74aea feat: Intelligente Telegram-Kanal-Selektion und verbesserte Quellenzuordnung
- Researcher: Claude-basierte Vorauswahl relevanter Telegram-Kanäle per Haiku
- FactChecker: Verbesserte Quellen-Zuordnung mit Relevanz-Scoring (Top 5)
- FactChecker: URLs werden nicht mehr doppelt zugeordnet, sources_count wird aktualisiert
- TelegramParser: Kanal-Filterung per channel_ids statt categories
- TelegramParser: Lockereres Keyword-Matching (1 Match reicht, da vorselektiert)
- Models: telegram_categories Feld entfernt (durch KI-Selektion ersetzt)
- Main: Chat-Router eingebunden unter /api/chat

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 18:01:32 +01:00
Claude Dev
2792e916c2 Telegram-Kategorie-Checkboxen: Nutzer koennen bei Lage-Erstellung einzelne Telegram-Quellkategorien auswaehlen 2026-03-13 19:08:36 +01:00
Claude Dev
01cad9dac5 Telegram-Kanaele als Quelle: Parser, Pipeline, UI-Checkbox, Validate-Endpoint
- Neuer source_type telegram_channel in models.py (Source + Incident)
- DB-Migration: include_telegram Spalte fuer incidents
- feeds/telegram_parser.py: Telethon-basierter Parser (analog RSS)
- Orchestrator: Telegram-Pipeline parallel zu RSS + WebSearch
- sources.py: POST /api/sources/telegram/validate Endpoint
- incidents.py: include_telegram in Create/Update/Response
- dashboard.html: Telegram-Checkbox + Filter-Option
- app.js: FormData, EditModal, SourceStats, TypeLabels
- config.py: TELEGRAM_API_ID, API_HASH, SESSION_PATH
- requirements.txt: telethon hinzugefuegt
2026-03-13 13:10:24 +01:00
claude-dev
5e19736a25 Per-User Domain-Ausschlüsse + Grundquellen-Schutz
- Neue Tabelle user_excluded_domains für benutzerspezifische Ausschlüsse
- Domain-Ausschlüsse wirken nur für den jeweiligen User, nicht org-weit
- user_id wird durch die gesamte Pipeline geschleust (Orchestrator → Researcher → RSS-Parser)
- Grundquellen (is_global) können nicht mehr bearbeitet/gelöscht werden im Frontend
- Grundquelle-Badge bei globalen Quellen statt Edit/Delete-Buttons
- Filter Von mir ausgeschlossen im Quellen-Modal

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 14:30:21 +01:00
claude-dev
18954cf70e Wording: Domain sperren → Domain ausschließen
Einheitliche Umbenennung in UI-Texten, Kommentaren und Docstrings:
- Sperren → Ausschließen
- Gesperrt → Ausgeschlossen
- Entsperren → Ausschluss aufheben

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 14:02:36 +01:00
claude-dev
a6c24366a0 Quellenverwaltung: Boulevard-Kategorie, Duplikat-Prüfung, Domain-Normalisierung
- Boulevard als Kategorie in HTML-Dropdowns, JS-Labels und Pydantic-Validierung
- create_source: URL-Duplikat-Prüfung (409 Conflict bei existierender URL)
- create_source + update_source: Domain via _DOMAIN_ALIASES normalisieren
- System-Quellen (auto-entdeckt) sind jetzt von allen Nutzern editierbar

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 23:45:01 +01:00
claude-dev
71296edb97 Großes Cleanup: Bugs fixen, Features fertigstellen, toten Code entfernen
Bugs behoben:
- handleEdit() async keyword hinzugefügt (E-Mail-Checkboxen funktionieren jetzt)
- parseUTC() Funktion definiert (Fortschritts-Timer nutzt Server-Startzeit)
- Status cancelling wird im Frontend korrekt angezeigt

Features fertiggestellt:
- Sidebar: Lagen nach Typ getrennt (adhoc/research) mit Zählern
- Quellen-Bearbeiten: Edit-Button pro Quelle, Formular vorausfüllen
- Lizenz-Info: Org-Name und Lizenzstatus im Header angezeigt

Toter Code entfernt:
- 5 verwaiste Dateien gelöscht (alte rss_parser, style.css, components.js, layout.js, setup_users)
- 6 ungenutzte Pydantic Models entfernt
- Ungenutzte Funktionen/Imports in auth.py, routers, agents, config
- Tote API-Methoden, Legacy-UI-Methoden, verwaiste WS-Handler
- Abgeschlossene DB-Migrationen aufgeräumt

Sonstiges:
- requirements.txt: passlib[bcrypt] durch bcrypt ersetzt
- Umlaute korrigiert (index.html)
- CSS: incident-type-label → incident-type-badge, .login-success hinzugefügt
- Schließen statt Schliessen im Feedback-Modal
2026-03-04 18:45:38 +01:00
claude-dev
8312d24912 Initial commit: AegisSight-Monitor (OSINT-Monitoringsystem) 2026-03-04 17:53:18 +01:00