""" Tool audit log endpoints — admin only. GET /api/audit/recent?user=scott&days=7&limit=200 Returns recent tool call entries for one user (or all users if user omitted). GET /api/audit/stats?user=scott&days=7 Returns aggregate counts by tool and status. """ import jwt from collections import Counter from fastapi import APIRouter, HTTPException, Query, Request from auth_utils import COOKIE_NAME, decode_token, get_user_role import tool_audit from persona import list_users router = APIRouter(prefix="/api/audit") def _require_admin(request: Request) -> str: token = request.cookies.get(COOKIE_NAME) if not token: raise HTTPException(status_code=401, detail="Not authenticated") try: username = decode_token(token) except jwt.InvalidTokenError: raise HTTPException(status_code=401, detail="Invalid session") if get_user_role(username) != "admin": raise HTTPException(status_code=403, detail="Admin access required") return username @router.get("/recent") async def audit_recent( request: Request, user: str = Query(None, description="Username to filter (omit for all users)"), days: int = Query(7, ge=1, le=90), limit: int = Query(200, ge=1, le=1000), ) -> dict: _require_admin(request) if user: if user not in list_users(): raise HTTPException(status_code=404, detail=f"User not found: {user}") entries = tool_audit.read_recent(user, days=days, limit=limit) else: entries = tool_audit.read_recent_all_users(days=days, limit=limit) return {"entries": entries, "count": len(entries), "days": days} @router.get("/stats") async def audit_stats( request: Request, user: str = Query(None), days: int = Query(7, ge=1, le=90), ) -> dict: _require_admin(request) if user: if user not in list_users(): raise HTTPException(status_code=404, detail=f"User not found: {user}") entries = tool_audit.read_recent(user, days=days, limit=10000) else: entries = tool_audit.read_recent_all_users(days=days, limit=10000) tool_counts: Counter = Counter() status_counts: Counter = Counter() user_counts: Counter = Counter() for e in entries: tool_counts[e.get("tool", "?")] += 1 status_counts[e.get("status", "?")] += 1 user_counts[e.get("user", "?")] += 1 return { "total": len(entries), "days": days, "by_tool": dict(tool_counts.most_common()), "by_status": dict(status_counts), "by_user": dict(user_counts.most_common()), }