klausur-service (7 monoliths): - grid_editor_helpers.py (1,737 → 5 files: columns, filters, headers, zones) - cv_cell_grid.py (1,675 → 7 files: build, legacy, streaming, merge, vocab) - worksheet_editor_api.py (1,305 → 4 files: models, AI, reconstruct, routes) - legal_corpus_ingestion.py (1,280 → 3 files: registry, chunking, ingestion) - cv_review.py (1,248 → 4 files: pipeline, spell, LLM, barrel) - cv_preprocessing.py (1,166 → 3 files: deskew, dewarp, barrel) - rbac.py, admin_api.py, routes/eh.py remain (next batch) backend-lehrer (1 monolith): - classroom_engine/repository.py (1,705 → 7 files by domain) All re-export barrels preserve backward compatibility. Zero import errors verified. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
249 lines
8.0 KiB
Python
249 lines
8.0 KiB
Python
"""
|
|
Session & Teacher Settings Repositories.
|
|
|
|
CRUD-Operationen fuer LessonSessions und Lehrer-Einstellungen.
|
|
"""
|
|
from typing import Optional, List, Dict
|
|
|
|
from sqlalchemy.orm import Session as DBSession
|
|
|
|
from .db_models import (
|
|
LessonSessionDB, LessonPhaseEnum, TeacherSettingsDB,
|
|
)
|
|
from .models import (
|
|
LessonSession, LessonPhase, get_default_durations,
|
|
)
|
|
|
|
|
|
class SessionRepository:
|
|
"""Repository fuer LessonSession CRUD-Operationen."""
|
|
|
|
def __init__(self, db: DBSession):
|
|
self.db = db
|
|
|
|
# ==================== CREATE ====================
|
|
|
|
def create(self, session: LessonSession) -> LessonSessionDB:
|
|
"""
|
|
Erstellt eine neue Session in der Datenbank.
|
|
|
|
Args:
|
|
session: LessonSession Dataclass
|
|
|
|
Returns:
|
|
LessonSessionDB Model
|
|
"""
|
|
db_session = LessonSessionDB(
|
|
id=session.session_id,
|
|
teacher_id=session.teacher_id,
|
|
class_id=session.class_id,
|
|
subject=session.subject,
|
|
topic=session.topic,
|
|
current_phase=LessonPhaseEnum(session.current_phase.value),
|
|
is_paused=session.is_paused,
|
|
lesson_started_at=session.lesson_started_at,
|
|
lesson_ended_at=session.lesson_ended_at,
|
|
phase_started_at=session.phase_started_at,
|
|
pause_started_at=session.pause_started_at,
|
|
total_paused_seconds=session.total_paused_seconds,
|
|
phase_durations=session.phase_durations,
|
|
phase_history=session.phase_history,
|
|
notes=session.notes,
|
|
homework=session.homework,
|
|
)
|
|
self.db.add(db_session)
|
|
self.db.commit()
|
|
self.db.refresh(db_session)
|
|
return db_session
|
|
|
|
# ==================== READ ====================
|
|
|
|
def get_by_id(self, session_id: str) -> Optional[LessonSessionDB]:
|
|
"""Holt eine Session nach ID."""
|
|
return self.db.query(LessonSessionDB).filter(
|
|
LessonSessionDB.id == session_id
|
|
).first()
|
|
|
|
def get_active_by_teacher(self, teacher_id: str) -> List[LessonSessionDB]:
|
|
"""Holt alle aktiven Sessions eines Lehrers."""
|
|
return self.db.query(LessonSessionDB).filter(
|
|
LessonSessionDB.teacher_id == teacher_id,
|
|
LessonSessionDB.current_phase != LessonPhaseEnum.ENDED
|
|
).all()
|
|
|
|
def get_history_by_teacher(
|
|
self,
|
|
teacher_id: str,
|
|
limit: int = 20,
|
|
offset: int = 0
|
|
) -> List[LessonSessionDB]:
|
|
"""Holt Session-History eines Lehrers (Feature f17)."""
|
|
return self.db.query(LessonSessionDB).filter(
|
|
LessonSessionDB.teacher_id == teacher_id,
|
|
LessonSessionDB.current_phase == LessonPhaseEnum.ENDED
|
|
).order_by(
|
|
LessonSessionDB.lesson_ended_at.desc()
|
|
).offset(offset).limit(limit).all()
|
|
|
|
def get_by_class(
|
|
self,
|
|
class_id: str,
|
|
limit: int = 20
|
|
) -> List[LessonSessionDB]:
|
|
"""Holt Sessions einer Klasse."""
|
|
return self.db.query(LessonSessionDB).filter(
|
|
LessonSessionDB.class_id == class_id
|
|
).order_by(
|
|
LessonSessionDB.created_at.desc()
|
|
).limit(limit).all()
|
|
|
|
# ==================== UPDATE ====================
|
|
|
|
def update(self, session: LessonSession) -> Optional[LessonSessionDB]:
|
|
"""
|
|
Aktualisiert eine bestehende Session.
|
|
|
|
Args:
|
|
session: LessonSession Dataclass mit aktualisierten Werten
|
|
|
|
Returns:
|
|
Aktualisierte LessonSessionDB oder None
|
|
"""
|
|
db_session = self.get_by_id(session.session_id)
|
|
if not db_session:
|
|
return None
|
|
|
|
db_session.current_phase = LessonPhaseEnum(session.current_phase.value)
|
|
db_session.is_paused = session.is_paused
|
|
db_session.lesson_started_at = session.lesson_started_at
|
|
db_session.lesson_ended_at = session.lesson_ended_at
|
|
db_session.phase_started_at = session.phase_started_at
|
|
db_session.pause_started_at = session.pause_started_at
|
|
db_session.total_paused_seconds = session.total_paused_seconds
|
|
db_session.phase_durations = session.phase_durations
|
|
db_session.phase_history = session.phase_history
|
|
db_session.notes = session.notes
|
|
db_session.homework = session.homework
|
|
|
|
self.db.commit()
|
|
self.db.refresh(db_session)
|
|
return db_session
|
|
|
|
def update_notes(
|
|
self,
|
|
session_id: str,
|
|
notes: str,
|
|
homework: str
|
|
) -> Optional[LessonSessionDB]:
|
|
"""Aktualisiert nur Notizen und Hausaufgaben."""
|
|
db_session = self.get_by_id(session_id)
|
|
if not db_session:
|
|
return None
|
|
|
|
db_session.notes = notes
|
|
db_session.homework = homework
|
|
|
|
self.db.commit()
|
|
self.db.refresh(db_session)
|
|
return db_session
|
|
|
|
# ==================== DELETE ====================
|
|
|
|
def delete(self, session_id: str) -> bool:
|
|
"""Loescht eine Session."""
|
|
db_session = self.get_by_id(session_id)
|
|
if not db_session:
|
|
return False
|
|
|
|
self.db.delete(db_session)
|
|
self.db.commit()
|
|
return True
|
|
|
|
# ==================== CONVERSION ====================
|
|
|
|
def to_dataclass(self, db_session: LessonSessionDB) -> LessonSession:
|
|
"""
|
|
Konvertiert DB-Model zu Dataclass.
|
|
|
|
Args:
|
|
db_session: LessonSessionDB Model
|
|
|
|
Returns:
|
|
LessonSession Dataclass
|
|
"""
|
|
return LessonSession(
|
|
session_id=db_session.id,
|
|
teacher_id=db_session.teacher_id,
|
|
class_id=db_session.class_id,
|
|
subject=db_session.subject,
|
|
topic=db_session.topic,
|
|
current_phase=LessonPhase(db_session.current_phase.value),
|
|
phase_started_at=db_session.phase_started_at,
|
|
lesson_started_at=db_session.lesson_started_at,
|
|
lesson_ended_at=db_session.lesson_ended_at,
|
|
is_paused=db_session.is_paused,
|
|
pause_started_at=db_session.pause_started_at,
|
|
total_paused_seconds=db_session.total_paused_seconds or 0,
|
|
phase_durations=db_session.phase_durations or get_default_durations(),
|
|
phase_history=db_session.phase_history or [],
|
|
notes=db_session.notes or "",
|
|
homework=db_session.homework or "",
|
|
)
|
|
|
|
|
|
class TeacherSettingsRepository:
|
|
"""Repository fuer Lehrer-Einstellungen (Feature f16)."""
|
|
|
|
def __init__(self, db: DBSession):
|
|
self.db = db
|
|
|
|
def get_or_create(self, teacher_id: str) -> TeacherSettingsDB:
|
|
"""Holt oder erstellt Einstellungen fuer einen Lehrer."""
|
|
settings = self.db.query(TeacherSettingsDB).filter(
|
|
TeacherSettingsDB.teacher_id == teacher_id
|
|
).first()
|
|
|
|
if not settings:
|
|
settings = TeacherSettingsDB(
|
|
teacher_id=teacher_id,
|
|
default_phase_durations=get_default_durations(),
|
|
)
|
|
self.db.add(settings)
|
|
self.db.commit()
|
|
self.db.refresh(settings)
|
|
|
|
return settings
|
|
|
|
def update_phase_durations(
|
|
self,
|
|
teacher_id: str,
|
|
durations: Dict[str, int]
|
|
) -> TeacherSettingsDB:
|
|
"""Aktualisiert die Standard-Phasendauern."""
|
|
settings = self.get_or_create(teacher_id)
|
|
settings.default_phase_durations = durations
|
|
self.db.commit()
|
|
self.db.refresh(settings)
|
|
return settings
|
|
|
|
def update_preferences(
|
|
self,
|
|
teacher_id: str,
|
|
audio_enabled: Optional[bool] = None,
|
|
high_contrast: Optional[bool] = None,
|
|
show_statistics: Optional[bool] = None
|
|
) -> TeacherSettingsDB:
|
|
"""Aktualisiert UI-Praeferenzen."""
|
|
settings = self.get_or_create(teacher_id)
|
|
|
|
if audio_enabled is not None:
|
|
settings.audio_enabled = audio_enabled
|
|
if high_contrast is not None:
|
|
settings.high_contrast = high_contrast
|
|
if show_statistics is not None:
|
|
settings.show_statistics = show_statistics
|
|
|
|
self.db.commit()
|
|
self.db.refresh(settings)
|
|
return settings
|