"""Admin user management API routes.""" from __future__ import annotations from fastapi import APIRouter, Query from core.db import conn router = APIRouter() @router.get("") def list_users( limit: int = Query(50, le=200), offset: int = Query(0, ge=0), ): """List all users with favorite/review counts.""" sql = """ SELECT u.id, u.email, u.nickname, u.avatar_url, u.provider, u.created_at, NVL(fav.cnt, 0) AS favorite_count, NVL(rev.cnt, 0) AS review_count FROM tasteby_users u LEFT JOIN ( SELECT user_id, COUNT(*) AS cnt FROM user_favorites GROUP BY user_id ) fav ON fav.user_id = u.id LEFT JOIN ( SELECT user_id, COUNT(*) AS cnt FROM user_reviews GROUP BY user_id ) rev ON rev.user_id = u.id ORDER BY u.created_at DESC OFFSET :off ROWS FETCH NEXT :lim ROWS ONLY """ count_sql = "SELECT COUNT(*) FROM tasteby_users" with conn() as c: cur = c.cursor() cur.execute(count_sql) total = cur.fetchone()[0] cur.execute(sql, {"off": offset, "lim": limit}) cols = [d[0].lower() for d in cur.description] rows = [dict(zip(cols, row)) for row in cur.fetchall()] for r in rows: if r.get("created_at"): r["created_at"] = r["created_at"].isoformat() return {"users": rows, "total": total} @router.get("/{user_id}/favorites") def get_user_favorites(user_id: str): """Get a user's favorite restaurants.""" sql = """ SELECT r.id, r.name, r.address, r.region, r.cuisine_type, r.rating, r.business_status, f.created_at FROM user_favorites f JOIN restaurants r ON r.id = f.restaurant_id WHERE f.user_id = :u ORDER BY f.created_at DESC """ with conn() as c: cur = c.cursor() cur.execute(sql, {"u": user_id}) cols = [d[0].lower() for d in cur.description] rows = [dict(zip(cols, row)) for row in cur.fetchall()] for r in rows: if r.get("created_at"): r["created_at"] = r["created_at"].isoformat() return rows @router.get("/{user_id}/reviews") def get_user_reviews(user_id: str): """Get a user's reviews with restaurant names.""" sql = """ SELECT r.id, r.restaurant_id, r.rating, r.review_text, r.visited_at, r.created_at, rest.name AS restaurant_name FROM user_reviews r LEFT JOIN restaurants rest ON rest.id = r.restaurant_id WHERE r.user_id = :u ORDER BY r.created_at DESC """ with conn() as c: cur = c.cursor() cur.execute(sql, {"u": user_id}) cols = [d[0].lower() for d in cur.description] rows = [dict(zip(cols, row)) for row in cur.fetchall()] for r in rows: # Handle CLOB if hasattr(r.get("review_text"), "read"): r["review_text"] = r["review_text"].read() if r.get("visited_at"): r["visited_at"] = r["visited_at"].isoformat() if r.get("created_at"): r["created_at"] = r["created_at"].isoformat() return rows