""" Evaluation Endpoints - Training Type Profiles Endpoints for activity evaluation and re-evaluation. Issue: #15 Date: 2026-03-23 """ import logging from typing import Optional from fastapi import APIRouter, HTTPException, Depends from db import get_db, get_cursor, r2d from auth import require_auth, require_admin from evaluation_helper import ( evaluate_and_save_activity, batch_evaluate_activities, load_parameters_registry ) router = APIRouter(prefix="/api/evaluation", tags=["evaluation"]) logger = logging.getLogger(__name__) @router.get("/parameters") def list_parameters(session: dict = Depends(require_auth)): """ List all available training parameters. """ with get_db() as conn: cur = get_cursor(conn) parameters = load_parameters_registry(cur) return { "parameters": list(parameters.values()), "count": len(parameters) } @router.post("/activity/{activity_id}") def evaluate_activity( activity_id: str, session: dict = Depends(require_auth) ): """ Evaluates or re-evaluates a single activity. Returns the evaluation result. """ profile_id = session['profile_id'] with get_db() as conn: cur = get_cursor(conn) # Load activity cur.execute(""" SELECT id, profile_id, date, training_type_id, duration_min, hr_avg, hr_max, distance_km, kcal_active, kcal_resting, rpe, pace_min_per_km, cadence, elevation_gain FROM activity_log WHERE id = %s AND profile_id = %s """, (activity_id, profile_id)) activity = cur.fetchone() if not activity: raise HTTPException(404, "Activity not found") activity_dict = dict(activity) # Evaluate result = evaluate_and_save_activity( cur, activity_dict["id"], activity_dict, activity_dict["training_type_id"], profile_id ) if not result: return { "message": "No profile configured for this training type", "evaluation": None } return { "message": "Activity evaluated", "evaluation": result } @router.post("/batch") def batch_evaluate( limit: Optional[int] = None, session: dict = Depends(require_auth) ): """ Re-evaluates all activities for the current user. Optional limit parameter for testing. """ profile_id = session['profile_id'] with get_db() as conn: cur = get_cursor(conn) stats = batch_evaluate_activities(cur, profile_id, limit) return { "message": "Batch evaluation completed", "stats": stats } @router.post("/batch/all") def batch_evaluate_all(session: dict = Depends(require_admin)): """ Admin-only: Re-evaluates all activities for all users. Use with caution on large databases! """ with get_db() as conn: cur = get_cursor(conn) # Get all profiles cur.execute("SELECT id FROM profiles") profiles = cur.fetchall() total_stats = { "profiles": len(profiles), "total": 0, "evaluated": 0, "skipped": 0, "errors": 0 } for profile in profiles: profile_id = profile['id'] stats = batch_evaluate_activities(cur, profile_id) total_stats["total"] += stats["total"] total_stats["evaluated"] += stats["evaluated"] total_stats["skipped"] += stats["skipped"] total_stats["errors"] += stats["errors"] return { "message": "Batch evaluation for all users completed", "stats": total_stats }