""" quiXzoom Academy API endpoints for LandveX Admin """ from fastapi import APIRouter, Depends, HTTPException, status from pydantic import BaseModel from typing import List, Optional from datetime import datetime from app.core.security import get_current_user from app.models.user import User router = APIRouter(prefix="/academy", tags=["academy"]) # Models class LessonCompleteRequest(BaseModel): lesson_id: str module_id: str score: Optional[int] = None class ProgressResponse(BaseModel): user_id: str completed_lessons: List[str] current_module: int total_progress: float certificate_earned: bool certificate_date: Optional[str] = None class CertificateResponse(BaseModel): pdf_url: str verification_code: str issue_date: str # In-memory storage (replace with DB in production) academy_progress = {} LESSONS_PER_MODULE = { "module1": 4, "module2": 4, "module3": 3, "module4": 3, "module5": 3, "module6": 4 } TOTAL_LESSONS = sum(LESSONS_PER_MODULE.values()) @router.get("/progress", response_model=ProgressResponse) async def get_progress(current_user: User = Depends(get_current_user)): """Get user's academy progress""" user_id = str(current_user.id) progress = academy_progress.get(user_id, { "completed_lessons": [], "current_module": 1 }) completed = len(progress["completed_lessons"]) total_progress = (completed / TOTAL_LESSONS) * 100 certificate_earned = completed >= TOTAL_LESSONS return ProgressResponse( user_id=user_id, completed_lessons=progress["completed_lessons"], current_module=progress["current_module"], total_progress=round(total_progress, 1), certificate_earned=certificate_earned, certificate_date=datetime.utcnow().isoformat() if certificate_earned else None ) @router.post("/complete", status_code=status.HTTP_200_OK) async def complete_lesson( request: LessonCompleteRequest, current_user: User = Depends(get_current_user) ): """Mark a lesson as completed""" user_id = str(current_user.id) if user_id not in academy_progress: academy_progress[user_id] = { "completed_lessons": [], "current_module": 1 } progress = academy_progress[user_id] if request.lesson_id not in progress["completed_lessons"]: progress["completed_lessons"].append(request.lesson_id) # Update current module module_num = int(request.module_id.replace("module", "")) module_lessons = [f"m{module_num}l{i}" for i in range(1, LESSONS_PER_MODULE[request.module_id] + 1)] if all(l in progress["completed_lessons"] for l in module_lessons): progress["current_module"] = min(module_num + 1, 6) return { "success": True, "lesson_id": request.lesson_id, "progress": len(progress["completed_lessons"]) / TOTAL_LESSONS * 100 } @router.get("/certificate", response_model=CertificateResponse) async def get_certificate(current_user: User = Depends(get_current_user)): """Generate certificate PDF""" user_id = str(current_user.id) progress = academy_progress.get(user_id, {"completed_lessons": []}) if len(progress["completed_lessons"]) < TOTAL_LESSONS: raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="Certificate not yet earned. Complete all lessons first." ) # Generate verification code verification = f"QX-{user_id[:8].upper()}-{datetime.utcnow().strftime('%Y%m%d')}" return CertificateResponse( pdf_url=f"/api/academy/certificate/{user_id}/download", verification_code=verification, issue_date=datetime.utcnow().isoformat() ) @router.get("/stats") async def get_academy_stats(current_user: User = Depends(get_current_user)): """Get academy statistics (admin only)""" if not current_user.is_admin: raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="Admin access required" ) total_users = len(academy_progress) completed_users = sum( 1 for p in academy_progress.values() if len(p["completed_lessons"]) >= TOTAL_LESSONS ) return { "total_enrolled": total_users, "completed_all": completed_users, "completion_rate": round(completed_users / total_users * 100, 1) if total_users > 0 else 0, "average_progress": round( sum(len(p["completed_lessons"]) for p in academy_progress.values()) / total_users / TOTAL_LESSONS * 100, 1 ) if total_users > 0 else 0 }