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).
Dieser Commit ist enthalten in:
Claude Code
2026-05-13 20:57:51 +00:00
Ursprung f68d25dbce
Commit 9754dcb4ef
3 geänderte Dateien mit 61 neuen und 9 gelöschten Zeilen

Datei anzeigen

@@ -181,7 +181,8 @@ CREATE TABLE IF NOT EXISTS sources (
eu_disinfo_case_count INTEGER DEFAULT 0,
eu_disinfo_last_seen TIMESTAMP,
ifcn_signatory INTEGER DEFAULT 0,
external_data_synced_at TIMESTAMP
external_data_synced_at TIMESTAMP,
primary_language TEXT
);
CREATE TABLE IF NOT EXISTS source_alignments (
@@ -817,6 +818,42 @@ async def init_db():
""")
await db.commit()
# Migration: sources.primary_language (ISO-2-Sprachcode aus Freitext-Feld 'language')
cursor = await db.execute("PRAGMA table_info(sources)")
sources_columns = [row[1] for row in await cursor.fetchall()]
if "primary_language" not in sources_columns:
await db.execute("ALTER TABLE sources ADD COLUMN primary_language TEXT")
await db.commit()
logger.info("Migration: primary_language zu sources hinzugefuegt")
# Backfill: aus Freitext-Feld 'language' (z.B. 'Deutsch', 'Hebraeisch/Englisch')
# die erste Sprache als ISO-Code uebernehmen. Nur fuer Quellen mit NULL primary_language.
_LANGUAGE_LOOKUP = {
"Deutsch": "de", "Englisch": "en", "Russisch": "ru", "Ukrainisch": "uk",
"Arabisch": "ar", "Hebraeisch": "he", "Hebräisch": "he",
"Farsi": "fa", "Japanisch": "ja", "Kurdisch": "ku", "Malaiisch": "ms",
}
cursor = await db.execute(
"SELECT id, language FROM sources WHERE primary_language IS NULL"
)
rows = await cursor.fetchall()
backfilled = 0
for row in rows:
sid = row[0]
lang = row[1]
iso = "de" # Default fuer NULL oder unbekannt
if lang:
first = lang.split("/")[0].strip()
iso = _LANGUAGE_LOOKUP.get(first, "de")
await db.execute(
"UPDATE sources SET primary_language = ? WHERE id = ?",
(iso, sid),
)
backfilled += 1
if backfilled:
await db.commit()
logger.info("Migration: primary_language Backfill fuer %d Quellen", backfilled)
# Verwaiste running-Eintraege beim Start als error markieren (aelter als 15 Min)
await db.execute(
"""UPDATE refresh_log SET status = 'error', error_message = 'Verwaist beim Neustart',