Commit graph

30 Commits

Autor SHA1 Nachricht Datum
claude-dev
657683d491 perf(sources): Quellen-Health Pagination (default 100, plus mehr/alle laden)
Echter Bottleneck war der DOM-Render von 519 Tabellen-Zeilen, nicht
das Backend (45ms). Backend-Slim und Cache aus dem letzten Commit
haben Bandbreite und wiederholte Klicks beschleunigt, aber der erste
Klick blieb langsam, weil weiterhin alle 519 Items in einem
innerHTML-Schub gerendert wurden.

Lösung: Server-Side-Pagination.

Backend (/api/sources/health):
- Neue Query-Param: limit (default 100, max 5000), offset (default 0)
- Counters errors/warnings/ok/total_checks aus separater GROUP-BY-
  Aggregat-Query über den GESAMTEN Bestand, nicht über die Page.
- Neues Feld all_orgs in der Antwort: alle Tenants mit Health-Checks,
  damit das Filter-Dropdown auch im Pagination-Modus die volle
  Org-Liste hat.
- Neue Felder limit, offset, has_more.

Frontend (source-health.js):
- healthLoadLimit (default 100), wird durch loadMoreHealth() um 200
  hochgesetzt oder durch loadAllHealth() auf alles gesetzt.
- Cache-Key beinhaltet jetzt auch das aktuelle Limit, damit beim
  Mehr-laden nicht aus altem Cache bedient wird.
- Org-Liste kommt aus healthData.all_orgs statt aus den geladenen
  Page-Items, sonst wäre sie nach Pagination unvollständig.
- Footer mit zwei Buttons ("+200 laden", "Alle N weiteren laden")
  unter der Tabelle, nur sichtbar bei has_more=true.
- Counter-Anzeige: "X / Y angezeigt (von Z insgesamt)".

Cache-Buster für source-health.js auf 20260509f gebumpt.
2026-05-09 12:54:35 +00:00
claude-dev
f6af21e6cb perf(sources): Quellen-Health Tab schneller (Payload-Slim + 60s-Cache)
Tab "Quellen Health" lädt deutlich schneller:

1. /api/sources/health: SELECT reduziert auf nur die im Frontend wirklich
   gerenderten Felder. Weg sind: h.id, s.url, s.source_type, s.category,
   s.bias, h.details, h.checked_at. Response-Größe sinkt damit von ~198 KB
   auf grob die Hälfte (bei 519 Health-Checks) ohne UI-Verlust.

2. source-health.js: 60-Sekunden In-Memory-Cache fürs loadHealthData.
   Tab hin und her klicken ist damit instant statt jedes Mal voller
   Reload + Render der 519 Tabellen-Zeilen.
   Bei Mutationen (Vorschlag annehmen/ablehnen, run-stream beendet,
   search-fix) wird mit loadHealthData(true) der Cache umgangen,
   damit frische Daten gezeigt werden.

3. dashboard.html: Cache-Buster für source-health.js auf 20260509e gebumpt.
2026-05-09 12:33:30 +00:00
claude-dev
7f729443cb Phase 18 (Verwaltung): fetch_strategy in CRUD + Edit-Modal
- migrations/2026-05-09e_fetch_strategy.py NEU: ALTER TABLE sources ADD COLUMN
  fetch_strategy. Pre-flagging fuer FT/WSJ/NZZ etc. (paywall) und Rheinische
  Post/Verfassungsschutz (googlebot).
- shared/services/source_health.py: gesynct vom Monitor (Phase-18-Code mit
  Retry-Logik + Strategien default/googlebot/paywall/skip).
- routers/sources.py: GlobalSourceCreate/Update um fetch_strategy
  (Pattern-Validation), SOURCE_UPDATE_COLUMNS + INSERT erweitert.
- dashboard.html: Edit-Modal hat jetzt Dropdown sourceFetchStrategy.
- sources.js: laedt + sendet fetch_strategy mit.

Cache-Buster 20260509c -> 20260509d.
2026-05-09 04:57:01 +00:00
claude-dev
bff934d673 Phase 17: Health-Tab Filter + Org-Spalte + History-View + URL-Schema-Fix
Backend:
- shared/services/source_health.py: URL ohne https://-Prefix wird normalisiert
  bevor httpx.get() aufgerufen wird (Bug-Fix: t.me/kanal liess httpx mit
  ValueError crashen, Synchron mit Monitor-Fix 1ee6c4d).
