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>
85 lines
2.2 KiB
Python
85 lines
2.2 KiB
Python
"""
|
|
PDF Service - Data Models and Shared Types.
|
|
|
|
Dataclasses for letters, certificates, and corrections.
|
|
"""
|
|
|
|
from dataclasses import dataclass
|
|
from typing import Any, Dict, Optional, List
|
|
|
|
|
|
@dataclass
|
|
class SchoolInfo:
|
|
"""Schulinformationen für Header."""
|
|
name: str
|
|
address: str
|
|
phone: str
|
|
email: str
|
|
logo_path: Optional[str] = None
|
|
website: Optional[str] = None
|
|
principal: Optional[str] = None
|
|
|
|
|
|
@dataclass
|
|
class LetterData:
|
|
"""Daten für Elternbrief-PDF."""
|
|
recipient_name: str
|
|
recipient_address: str
|
|
student_name: str
|
|
student_class: str
|
|
subject: str
|
|
content: str
|
|
date: str
|
|
teacher_name: str
|
|
teacher_title: Optional[str] = None
|
|
school_info: Optional[SchoolInfo] = None
|
|
letter_type: str = "general" # general, halbjahr, fehlzeiten, elternabend, lob
|
|
tone: str = "professional"
|
|
legal_references: Optional[List[Dict[str, str]]] = None
|
|
gfk_principles_applied: Optional[List[str]] = None
|
|
|
|
|
|
@dataclass
|
|
class CertificateData:
|
|
"""Daten für Zeugnis-PDF."""
|
|
student_name: str
|
|
student_birthdate: str
|
|
student_class: str
|
|
school_year: str
|
|
certificate_type: str # halbjahr, jahres, abschluss
|
|
subjects: List[Dict[str, Any]] # [{name, grade, note}]
|
|
attendance: Dict[str, int] # {days_absent, days_excused, days_unexcused}
|
|
remarks: Optional[str] = None
|
|
class_teacher: str = ""
|
|
principal: str = ""
|
|
school_info: Optional[SchoolInfo] = None
|
|
issue_date: str = ""
|
|
social_behavior: Optional[str] = None # A, B, C, D
|
|
work_behavior: Optional[str] = None # A, B, C, D
|
|
|
|
|
|
@dataclass
|
|
class StudentInfo:
|
|
"""Schülerinformationen für Korrektur-PDFs."""
|
|
student_id: str
|
|
name: str
|
|
class_name: str
|
|
|
|
|
|
@dataclass
|
|
class CorrectionData:
|
|
"""Daten für Korrektur-Übersicht PDF."""
|
|
student: StudentInfo
|
|
exam_title: str
|
|
subject: str
|
|
date: str
|
|
max_points: int
|
|
achieved_points: int
|
|
grade: str
|
|
percentage: float
|
|
corrections: List[Dict[str, Any]] # [{question, answer, points, feedback}]
|
|
teacher_notes: str = ""
|
|
ai_feedback: str = ""
|
|
grade_distribution: Optional[Dict[str, int]] = None # {note: anzahl}
|
|
class_average: Optional[float] = None
|