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>
168 lines
5.7 KiB
Python
168 lines
5.7 KiB
Python
"""
|
|
Template Repository.
|
|
|
|
CRUD-Operationen fuer Stunden-Vorlagen (Feature f37).
|
|
"""
|
|
from typing import Optional, List
|
|
|
|
from sqlalchemy.orm import Session as DBSession
|
|
|
|
from .db_models import LessonTemplateDB
|
|
from .models import LessonTemplate, get_default_durations
|
|
|
|
|
|
class TemplateRepository:
|
|
"""Repository fuer Stunden-Vorlagen (Feature f37)."""
|
|
|
|
def __init__(self, db: DBSession):
|
|
self.db = db
|
|
|
|
# ==================== CREATE ====================
|
|
|
|
def create(self, template: LessonTemplate) -> LessonTemplateDB:
|
|
"""Erstellt eine neue Vorlage."""
|
|
db_template = LessonTemplateDB(
|
|
id=template.template_id,
|
|
teacher_id=template.teacher_id,
|
|
name=template.name,
|
|
description=template.description,
|
|
subject=template.subject,
|
|
grade_level=template.grade_level,
|
|
phase_durations=template.phase_durations,
|
|
default_topic=template.default_topic,
|
|
default_notes=template.default_notes,
|
|
is_public=template.is_public,
|
|
usage_count=template.usage_count,
|
|
)
|
|
self.db.add(db_template)
|
|
self.db.commit()
|
|
self.db.refresh(db_template)
|
|
return db_template
|
|
|
|
# ==================== READ ====================
|
|
|
|
def get_by_id(self, template_id: str) -> Optional[LessonTemplateDB]:
|
|
"""Holt eine Vorlage nach ID."""
|
|
return self.db.query(LessonTemplateDB).filter(
|
|
LessonTemplateDB.id == template_id
|
|
).first()
|
|
|
|
def get_by_teacher(
|
|
self,
|
|
teacher_id: str,
|
|
include_public: bool = True
|
|
) -> List[LessonTemplateDB]:
|
|
"""
|
|
Holt alle Vorlagen eines Lehrers.
|
|
|
|
Args:
|
|
teacher_id: ID des Lehrers
|
|
include_public: Auch oeffentliche Vorlagen anderer Lehrer einbeziehen
|
|
"""
|
|
if include_public:
|
|
return self.db.query(LessonTemplateDB).filter(
|
|
(LessonTemplateDB.teacher_id == teacher_id) |
|
|
(LessonTemplateDB.is_public == True)
|
|
).order_by(
|
|
LessonTemplateDB.usage_count.desc()
|
|
).all()
|
|
else:
|
|
return self.db.query(LessonTemplateDB).filter(
|
|
LessonTemplateDB.teacher_id == teacher_id
|
|
).order_by(
|
|
LessonTemplateDB.created_at.desc()
|
|
).all()
|
|
|
|
def get_public_templates(self, limit: int = 20) -> List[LessonTemplateDB]:
|
|
"""Holt oeffentliche Vorlagen, sortiert nach Beliebtheit."""
|
|
return self.db.query(LessonTemplateDB).filter(
|
|
LessonTemplateDB.is_public == True
|
|
).order_by(
|
|
LessonTemplateDB.usage_count.desc()
|
|
).limit(limit).all()
|
|
|
|
def get_by_subject(
|
|
self,
|
|
subject: str,
|
|
teacher_id: Optional[str] = None
|
|
) -> List[LessonTemplateDB]:
|
|
"""Holt Vorlagen fuer ein bestimmtes Fach."""
|
|
query = self.db.query(LessonTemplateDB).filter(
|
|
LessonTemplateDB.subject == subject
|
|
)
|
|
if teacher_id:
|
|
query = query.filter(
|
|
(LessonTemplateDB.teacher_id == teacher_id) |
|
|
(LessonTemplateDB.is_public == True)
|
|
)
|
|
else:
|
|
query = query.filter(LessonTemplateDB.is_public == True)
|
|
|
|
return query.order_by(
|
|
LessonTemplateDB.usage_count.desc()
|
|
).all()
|
|
|
|
# ==================== UPDATE ====================
|
|
|
|
def update(self, template: LessonTemplate) -> Optional[LessonTemplateDB]:
|
|
"""Aktualisiert eine Vorlage."""
|
|
db_template = self.get_by_id(template.template_id)
|
|
if not db_template:
|
|
return None
|
|
|
|
db_template.name = template.name
|
|
db_template.description = template.description
|
|
db_template.subject = template.subject
|
|
db_template.grade_level = template.grade_level
|
|
db_template.phase_durations = template.phase_durations
|
|
db_template.default_topic = template.default_topic
|
|
db_template.default_notes = template.default_notes
|
|
db_template.is_public = template.is_public
|
|
|
|
self.db.commit()
|
|
self.db.refresh(db_template)
|
|
return db_template
|
|
|
|
def increment_usage(self, template_id: str) -> Optional[LessonTemplateDB]:
|
|
"""Erhoeht den Usage-Counter einer Vorlage."""
|
|
db_template = self.get_by_id(template_id)
|
|
if not db_template:
|
|
return None
|
|
|
|
db_template.usage_count += 1
|
|
self.db.commit()
|
|
self.db.refresh(db_template)
|
|
return db_template
|
|
|
|
# ==================== DELETE ====================
|
|
|
|
def delete(self, template_id: str) -> bool:
|
|
"""Loescht eine Vorlage."""
|
|
db_template = self.get_by_id(template_id)
|
|
if not db_template:
|
|
return False
|
|
|
|
self.db.delete(db_template)
|
|
self.db.commit()
|
|
return True
|
|
|
|
# ==================== CONVERSION ====================
|
|
|
|
def to_dataclass(self, db_template: LessonTemplateDB) -> LessonTemplate:
|
|
"""Konvertiert DB-Model zu Dataclass."""
|
|
return LessonTemplate(
|
|
template_id=db_template.id,
|
|
teacher_id=db_template.teacher_id,
|
|
name=db_template.name,
|
|
description=db_template.description or "",
|
|
subject=db_template.subject or "",
|
|
grade_level=db_template.grade_level or "",
|
|
phase_durations=db_template.phase_durations or get_default_durations(),
|
|
default_topic=db_template.default_topic or "",
|
|
default_notes=db_template.default_notes or "",
|
|
is_public=db_template.is_public,
|
|
usage_count=db_template.usage_count,
|
|
created_at=db_template.created_at,
|
|
updated_at=db_template.updated_at,
|
|
)
|