- routers/sources.py /health: Query erweitert um tenant_id, category,
  language, bias, org_name (LEFT JOIN organizations) - Frontend kann jetzt
  pro Issue Tenant-Info anzeigen.
- routers/sources.py /health/history NEU: letzte N Runs aus
  source_health_history aggregiert (run_id, archived_at, errors/warnings/ok).

Frontend (source-health.js):
- healthFilters State: status / check_type / org.
- applyHealthFilter() reduziert die Anzeige.
- Filter-Bar mit 3 Dropdowns + Counter "X / Y Ergebnisse".
- Tabelle erweitert: Org-Spalte ("global" oder Org-Name), Sprache-Spalte.
- History-View neu: letzte 10 Runs als Tabelle (Zeitpunkt, Run-ID, Counts).

Cache-Buster auf 20260509c gebumpt.
2026-05-09 04:47:05 +00:00
claude-dev
c86b2a0056 Phase 15: language + bias als Spalten, Filter, Edit-Form
Bisher waren die DB-Felder sources.language und sources.bias zwar gepflegt
(254/275 Quellen mit bias, 254 mit language), aber in der Verwaltung nicht
sichtbar. Der Admin konnte nicht filtern oder editieren.

Backend (routers/sources.py)
- GlobalSourceCreate + GlobalSourceUpdate Pydantic-Modelle: language +
  bias als Optional[str] erweitert (max 100 / 500 Zeichen).
- SOURCE_UPDATE_COLUMNS: language + bias hinzu.
- INSERT in create_global_source: schreibt language + bias mit.
- Neuer Endpoint GET /api/sources/global/languages: distinct language-Werte
  fuer Frontend-Filter-Dropdown.

Frontend HTML (dashboard.html)
- Grundquellen-Filter-Bar: Sprachen-Dropdown ergaenzt.
- Grundquellen-Tabellenkopf: 2 neue Spalten Sprache (sortable) + Bias.
- modalSource: 2 neue Felder language (mit datalist Vorschlaegen) + bias.
- Kundenquellen-Filter-Bar: Sprachen-Dropdown.
- Kundenquellen-Tabellenkopf: Sprache (sortable) + Bias.

Frontend JS (sources.js)
- loadGlobalSources lädt /languages parallel zu /global + /global/stats,
  populiert beide Sprache-Dropdowns + datalist im Edit-Modal.
- renderGlobalSources: cols 11 -> 13, language+bias-Zellen
  (Bias mit Tooltip fuer Lang-Texte).
- filterGlobalSources: Sprache-Filter, Bias in Suche.
- editGlobalSource: language + bias laden.
- Form-Submit: language + bias mitgesendet.
- renderTenantSources: cols 8 -> 10, language+bias-Zellen.
- tenantFilters um language erweitert, applyTenantFilterAndSort prueft.

Cache-Buster ?v=20260509 (heute) bleibt - Tag wechselt erst morgen.
2026-05-09 04:35:08 +00:00
claude-dev
9000750df2 Phase 9: Code-Hygiene - alle pyflakes-Issues fixen
15 pyflakes-Warnings entfernt:
- src/audit.py: HTTPException (in router import statt helper, war hier ungenutzt)
- src/routers/auth.py: status (FastAPI-status ungenutzt)
- src/routers/audit.py: HTTPException (ungenutzt)
- src/routers/users.py: MAGIC_LINK_EXPIRE_MINUTES (ungenutzt)
- src/routers/sources.py: row_to_dict, _extract_domain, _detect_category,
  urlparse, status (alle ungenutzt - status.HTTP_* wird nirgendwo aufgerufen)
- src/routers/sources.py: 2x f-string ohne Placeholder (URL aktualisiert,
  Verbindung fehlgeschlagen) zu normalen Strings
- src/routers/sources.py: except httpx.ConnectError as e -> e ungenutzt, weg
- src/database.py: os ungenutzt
- src/models.py: EmailStr ungenutzt

Audit-Coverage geprueft: alle write-Endpoints in users.py rufen
_toggle_field() auf, das die log_action-Aufrufe macht. Keine Audit-Luecken.
Alle anderen Routers (organizations/licenses/dashboard/token_usage)
hatten bereits saubere Audit-Coverage.

