from datetime import datetime from typing import List from sqlalchemy.orm import Session from app.models import Module, ModuleProgress, ProgressStatus def ensure_module_progress(db: Session, user_id: int, course_id: int) -> List[ModuleProgress]: modules = db.query(Module).filter(Module.course_id == course_id).order_by(Module.order_index).all() progress_list: List[ModuleProgress] = [] for module in modules: progress = ( db.query(ModuleProgress) .filter(ModuleProgress.user_id == user_id, ModuleProgress.module_id == module.id) .first() ) if not progress: progress = ModuleProgress(user_id=user_id, module_id=module.id, status=ProgressStatus.locked) db.add(progress) db.flush() progress_list.append(progress) db.commit() return progress_list def recompute_progress(db: Session, user_id: int, course_id: int) -> None: modules = db.query(Module).filter(Module.course_id == course_id).order_by(Module.order_index).all() progresses = { p.module_id: p for p in db.query(ModuleProgress).filter(ModuleProgress.user_id == user_id).all() } last_completed_index = -1 for idx, module in enumerate(modules): progress = progresses.get(module.id) if not progress: progress = ModuleProgress(user_id=user_id, module_id=module.id, status=ProgressStatus.locked) db.add(progress) progresses[module.id] = progress if progress.status == ProgressStatus.completed: last_completed_index = idx for idx, module in enumerate(modules): progress = progresses[module.id] if progress.status == ProgressStatus.completed: continue if idx == last_completed_index + 1: progress.status = ProgressStatus.unlocked else: progress.status = ProgressStatus.locked db.commit() def complete_content_module(db: Session, user_id: int, module: Module) -> ModuleProgress: progress = ( db.query(ModuleProgress) .filter(ModuleProgress.user_id == user_id, ModuleProgress.module_id == module.id) .first() ) if not progress: progress = ModuleProgress(user_id=user_id, module_id=module.id, status=ProgressStatus.unlocked) db.add(progress) progress.status = ProgressStatus.completed progress.completed_at = datetime.utcnow() db.commit() return progress