Files
breakpilot-lehrer/backend-lehrer/classroom/models_analytics.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

162 lines
4.8 KiB
Python

"""
Classroom API - Analytics, Reflection, Feedback, Settings Pydantic Models.
"""
from typing import Dict, List, Optional, Any
from pydantic import BaseModel, Field
# === Analytics Models ===
class SessionSummaryResponse(BaseModel):
"""Response fuer Session-Summary."""
session_id: str
teacher_id: str
class_id: str
subject: str
topic: Optional[str]
date: Optional[str]
date_formatted: str
total_duration_seconds: int
total_duration_formatted: str
planned_duration_seconds: int
planned_duration_formatted: str
phases_completed: int
total_phases: int
completion_percentage: int
phase_statistics: List[Dict[str, Any]]
total_overtime_seconds: int
total_overtime_formatted: str
phases_with_overtime: int
total_pause_count: int
total_pause_seconds: int
reflection_notes: str = ""
reflection_rating: Optional[int] = None
key_learnings: List[str] = []
class TeacherAnalyticsResponse(BaseModel):
"""Response fuer Lehrer-Analytics."""
teacher_id: str
period_start: Optional[str]
period_end: Optional[str]
total_sessions: int
completed_sessions: int
total_teaching_minutes: int
total_teaching_hours: float
avg_phase_durations: Dict[str, int]
sessions_with_overtime: int
overtime_percentage: int
avg_overtime_seconds: int
avg_overtime_formatted: str
most_overtime_phase: Optional[str]
avg_pause_count: float
avg_pause_duration_seconds: int
subjects_taught: Dict[str, int]
classes_taught: Dict[str, int]
class ReflectionCreate(BaseModel):
"""Request-Body fuer Reflection-Erstellung."""
session_id: str
teacher_id: str
notes: str = ""
overall_rating: Optional[int] = Field(None, ge=1, le=5)
what_worked: List[str] = []
improvements: List[str] = []
notes_for_next_lesson: str = ""
class ReflectionUpdate(BaseModel):
"""Request-Body fuer Reflection-Update."""
notes: Optional[str] = None
overall_rating: Optional[int] = Field(None, ge=1, le=5)
what_worked: Optional[List[str]] = None
improvements: Optional[List[str]] = None
notes_for_next_lesson: Optional[str] = None
class ReflectionResponse(BaseModel):
"""Response fuer eine einzelne Reflection."""
reflection_id: str
session_id: str
teacher_id: str
notes: str
overall_rating: Optional[int]
what_worked: List[str]
improvements: List[str]
notes_for_next_lesson: str
created_at: Optional[str]
updated_at: Optional[str]
# === Feedback Models ===
class FeedbackCreate(BaseModel):
"""Request zum Erstellen von Feedback."""
title: str = Field(..., min_length=3, max_length=500, description="Kurzer Titel")
description: str = Field(..., min_length=10, description="Beschreibung")
feedback_type: str = Field("improvement", description="bug, feature_request, improvement, praise, question")
priority: str = Field("medium", description="critical, high, medium, low")
teacher_name: str = Field("", description="Name des Lehrers")
teacher_email: str = Field("", description="E-Mail fuer Rueckfragen")
context_url: str = Field("", description="URL wo Feedback gegeben wurde")
context_phase: str = Field("", description="Aktuelle Phase")
context_session_id: Optional[str] = Field(None, description="Session-ID falls aktiv")
related_feature: Optional[str] = Field(None, description="Verwandtes Feature")
class FeedbackResponse(BaseModel):
"""Response fuer Feedback."""
id: str
teacher_id: str
teacher_name: str
title: str
description: str
feedback_type: str
priority: str
status: str
created_at: str
response: Optional[str] = None
class FeedbackListResponse(BaseModel):
"""Liste von Feedbacks."""
feedbacks: List[Dict[str, Any]]
total: int
class FeedbackStatsResponse(BaseModel):
"""Feedback-Statistiken."""
total: int
by_status: Dict[str, int]
by_type: Dict[str, int]
by_priority: Dict[str, int]
# === Settings Models ===
class TeacherSettingsResponse(BaseModel):
"""Response fuer Lehrer-Einstellungen."""
teacher_id: str
default_phase_durations: Dict[str, int]
audio_enabled: bool = True
high_contrast: bool = False
show_statistics: bool = True
class UpdatePhaseDurationsRequest(BaseModel):
"""Request zum Aktualisieren der Phasen-Dauern."""
durations: Dict[str, int] = Field(
...,
description="Phasen-Dauern in Minuten, z.B. {'einstieg': 10, 'erarbeitung': 25}",
examples=[{"einstieg": 10, "erarbeitung": 25, "sicherung": 10, "transfer": 8, "reflexion": 5}]
)
class UpdatePreferencesRequest(BaseModel):
"""Request zum Aktualisieren der UI-Praeferenzen."""
audio_enabled: Optional[bool] = None
high_contrast: Optional[bool] = None
show_statistics: Optional[bool] = None