[split-required] Split 500-1000 LOC files across all services

backend-lehrer (5 files):
- alerts_agent/db/repository.py (992 → 5), abitur_docs_api.py (956 → 3)
- teacher_dashboard_api.py (951 → 3), services/pdf_service.py (916 → 3)
- mail/mail_db.py (987 → 6)

klausur-service (5 files):
- legal_templates_ingestion.py (942 → 3), ocr_pipeline_postprocess.py (929 → 4)
- ocr_pipeline_words.py (876 → 3), ocr_pipeline_ocr_merge.py (616 → 2)
- KorrekturPage.tsx (956 → 6)

website (5 pages):
- mail (985 → 9), edu-search (958 → 8), mac-mini (950 → 7)
- ocr-labeling (946 → 7), audit-workspace (871 → 4)

studio-v2 (5 files + 1 deleted):
- page.tsx (946 → 5), MessagesContext.tsx (925 → 4)
- korrektur (914 → 6), worksheet-cleanup (899 → 6)
- useVocabWorksheet.ts (888 → 3)
- Deleted dead page-original.tsx (934 LOC)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Benjamin Admin
2026-04-24 23:35:37 +02:00
parent 6811264756
commit b6983ab1dc
99 changed files with 13484 additions and 16106 deletions

View File

@@ -0,0 +1,187 @@
"""
Repository für Alert Rules (Filterregeln).
"""
import uuid
from datetime import datetime
from typing import Optional, List, Dict, Any
from sqlalchemy.orm import Session as DBSession
from sqlalchemy import or_
from .models import AlertRuleDB, RuleActionEnum
class RuleRepository:
"""Repository für Alert Rules (Filterregeln)."""
def __init__(self, db: DBSession):
self.db = db
# ==================== CREATE ====================
def create(
self,
name: str,
conditions: List[Dict],
action_type: str = "keep",
action_config: Dict = None,
topic_id: str = None,
user_id: str = None,
description: str = "",
priority: int = 0,
) -> AlertRuleDB:
"""Erstellt eine neue Regel."""
rule = AlertRuleDB(
id=str(uuid.uuid4()),
topic_id=topic_id,
user_id=user_id,
name=name,
description=description,
conditions=conditions,
action_type=RuleActionEnum(action_type),
action_config=action_config or {},
priority=priority,
)
self.db.add(rule)
self.db.commit()
self.db.refresh(rule)
return rule
# ==================== READ ====================
def get_by_id(self, rule_id: str) -> Optional[AlertRuleDB]:
"""Holt eine Regel nach ID."""
return self.db.query(AlertRuleDB).filter(
AlertRuleDB.id == rule_id
).first()
def get_active(
self,
topic_id: str = None,
user_id: str = None,
) -> List[AlertRuleDB]:
"""Holt alle aktiven Regeln, sortiert nach Priorität."""
query = self.db.query(AlertRuleDB).filter(
AlertRuleDB.is_active == True
)
if topic_id:
# Topic-spezifische und globale Regeln
query = query.filter(
or_(
AlertRuleDB.topic_id == topic_id,
AlertRuleDB.topic_id.is_(None)
)
)
if user_id:
query = query.filter(
or_(
AlertRuleDB.user_id == user_id,
AlertRuleDB.user_id.is_(None)
)
)
return query.order_by(AlertRuleDB.priority.desc()).all()
def get_all(
self,
user_id: str = None,
topic_id: str = None,
is_active: bool = None,
) -> List[AlertRuleDB]:
"""Holt alle Regeln mit optionalen Filtern."""
query = self.db.query(AlertRuleDB)
if user_id:
query = query.filter(AlertRuleDB.user_id == user_id)
if topic_id:
query = query.filter(AlertRuleDB.topic_id == topic_id)
if is_active is not None:
query = query.filter(AlertRuleDB.is_active == is_active)
return query.order_by(AlertRuleDB.priority.desc()).all()
# ==================== UPDATE ====================
def update(
self,
rule_id: str,
name: str = None,
description: str = None,
conditions: List[Dict] = None,
action_type: str = None,
action_config: Dict = None,
priority: int = None,
is_active: bool = None,
) -> Optional[AlertRuleDB]:
"""Aktualisiert eine Regel."""
rule = self.get_by_id(rule_id)
if not rule:
return None
if name is not None:
rule.name = name
if description is not None:
rule.description = description
if conditions is not None:
rule.conditions = conditions
if action_type is not None:
rule.action_type = RuleActionEnum(action_type)
if action_config is not None:
rule.action_config = action_config
if priority is not None:
rule.priority = priority
if is_active is not None:
rule.is_active = is_active
self.db.commit()
self.db.refresh(rule)
return rule
def increment_match_count(self, rule_id: str) -> Optional[AlertRuleDB]:
"""Erhöht den Match-Counter einer Regel."""
rule = self.get_by_id(rule_id)
if not rule:
return None
rule.match_count += 1
rule.last_matched_at = datetime.utcnow()
self.db.commit()
self.db.refresh(rule)
return rule
# ==================== DELETE ====================
def delete(self, rule_id: str) -> bool:
"""Löscht eine Regel."""
rule = self.get_by_id(rule_id)
if not rule:
return False
self.db.delete(rule)
self.db.commit()
return True
# ==================== CONVERSION ====================
def to_dict(self, rule: AlertRuleDB) -> Dict[str, Any]:
"""Konvertiert DB-Model zu Dictionary."""
return {
"id": rule.id,
"topic_id": rule.topic_id,
"user_id": rule.user_id,
"name": rule.name,
"description": rule.description,
"conditions": rule.conditions,
"action_type": rule.action_type.value,
"action_config": rule.action_config,
"priority": rule.priority,
"is_active": rule.is_active,
"stats": {
"match_count": rule.match_count,
"last_matched_at": rule.last_matched_at.isoformat() if rule.last_matched_at else None,
},
"created_at": rule.created_at.isoformat() if rule.created_at else None,
"updated_at": rule.updated_at.isoformat() if rule.updated_at else None,
}