"""Leaderboard stats: compare all users on overtime precision and directive compliance.""" from models import list_users from stats import compute_all_stats, _compliance_over, _day_compliant from calcul import minutes_to_hhmm def compute_classement() -> list[dict]: """Return ranked list of users with their key metrics.""" results = [] for user_id in list_users(): s = compute_all_stats(user_id) if not s["weekly_balances"] and s["n_jours"] == 0: continue # skip empty accounts balances = [b["delta_min"] for b in s["weekly_balances"]] # Precision: % of weeks where |solde| ≤ 30 min (≈ at zero) if balances: pct_zero = round(100 * sum(1 for b in balances if abs(b) <= 30) / len(balances)) mean_abs = round(sum(abs(b) for b in balances) / len(balances)) else: pct_zero = None mean_abs = None conf_pct = s["comp_globale"]["pct"] # Combined score (SSO era: will weight per role/contract) score = round( (pct_zero or 0) * 0.6 + (conf_pct or 0) * 0.4 ) results.append({ "user_id": user_id, "display_name": user_id.replace("_", " ").replace("-", " ").title(), "n_semaines": len(balances), "n_jours": s["n_jours"], "pct_zero": pct_zero, # % weeks ≈ 0 HS — higher = better "mean_abs_min": mean_abs, # mean abs(solde) in minutes — lower = better "mean_abs_str": minutes_to_hhmm(mean_abs) if mean_abs is not None else "—", "conf_pct": conf_pct, # directive compliance % — higher = better "score": score, # combined 0-100 — higher = better "avg_delta": s["avg_delta"], "avg_delta_min": s["avg_delta_min"], }) results.sort(key=lambda r: -r["score"]) return results