"""Admin analytics: aggregate trainee results.""" from __future__ import annotations from flask import Blueprint, jsonify from .helpers import ApiError, current_user, require_auth, require_roles analytics_bp = Blueprint("analytics", __name__) def _stores(): from flask import current_app return { "sessions": current_app.extensions["session_store"], "groups": current_app.extensions["group_store"], "users": current_app.extensions["user_store"], } @analytics_bp.get("") @require_auth @require_roles("admin") def analytics(): s = _stores() actor = current_user() if actor.get("role") == "super_admin": sessions = s["sessions"].sessions.all() users = s["users"].list_users() else: org_id = actor.get("org_id") # users in this org users = s["users"].list_users(org_id=org_id) user_ids = {u["id"] for u in users} sessions = [ x for x in s["sessions"].sessions.all() if x.get("user_id") in user_ids ] overall = { "total_sessions": len(sessions), "wins": sum(1 for x in sessions if x.get("outcome") == "won"), "losses": sum(1 for x in sessions if x.get("outcome") == "lost"), } overall["close_rate"] = round( overall["wins"] / overall["total_sessions"] * 100, 1 ) if overall["total_sessions"] else 0 # average score scores = [ (x.get("debrief") or {}).get("score", 0) for x in sessions if x.get("outcome") ] overall["avg_score"] = round(sum(scores) / len(scores), 1) if scores else 0 # hardest personas = personas with most losses (lowest avg score) by_persona: dict = {} for x in sessions: key = (x.get("group_id"), x.get("persona_id"), x.get("persona_name", "?")) if key not in by_persona: by_persona[key] = {"plays": 0, "losses": 0, "wins": 0, "scores": []} rec = by_persona[key] rec["plays"] += 1 rec["scores"].append((x.get("debrief") or {}).get("score", 0)) if x.get("outcome") == "won": rec["wins"] += 1 elif x.get("outcome") == "lost": rec["losses"] += 1 hardest = sorted( ( { "persona_name": k[2], "plays": v["plays"], "wins": v["wins"], "losses": v["losses"], "avg_score": round(sum(v["scores"]) / len(v["scores"]), 1) if v["scores"] else 0, } for k, v in by_persona.items() ), key=lambda r: (r["losses"], -r["avg_score"]), )[:10] return jsonify({ "overall": overall, "trainee_count": len(users), "hardest_personas": hardest, })