Mojibake-Diagnose ueber alle src/*.py: 0 Treffer.
2026-05-09 03:49:53 +00:00
claude-dev
e9ff2bac02 Phase 6: Verwendungs-Sicht pro Grundquelle
Backend
- /api/sources/global liefert pro Quelle articles_7d, articles_30d und
  tenant_excluded_count (eine aggregierte Query mit CTEs, kein N+1).
- Match-Logik fuer Articles: LOWER(articles.source) = LOWER(sources.name)
  - articles.source_url ist Artikel-URL, NICHT Feed-URL, daher matcht das
    nicht mit sources.url. source-Name-Match liefert sinnvolle Treffer.
- tenant_excluded_count zaehlt distinct organization_ids aus
  user_excluded_domains (per LOWER(domain)-Match).

Frontend
- dashboard.html: zwei neue sortierbare Spalten Aktivitaet (7d/30d) +
  Sperren in der Grundquellen-Tabelle.
- style.css: .activity-cell + .exclude-badge Styles (mit zero-Variante
  fuer ruhigen Look bei keiner Aktivitaet/Sperre).
- sources.js:
  - cols 9 -> 11
  - Render: 7d-Wert fett, 30d-Wert dezent, Tooltip 7 Tage / 30 Tage
  - Sort-Logik: NUMERIC_FIELDS um articles_7d/articles_30d/tenant_excluded_count
    erweitert (numerischer Compare statt localeCompare)
2026-05-09 03:23:42 +00:00
claude-dev
6b70a7195e Phase 5: Audit-Spur pro Quelle (ausklappbares Modal)
Backend
- routers/audit.py: GET /api/audit-log nimmt jetzt resource_id als Filter
  (zusätzlich zu resource_type, action, admin_id, from_ts/to_ts).

Frontend
- dashboard.html: modalAudit (Modal) für die Audit-Spur einer Ressource.
- style.css: audit-entry Styles (action-Badge mit Farbcode pro Action-Typ,
  Diff als <details>-Block mit JSON-Pre).
- sources.js:
  - showSourceAudit(id, name) öffnet Modal, lädt /audit-log?resource_type=source&resource_id=...
  - renderAuditEntries: pro Eintrag Action-Badge + Meta (ts/admin/ip) +
    optional ausklappbarer Diff (before/after-JSON)
  - formatDateTime Helper
  - Audit-Button in der Aktionen-Spalte der Grundquellen-Tabelle
2026-05-09 03:19:32 +00:00
claude-dev
2001815e19 Phase 4: Admin-Übersicht erweitern (Stats-Bar + Health-Badge inline + Letzter Treffer)
Backend
- routers/sources.py:
  - GET /api/sources/global/stats NEU: aggregierte Counter
    nach Typ, Total-Articles, Health-Bilanz (errors/warnings/ok)
  - GET /api/sources/global liefert pro Quelle health_status
    (worst-case error > warning > ok, NULL wenn nie gecheckt)

Frontend
- dashboard.html sub-global-sources: Stats-Bar Container oben.
  Tabellenkopf bekommt zwei neue Spalten: Letzter Treffer + Health.
- style.css: .sources-stats-bar (analog Monitor-Style),
  .health-badge mit Varianten error/warning/ok/unknown.
- sources.js:
  - loadGlobalSources lädt parallel /global + /global/stats
  - renderGlobalStats: rendert Stats-Bar mit Total-Quellen,
    Counts pro Typ (aus META), Total-Articles, Health-Counters
  - renderGlobalSources: 9 Spalten statt 7, Letzter-Treffer + Health-Badge,
    typeLabel statt TYPE_LABELS-Direktzugriff
2026-05-09 03:12:30 +00:00
claude-dev
9350e4538a Phase 3c: Kundenquellen-Tab mit Filter + Sort + Bulk-Promote
Backend
- routers/sources.py: POST /api/sources/tenant/bulk-promote NEU
  Nimmt Liste von source_ids, promotet jede einzeln zur Grundquelle.
  Returns {promoted, skipped[{id,name,reason}], failed[{id,error}]}.
  Ueberspringt Quellen die schon Grundquellen sind oder deren URL bereits
  als Grundquelle existiert.

Frontend
- dashboard.html sub-tenant-sources: action-bar erweitert um
  3 Filter-Selects (Typ, Kategorie, Org), Bulk-Promote-Button.
  Tabelle bekommt Checkbox-Spalte + sortable Spalten (Sort-Icons).
- sources.js: tenant-Tab komplett refactored
  - State: tenantFilters, tenantSort, tenantSelected (Set)
  - applyTenantFilterAndSort: zentraler Render-Pfad mit allen Filtern + Sort
  - populateTenantFilters: Org-Liste aus Daten, Typ/Kategorie aus META
  - toggleTenantSelect / toggleTenantSelectAll: Selection-Logik
  - bulkPromoteSelected: showConfirm -> POST -> Toast mit Ergebnis
  - renderTenantSources: Checkbox-Spalte, dynamische typeLabel/categoryLabel
  - Counter zeigt jetzt N gefiltert / Gesamt
2026-05-09 03:07:55 +00:00
claude-dev
eda60f9299 Phase 3b: Kategorien/Typen aus Backend (/api/sources/meta)
- src/source_meta.py NEU: SOURCE_CATEGORIES + SOURCE_TYPES als
  Single Source of Truth (Liste mit {key, label}). category_label/type_label
  Lookup-Funktionen, get_meta() liefert das gesamte Set.
- src/routers/sources.py: GET /api/sources/meta ergänzt (admin-auth,
  liefert Kategorien + Typen)
- src/static/js/app.js: window.META + loadMeta() + categoryLabel/typeLabel +
  populateSelect Helper. Beim DOMContentLoaded wird Meta geladen, befüllt
  globale CATEGORY_LABELS und TYPE_LABELS.
- src/static/js/sources.js: hardcoded const CATEGORY_LABELS und TYPE_LABELS
  entfernt - werden jetzt aus app.js loadMeta() global gesetzt.
  loadGlobalSources() ruft populateSelect() für die Filter-Dropdowns auf.
- src/static/js/source-health.js: gleiche hardcoded Listen entfernt.
- src/static/dashboard.html: <option>-Listen für globalFilterCategory und
  globalFilterType entfernt (nur noch default Alle). JS befüllt sie dynamisch.

Ergebnis: Bei einer neuen Kategorie nur source_meta.py anpassen,
keine 3-fach-Pflege mehr in HTML+sources.js+source-health.js.
2026-05-09 03:05:16 +00:00
claude-dev
ca4422ccd1 Phase 2 Health-Check tenant-fähig + Historie
- migrations/2026-05-09d_source_health_history.py NEU: source_health_history-Tabelle
  (Append-only Verlauf der Health-Check-Runs mit run_id und archived_at)
- shared/services/source_health.py:
  - tenant_id IS NULL Filter raus -> auch Tenant-Quellen werden gecheckt
  - Mojibake (Triple-Encoded UTF-8) via ftfy gefixt
  - DELETE FROM source_health_checks: vorher Stand mit run_id (uuid4) in
    source_health_history archivieren -> kein Datenverlust mehr
  - User-Agent + Timeout aus config.HEALTH_CHECK_* statt hardcoded
- routers/sources.py /health/run-stream: gleiche Änderungen wie oben
- config.py: HEALTH_CHECK_USER_AGENT + HEALTH_CHECK_TIMEOUT_S ergänzt
2026-05-09 02:56:49 +00:00
claude-dev
650f8b0342 Phase 1 Backend-Hygiene Quellen
- src/shared/ neu: source_rules, services/source_health, services/source_suggester,
  agents/claude_client als lokale Kopien aus dem Monitor-Repo (statt sys.path-Hack
  auf /home/claude-dev/AegisSight-Monitor/src - 5 sys.path.insert-Aufrufe entfernt)
- src/routers/sources.py: Imports auf shared. umgestellt, Header neu sortiert
  (Docstring zuerst, sys/os raus), Mojibake (Triple-Encoded UTF-8) via ftfy gefixt
- src/shared/services/source_suggester.py: Mojibake (Double-Encoded UTF-8) via ftfy gefixt
- migrations/2026-05-09c_source_health_schema.py NEU: source_health_checks +
  source_suggestions Tabellen mit Indizes (idempotent), gezogen aus 3 Inline-DDL-Blöcken
  in routers/sources.py (/health/run, /health/run-stream, /health/search-fix)
- src/config.py: CLAUDE_MODEL_MEDIUM und CLAUDE_MODEL_STANDARD ergänzt
  (vorher nur CLAUDE_MODEL_FAST - claude_client.py braucht alle drei)
- requirements.txt: httpx + feedparser explizit (im venv schon vorhanden, jetzt dokumentiert)
2026-05-09 02:47:13 +00:00
claude-dev
7c741062a9 Auth: Verwaltung auf Magic-Link umstellen (Passwort-Login entfernt)
Backend:
- src/routers/auth.py NEU: POST /api/auth/magic-link + POST /api/auth/verify
- src/auth.py: verify_password/hash_password raus, generate_magic_token rein
- src/main.py: alter Login-Endpoint + Brute-Force-Logik raus, neuer auth-Router eingebunden
- src/config.py: ALLOWED_EMAIL + PORTAL_MAGIC_LINK_* hinzu
- src/models.py: LoginRequest raus, MagicLinkRequest etc. rein
- src/email_utils/templates.py: portal_magic_link_email Template

Frontend:
- src/static/index.html: Email-Eingabe statt Passwort, Token-Verify-Logik fuer ?token= aus URL

Datenbank-Migration (migrations/2026-05-09_portal_magic_link.py):
- portal_magic_links + portal_magic_link_attempts neu
- portal_login_attempts gedroppt
- portal_admins.email Spalte hinzu, password_hash geleert

Whitelist info@aegis-sight.de, Rate-Limit 5/15 Min, Anti-Enumeration generische Antwort.
2026-05-09 02:21:40 +00:00
claude-dev
4dc372814d Audit-Log + Brute-Force-Schutz + unlimited_budget + User-Delete-Fix
- Schema-Migration: ON DELETE SET NULL fuer incidents.created_by, magic_links.user_id,
  network_analyses.created_by (behebt 500er beim User-Loeschen). Neue Spalte
  licenses.unlimited_budget. Neue Tabellen portal_audit_log, portal_login_attempts.
- Audit-Log: alle CREATE/UPDATE/DELETE auf Org/User/Lizenz/Quelle + Login-Events
  werden mit before/after-Diff in portal_audit_log geschrieben.
- Brute-Force-Schutz: 5 Fehlversuche pro IP+Username/15min -> 429 mit Retry-After.
- Token-Budget: expliziter Schalter unlimited_budget pro Lizenz. UI zeigt ehrlich
  >100%-Verbrauch (kein Math.min mehr) und ungebremste Anzeige bei unlimited.
- Neuer Audit-Log Tab mit Filter (Aktion/Ressource/Admin/Zeitraum) und Pagination.
2026-05-02 20:16:03 +00:00
claude-dev
0da66fb585 Podcast-Feed-Typ im Verwaltungsportal
Passt Verwaltung an die Podcast-Integration im Monitor an (Commit 5127e0a):

Backend (src/routers/sources.py):
- Pydantic-Pattern von GlobalSourceCreate + GlobalSourceUpdate um
  podcast_feed erweitert
- Health-Check Feed-Validierung greift jetzt auch fuer podcast_feed
  (Podcast-Feeds sind technisch RSS/Atom)

Frontend:
- src/static/js/sources.js: TYPE_LABELS um podcast_feed ("Podcast-Feed")
  ergaenzt
- src/static/dashboard.html: Neue <option value=podcast_feed> in Filter-
  und Anlage-Dropdown

Ohne diese Anpassung waere das Anlegen von Podcast-Quellen ueber das
Verwaltungsportal nicht moeglich (422 Unprocessable Entity vom
Pydantic-Validator).
2026-04-18 12:22:12 +00:00
Claude Dev
48c1892fea feat: Token-Nutzung nach Quelle (Monitor/Globe) aufgeschluesselt
- Backend liefert usage_by_source im current-Endpoint
- Monatliche Tabelle zeigt Quelle-Badge (Monitor/Globe)
- Source-Split unter den Kosten-KPIs sichtbar

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 20:44:20 +01:00
Claude Dev
1ebb68f147 Netzwerkanalyse-Zugang: network_access Toggle im User-Management
- network_access Spalte in UserResponse Model
- PUT /api/users/{id}/network-access Toggle-Endpoint
- Dashboard: Netzwerk-Spalte mit An/Aus-Button in User-Tabelle
2026-03-25 00:40:39 +01:00
Claude Dev
0e13dcb9a4 Globe-Zugang: Checkbox im User-Management
Neue Spalte "Globe" in der Nutzertabelle mit Toggle-Checkbox.
API-Endpoint PUT /api/users/{id}/globe-access.
Steuert das globe_access Feld in der geteilten DB.
2026-03-24 11:57:08 +01:00
Claude Dev
7cd36959b0 feat: Credits-System — Token-Usage-Router, Budget-Verwaltung, Frontend-Übersicht
- Neuer Router /api/token-usage mit Overview, Org-Detail, Monatsstatistik
- Budget-Felder (credits_total, cost_per_credit, token_budget_usd) bei Lizenz-Erstellung
- Token-Nutzung Sub-Tab in Org-Detail mit Verbrauchsbalken und Monatstabelle
- Dashboard Stat-Card für API-Kosten gesamt
- CSS Dark-Theme Styling für Token-Komponenten
2026-03-17 23:59:49 +01:00
Claude Dev
1d9de549ec Neue Kategorie russische-opposition in Verwaltungs-UI + 10 neue Telegram-Kanaele (Wave 3) 2026-03-13 19:08:44 +01:00
claude-dev
29f3e73480 Fix: Duplikat-Check + Stale-Check in Streaming-Endpoint
- Duplikat-Check in search-fix auf source_id+type umgestellt
- Stale-Check im Streaming-Endpoint überspringt web_sources

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 19:05:46 +01:00
claude-dev
d46eac4733 Fortschrittsanzeige beim Health-Check (SSE-Streaming)
- Neuer Endpoint /health/run-stream mit Server-Sent Events
- Frontend zeigt Fortschrittsbalken: 4/12 + Quellenname + Prozent
- Status-Icons pro Quelle (Fehler/Warnung/OK)
- Phase Vorschläge wird separat angezeigt
- Ergebnis-Zusammenfassung verschwindet nach 5 Sekunden

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 17:35:37 +01:00
claude-dev
eaceb5ef6b Vorschlagssystem: Sonnet-Prompt, Auto-Reject, Titellimit
- Sonnet: max 3 Lösungen, echte Umlaute erzwingen
- Auto-Reject: deactivate_source wird abgelehnt wenn fix_url akzeptiert
- Titel-Limit von 80 auf 120 Zeichen erhöht

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 17:29:19 +01:00
claude-dev
be0f31344a Sonnet-WebSearch "Lösung suchen" für kaputte Quellen
- POST /health/search-fix/{source_id}: Sonnet recherchiert Alternativen
- Button "Lösung suchen" bei Erreichbarkeits-Fehlern im Health-Tab
- Gefundene Lösungen werden automatisch als Vorschläge gespeichert

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 16:33:11 +01:00
claude-dev
7045a5c657 Quellen-Health UI: Tab, API-Endpunkte, Vorschläge
- Neuer Sub-Tab "Quellen-Health" mit Vorschlägen + Check-Ergebnissen
- API: GET /health, GET /suggestions, PUT /suggestions/{id}, POST /health/run
- Vorschläge annehmen/ablehnen mit Auto-Ausführung
- Badge-Styles für Health-Status und Prioritäten
- Umlaute in Source-Modal und Dashboard korrigiert

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 15:26:31 +01:00
claude-dev
801944a7ea feat: Discovery-Funktion in Grundquellen-Verwaltung integriert
- POST /api/sources/discover: URL analysieren, RSS-Feeds erkennen, Duplikate prüfen
- POST /api/sources/discover/add: Erkannte Feeds als Grundquellen anlegen (inkl. Web-Source)
- Erkennen-Button und Modal im Dashboard mit Feed-Auswahl per Checkbox
- Duplikat-Erkennung zeigt bereits vorhandene Grundquellen an
- source_rules aus Monitor importiert für Feed-Discovery und Claude-Bewertung
- config.py um Discovery-Konfiguration erweitert

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 20:04:18 +01:00
claude-dev
19fbf152eb Feat: Grundquellen-Verwaltung und Kundenquellen-Übersicht
- Neuer Tab "Quellen" mit Sub-Tabs "Grundquellen" und "Kundenquellen"
- Grundquellen: CRUD (Erstellen, Bearbeiten, Löschen) - gilt für alle Monitore
- Kundenquellen: Übersicht aller tenant-spezifischen Quellen mit Org-Zuordnung
- Kundenquellen können zu Grundquellen befördert werden
- Suche/Filter in beiden Ansichten
- Sources-Router mit vollständiger API

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 19:46:45 +01:00
claude-dev
af6040cbf6 Refactor: Name-Feld entfernen, Email als einziger Identifier
- Name-Spalte aus Nutzertabelle entfernt
- Anzeigename-Feld aus Nutzer-Anlegen-Dialog entfernt
- Username wird automatisch aus Email-Prefix generiert
- UserCreate Model: username jetzt optional

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 18:55:30 +01:00
claude-dev
e5a11d3549 Initial commit: AegisSight-Monitor-Verwaltung 2026-03-04 17:53:19 +01:00