"""Stable backend protocol enums. Database columns and JSON payloads continue to store the enum string values. Configurable identifiers, user-authored values, and open-ended taxonomies do not belong in this module. """ from __future__ import annotations import logging from enum import StrEnum from typing import TypeVar logger = logging.getLogger(__name__) EnumT = TypeVar("EnumT", bound=StrEnum) def parse_enum(enum_type: type[EnumT], value: object, default: EnumT) -> EnumT: """Parse an external value without breaking reads of legacy data.""" if value is None or str(value).strip() == "": return default if isinstance(value, enum_type): return value try: return enum_type(str(value).strip().lower()) except (TypeError, ValueError): logger.warning( "Unknown %s value %r; falling back to %s", enum_type.__name__, value, default.value, ) return default class NewsImportanceLevel(StrEnum): LOW = "low" MEDIUM = "medium" HIGH = "high" CRITICAL = "critical" class BreakingLevel(StrEnum): NONE = "none" WATCH = "watch" BREAKING = "breaking" CRITICAL = "critical" class BreakingScope(StrEnum): REGIONAL = "regional" GLOBAL = "global" class BreakingSource(StrEnum): RULES = "rules" AI = "ai" MANUAL = "manual" MULTI_SOURCE = "multi_source" class NewsSourceType(StrEnum): RSS = "rss" ATOM = "atom" AGGREGATED = "aggregated" REFERENCE = "reference" MANUAL = "manual" class NewsEnrichmentStatus(StrEnum): PENDING = "pending" QUEUED = "queued" ATTEMPTED = "attempted" SUCCESS = "success" CONTENT_ONLY = "content_only" LOCATION_ONLY = "location_only" UNAVAILABLE = "unavailable" PROVIDER_ERROR = "provider_error" PARSE_ERROR = "parse_error" NO_RESULT = "no_result" class NewsMarketImpact(StrEnum): NONE = "none" SECTOR = "sector" NATIONAL = "national" GLOBAL = "global" class NewsTaggingSource(StrEnum): RULES = "rules" AI = "ai" MANUAL = "manual" class JobType(StrEnum): COLLECT = "collect" CLEAR_DATA = "clear_data" CLEAR_CACHE = "clear_cache" EARTH_REFRESH = "earth_refresh" class JobStatus(StrEnum): QUEUED = "queued" RUNNING = "running" CANCELLING = "cancelling" SUCCESS = "success" FAILED = "failed" CANCELLED = "cancelled" class RollbackPolicy(StrEnum): KEEP_COMMITTED_BATCHES = "keep_committed_batches" class MappingValidationStatus(StrEnum): DRAFT = "draft" VALID = "valid" INVALID = "invalid" class SnapshotStatus(StrEnum): RUNNING = "running" SUCCESS = "success" FAILED = "failed" CANCELLED = "cancelled" class DatasourceRunStatus(StrEnum): RUNNING = "running" NOT_RUN = "not_run" COLLECTED = "collected" UNCOLLECTED = "uncollected" class ProviderApi(StrEnum): ANTHROPIC_MESSAGES = "anthropic-messages" OPENAI_COMPLETIONS = "openai-completions" OLLAMA_GENERATE = "ollama-generate" class PlaygroundMessageRole(StrEnum): SYSTEM = "system" USER = "user" ASSISTANT = "assistant" TOOL = "tool" class PlaygroundMessageKind(StrEnum): MESSAGE = "message" THINKING = "thinking" ERROR = "error" STATUS = "status" class PlaygroundMessageStatus(StrEnum): PENDING = "pending" THINKING = "thinking" ANSWERING = "answering" DONE = "done" FAILED = "failed" CANCELLED = "cancelled" ERROR = "error" STOPPED = "stopped" class OtpPurpose(StrEnum): REGISTER = "register" VERIFY_EMAIL = "verify_email" RESET_PASSWORD = "reset_password" class UserRole(StrEnum): VIEWER = "viewer" ADMIN = "admin" SUPER_ADMIN = "super_admin" class AlertSeverity(StrEnum): CRITICAL = "critical" WARNING = "warning" INFO = "info" class AlertStatus(StrEnum): ACTIVE = "active" ACKNOWLEDGED = "acknowledged" RESOLVED = "resolved" class BGPStatus(StrEnum): ACTIVE = "active" ACKNOWLEDGED = "acknowledged" RESOLVED = "resolved" class LogLevel(StrEnum): ALL = "all" ERROR = "error" WARNING = "warning" INFO = "info" DEBUG = "debug" class ConnectionState(StrEnum): DISCONNECTED = "disconnected" CONNECTING = "connecting" CONNECTED = "connected" ERROR = "error" class AuthType(StrEnum): NONE = "none" BEARER = "bearer" API_KEY = "api_key" BASIC = "basic" class TVSourceType(StrEnum): IFRAME = "iframe" HLS = "hls" VIDEO = "video" EXTERNAL = "external" YOUTUBE = "youtube"