""" Klausur-Service Grading Models Grade thresholds, labels, criteria, and audit logging. """ from dataclasses import dataclass from datetime import datetime from typing import Optional, Dict, Any # ============================================= # GRADE CONSTANTS # ============================================= GRADE_THRESHOLDS = { 15: 95, 14: 90, 13: 85, 12: 80, 11: 75, 10: 70, 9: 65, 8: 60, 7: 55, 6: 50, 5: 45, 4: 40, 3: 33, 2: 27, 1: 20, 0: 0 } GRADE_LABELS = { 15: "1+ (sehr gut plus)", 14: "1 (sehr gut)", 13: "1- (sehr gut minus)", 12: "2+ (gut plus)", 11: "2 (gut)", 10: "2- (gut minus)", 9: "3+ (befriedigend plus)", 8: "3 (befriedigend)", 7: "3- (befriedigend minus)", 6: "4+ (ausreichend plus)", 5: "4 (ausreichend)", 4: "4- (ausreichend minus)", 3: "5+ (mangelhaft plus)", 2: "5 (mangelhaft)", 1: "5- (mangelhaft minus)", 0: "6 (ungenuegend)" } DEFAULT_CRITERIA = { "rechtschreibung": {"weight": 0.15, "label": "Rechtschreibung"}, "grammatik": {"weight": 0.15, "label": "Grammatik"}, "inhalt": {"weight": 0.40, "label": "Inhalt"}, "struktur": {"weight": 0.15, "label": "Struktur"}, "stil": {"weight": 0.15, "label": "Stil"}, } # ============================================= # AUDIT LOG # ============================================= @dataclass class AuditLogEntry: """Audit log entry for tracking changes.""" id: str timestamp: datetime user_id: str action: str # score_update, gutachten_update, status_change, examiner_assign entity_type: str # klausur, student entity_id: str field: Optional[str] old_value: Optional[str] new_value: Optional[str] details: Optional[Dict] def to_dict(self) -> Dict[str, Any]: """Convert to dictionary for JSON serialization.""" return { 'id': self.id, 'timestamp': self.timestamp.isoformat(), 'user_id': self.user_id, 'action': self.action, 'entity_type': self.entity_type, 'entity_id': self.entity_id, 'field': self.field, 'old_value': self.old_value, 'new_value': self.new_value, 'details': self.details }