Files
breakpilot-lehrer/backend-lehrer/alerts_agent/api/digests_models.py
Benjamin Admin bd4b956e3c [split-required] Split final 43 files (500-668 LOC) to complete refactoring
klausur-service (11 files):
- cv_gutter_repair, ocr_pipeline_regression, upload_api
- ocr_pipeline_sessions, smart_spell, nru_worksheet_generator
- ocr_pipeline_overlays, mail/aggregator, zeugnis_api
- cv_syllable_detect, self_rag

backend-lehrer (17 files):
- classroom_engine/suggestions, generators/quiz_generator
- worksheets_api, llm_gateway/comparison, state_engine_api
- classroom/models (→ 4 submodules), services/file_processor
- alerts_agent/api/wizard+digests+routes, content_generators/pdf
- classroom/routes/sessions, llm_gateway/inference
- classroom_engine/analytics, auth/keycloak_auth
- alerts_agent/processing/rule_engine, ai_processor/print_versions

agent-core (5 files):
- brain/memory_store, brain/knowledge_graph, brain/context_manager
- orchestrator/supervisor, sessions/session_manager

admin-lehrer (5 components):
- GridOverlay, StepGridReview, DevOpsPipelineSidebar
- DataFlowDiagram, sbom/wizard/page

website (2 files):
- DependencyMap, lehrer/abitur-archiv

Other: nibis_ingestion, grid_detection_service, export-doclayout-onnx

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-25 09:41:42 +02:00

117 lines
3.4 KiB
Python

"""
Alert Digests - Request/Response Models und Konverter.
"""
from typing import Optional, List
from datetime import datetime
from pydantic import BaseModel, Field
from ..db.models import AlertDigestDB
# ============================================================================
# Request/Response Models
# ============================================================================
class DigestListItem(BaseModel):
"""Kurze Digest-Info fuer Liste."""
id: str
period_start: datetime
period_end: datetime
total_alerts: int
critical_count: int
urgent_count: int
status: str
created_at: datetime
class DigestDetail(BaseModel):
"""Vollstaendige Digest-Details."""
id: str
subscription_id: Optional[str]
user_id: str
period_start: datetime
period_end: datetime
summary_html: str
summary_pdf_url: Optional[str]
total_alerts: int
critical_count: int
urgent_count: int
important_count: int
review_count: int
info_count: int
status: str
sent_at: Optional[datetime]
created_at: datetime
class DigestListResponse(BaseModel):
"""Response fuer Digest-Liste."""
digests: List[DigestListItem]
total: int
class GenerateDigestRequest(BaseModel):
"""Request fuer manuelle Digest-Generierung."""
weeks_back: int = Field(default=1, ge=1, le=4, description="Wochen zurueck")
force_regenerate: bool = Field(default=False, description="Vorhandenen Digest ueberschreiben")
class GenerateDigestResponse(BaseModel):
"""Response fuer Digest-Generierung."""
status: str
digest_id: Optional[str]
message: str
class SendEmailRequest(BaseModel):
"""Request fuer E-Mail-Versand."""
email: Optional[str] = Field(default=None, description="E-Mail-Adresse (optional)")
class SendEmailResponse(BaseModel):
"""Response fuer E-Mail-Versand."""
status: str
sent_to: str
message: str
# ============================================================================
# Converter Functions
# ============================================================================
def digest_to_list_item(digest: AlertDigestDB) -> DigestListItem:
"""Konvertiere DB-Model zu List-Item."""
return DigestListItem(
id=digest.id,
period_start=digest.period_start,
period_end=digest.period_end,
total_alerts=digest.total_alerts or 0,
critical_count=digest.critical_count or 0,
urgent_count=digest.urgent_count or 0,
status=digest.status.value if digest.status else "pending",
created_at=digest.created_at
)
def digest_to_detail(digest: AlertDigestDB) -> DigestDetail:
"""Konvertiere DB-Model zu Detail."""
return DigestDetail(
id=digest.id,
subscription_id=digest.subscription_id,
user_id=digest.user_id,
period_start=digest.period_start,
period_end=digest.period_end,
summary_html=digest.summary_html or "",
summary_pdf_url=digest.summary_pdf_url,
total_alerts=digest.total_alerts or 0,
critical_count=digest.critical_count or 0,
urgent_count=digest.urgent_count or 0,
important_count=digest.important_count or 0,
review_count=digest.review_count or 0,
info_count=digest.info_count or 0,
status=digest.status.value if digest.status else "pending",
sent_at=digest.sent_at,
created_at=digest.created_at
)