"""Уведомления в центр зоотехника по алертам feed_quality.""" from __future__ import annotations import logging from typing import Iterable from app.models.feed_alert import FeedAlert from app.services.feed_quality.rules import ( EVENT_LEFT_IN_MIXER, EVENT_LOADING_FAST, EVENT_LOADING_TIME, EVENT_MIX_TIME, EVENT_OVERLOAD, EVENT_UNDERLOAD, SEVERITY_ERROR, SEVERITY_WARNING, settings_section_for_alert, ) from app.services.feed_quality.settings_store import get_feed_quality_settings from app.services.notification_center_service import create_notification, format_detail_timestamp logger = logging.getLogger(__name__) _EVENT_TITLES = { EVENT_OVERLOAD: "Перегруз при загрузке", EVENT_UNDERLOAD: "Недогруз при загрузке", EVENT_LOADING_TIME: "Долгая загрузка компонента", EVENT_LOADING_FAST: "Быстрая загрузка компонента", EVENT_MIX_TIME: "Отклонение смешивания", EVENT_LEFT_IN_MIXER: "Остаток в миксере", } def _alert_title(alert: FeedAlert) -> str: if alert.group_name and alert.event_type in (EVENT_OVERLOAD, EVENT_UNDERLOAD): return "Отклонение при выгрузке" return _EVENT_TITLES.get(alert.event_type, "Отклонение кормления") def _alert_detail(alert: FeedAlert) -> str: when = format_detail_timestamp(alert.created_at) recipe = alert.recipe_name or "рейс" return f"Рейс «{recipe}»: {alert.detail} — {when}" def _should_notify(alert: FeedAlert) -> bool: if alert.severity not in (SEVERITY_WARNING, SEVERITY_ERROR): return False section_key = settings_section_for_alert( alert.event_type, component_name=alert.component_name, group_name=alert.group_name, ) cfg = get_feed_quality_settings().get(section_key) or {} if alert.severity == SEVERITY_ERROR: return bool(cfg.get("notify_critical", True)) return bool(cfg.get("notify_warning", True)) def notify_feed_quality_alerts(alerts: Iterable[FeedAlert]) -> int: """Создаёт записи в «К» по флагам notify_* в настройках.""" count = 0 for alert in alerts: if not _should_notify(alert): continue kind = "error" if alert.severity == SEVERITY_ERROR else "warning" try: create_notification( title=_alert_title(alert), detail=_alert_detail(alert), kind=kind, category="feed_quality", page="reports", link_kind="report_loading", link_id=alert.loading_report_id, ) count += 1 except Exception: logger.exception( "[FEED-QUALITY-NOTIFY] alert=%s report=%s", alert.id, alert.loading_report_id, ) return count