"""Single Source of Truth für Quellen-Kategorien und -Typen. Wird vom Backend über GET /api/sources/meta exportiert. Frontend (sources.js, source-health.js, dashboard.html) lädt diese beim Init und befüllt damit Filter-Dropdowns und Label-Lookups. """ from typing import TypedDict class CategoryEntry(TypedDict): key: str label: str class TypeEntry(TypedDict): key: str label: str SOURCE_CATEGORIES: list[CategoryEntry] = [ {"key": "nachrichtenagentur", "label": "Nachrichtenagentur"}, {"key": "oeffentlich-rechtlich", "label": "Öffentlich-Rechtlich"}, {"key": "qualitaetszeitung", "label": "Qualitätszeitung"}, {"key": "behoerde", "label": "Behörde"}, {"key": "fachmedien", "label": "Fachmedien"}, {"key": "think-tank", "label": "Think-Tank"}, {"key": "international", "label": "International"}, {"key": "regional", "label": "Regional"}, {"key": "boulevard", "label": "Boulevard"}, {"key": "telegram", "label": "Telegram"}, {"key": "x", "label": "X (Twitter)"}, {"key": "sonstige", "label": "Sonstige"}, ] SOURCE_TYPES: list[TypeEntry] = [ {"key": "rss_feed", "label": "RSS-Feed"}, {"key": "web_source", "label": "Webquelle"}, {"key": "telegram_channel", "label": "Telegram-Kanal"}, {"key": "podcast_feed", "label": "Podcast-Feed"}, {"key": "x_account", "label": "X-Konto"}, {"key": "pdf_document", "label": "PDF-Dokument"}, ] def get_meta() -> dict: """Vollständige Meta-Information für Frontend-Konsumenten.""" return { "categories": SOURCE_CATEGORIES, "types": SOURCE_TYPES, } def category_label(key: str) -> str: """Lookup: Kategorie-Key -> Label. Fallback: Key selbst.""" for c in SOURCE_CATEGORIES: if c["key"] == key: return c["label"] return key def type_label(key: str) -> str: """Lookup: Typ-Key -> Label. Fallback: Key selbst.""" for t in SOURCE_TYPES: if t["key"] == key: return t["label"] return key