from typing import List, Optional from sqlalchemy.orm import Session from datetime import datetime from app.crud.base import CRUDBase from app.models.exam_result import ExamResult from app.schemas.exam_result import ExamResultCreate, ExamResultUpdate class CRUDExamResult(CRUDBase[ExamResult, ExamResultCreate, ExamResultUpdate]): def get_by_student(self, db: Session, *, student_id: int) -> List[ExamResult]: """Get all exam results for a specific student""" return db.query(self.model).filter(ExamResult.student_id == student_id).all() def get_by_exam(self, db: Session, *, exam_id: int) -> List[ExamResult]: """Get all exam results for a specific exam""" return db.query(self.model).filter(ExamResult.exam_id == exam_id).all() def get_by_student_and_exam( self, db: Session, *, student_id: int, exam_id: int ) -> Optional[ExamResult]: """Get a student's result for a specific exam""" return ( db.query(self.model) .filter( ExamResult.student_id == student_id, ExamResult.exam_id == exam_id ) .first() ) def get_active_exam_attempt( self, db: Session, *, student_id: int, exam_id: int ) -> Optional[ExamResult]: """Get a student's active (incomplete) attempt for an exam""" return ( db.query(self.model) .filter( ExamResult.student_id == student_id, ExamResult.exam_id == exam_id, ~ExamResult.is_completed ) .first() ) def complete_exam( self, db: Session, *, db_obj: ExamResult, score: float, max_score: float ) -> ExamResult: """Mark an exam as completed with the final score""" db_obj.score = score db_obj.max_score = max_score db_obj.completed_at = datetime.utcnow() db_obj.is_completed = True db.add(db_obj) db.commit() db.refresh(db_obj) return db_obj exam_result = CRUDExamResult(ExamResult)