""" worker.py — PragatiVeer Celery Background Tasks Active Tasks: - generate_daily_study_plans: Runs daily at 5:00 AM IST via Celery Beat Deferred (Phase 2 — AI LLM): - process_pdf_test: Automated PDF → LLM → Questions pipeline """ import os from datetime import datetime from celery import Celery from celery.schedules import crontab from sqlmodel import Session, select from database import engine import models REDIS_URL = os.getenv("REDIS_URL", "redis://redis:6379/0") # Initialize Celery connected to our Redis broker celery_app = Celery( "pragativeer_tasks", broker=REDIS_URL, backend=REDIS_URL ) # Configure timezone to IST for accurate 5:00 AM scheduling celery_app.conf.update( timezone='Asia/Kolkata', enable_utc=True, ) @celery_app.task(name="generate_daily_study_plans", bind=True, default_retry_delay=60, max_retries=3) def generate_daily_study_plans(self): """ Runs daily to evaluate students' weak areas and generate a personalized study plan for the day. """ try: with Session(engine) as session: # Fetch all active users on the AI Coach tier ai_students = session.exec( select(models.User).where(models.User.tier == models.TierEnum.AI_COACH) ).all() today = datetime.utcnow().date() plans_created = 0 for student in ai_students: # 1. Fetch pending spaced repetition mistakes for today pending_mistakes = session.exec( select(models.Mistake) .where(models.Mistake.user_id == student.id) .where(models.Mistake.is_mastered == False) .where(models.Mistake.next_review <= datetime.utcnow()) ).all() # 2. Extract weak topics (for revision recommendation) topics = [m.topic for m in pending_mistakes] most_weak_topic = max(set(topics), key=topics.count) if topics else "Mixed Syllabus" # 3. Construct the time-budgeted dynamic task list tasks = [ {"type": "Revision", "description": f"Revise {most_weak_topic}", "duration_minutes": 15, "status": "Pending"}, {"type": "Mistake_Review", "description": "Daily Mistake Review Session", "duration_minutes": 10, "status": "Pending"}, {"type": "DPS", "description": f"Attempt {most_weak_topic} Practice Sheet", "duration_minutes": 20, "status": "Pending"} ] # 4. Save to Database new_plan = models.StudyPlan( user_id=student.id, date=today, tasks=tasks, is_completed=False ) session.add(new_plan) plans_created += 1 session.commit() return f"Successfully generated {plans_created} daily study plans." except Exception as exc: print(f"Database error during study plan generation: {exc}") raise self.retry(exc=exc) # Schedule: 5:00 AM IST every day celery_app.conf.beat_schedule = { 'generate-study-plans-every-morning': { 'task': 'generate_daily_study_plans', 'schedule': crontab(hour=5, minute=0), }, }