""" Antizipation Engine - SuggestionGenerator. Main class that collects signals, evaluates rules, and generates prioritized suggestions for teachers. """ from typing import List, Dict, Any from .antizipation_models import Signals, ActiveContext, ContextType from .antizipation_collector import SignalCollector from .antizipation_rules import RuleEngine class SuggestionGenerator: """ Hauptklasse die Signale sammelt, Regeln evaluiert und Vorschlaege generiert. """ def __init__(self, db_session=None): self.collector = SignalCollector(db_session) self.rule_engine = RuleEngine() def generate(self, teacher_id: str, limit: int = 5) -> Dict[str, Any]: """ Generiert Vorschlaege fuer einen Lehrer. Returns: { "active_contexts": [...], "suggestions": [...], "signals_summary": {...} } """ # 1. Signale sammeln signals = self.collector.collect(teacher_id) # 2. Regeln evaluieren all_suggestions = self.rule_engine.evaluate(signals) # 3. Aktive Kontexte bestimmen active_contexts = self._determine_active_contexts(signals) # 4. Top N Vorschlaege top_suggestions = all_suggestions[:limit] return { "active_contexts": [ { "id": ctx.id, "type": ctx.context_type.value, "label": ctx.label, } for ctx in active_contexts ], "suggestions": [ { "id": s.id, "title": s.title, "description": s.description, "tone": s.tone.value, "badge": s.badge, "priority": s.priority, "icon": s.icon, "action_url": s.action_url, } for s in top_suggestions ], "signals_summary": { "macro_phase": signals.macro_phase, "current_week": signals.current_week, "has_classes": signals.has_classes, "exams_soon": len(signals.exams_in_7_days), "routines_today": len(signals.routines_today), }, "total_suggestions": len(all_suggestions), } def _determine_active_contexts(self, signals: Signals) -> List[ActiveContext]: """Bestimmt die aktiven Kontexte basierend auf Signalen.""" contexts = [] # Event-Kontexte if signals.exams_in_7_days: contexts.append(ActiveContext( id="EXAM_IN_7_DAYS", context_type=ContextType.EVENT_WINDOW, label="Klausur in 7 Tagen", )) if signals.trips_in_30_days: contexts.append(ActiveContext( id="TRIP_UPCOMING", context_type=ContextType.EVENT_WINDOW, label="Klassenfahrt geplant", )) # Routine-Kontexte if signals.has_conference_today: contexts.append(ActiveContext( id="CONFERENCE_TODAY", context_type=ContextType.ROUTINE, label="Konferenz heute", )) # Zeit-Kontexte if signals.is_weekend: contexts.append(ActiveContext( id="WEEKEND", context_type=ContextType.TIME, label="Wochenende", )) if signals.is_before_holidays: contexts.append(ActiveContext( id="BEFORE_HOLIDAYS", context_type=ContextType.TIME, label="Vor den Ferien", )) # Phase-Kontexte if signals.macro_phase == "onboarding": contexts.append(ActiveContext( id="ONBOARDING", context_type=ContextType.PHASE, label="Einrichtung", )) elif signals.macro_phase in ("halbjahresabschluss", "jahresabschluss"): contexts.append(ActiveContext( id="GRADE_PERIOD", context_type=ContextType.PHASE, label="Notenphase", )) return contexts