from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy.orm import Session from typing import List, Optional from backend.database import get_db from backend.models import User, UserRole from backend.schemas import UserOut, UserCreate, UserUpdate from backend.routers.auth import get_current_user, get_admin_user router = APIRouter(prefix="/api/users", tags=["users"]) @router.get("", response_model=List[UserOut]) def get_all_users(db: Session = Depends(get_db), current_user: User = Depends(get_current_user)): return db.query(User).order_by(User.id.asc()).all() @router.post("", response_model=UserOut) def create_user(user_in: UserCreate, db: Session = Depends(get_db), admin: User = Depends(get_admin_user)): existing = db.query(User).filter(User.email == user_in.email).first() if existing: raise HTTPException(status_code=400, detail="User with this email already exists") avatar = user_in.avatar_url or f"https://api.dicebear.com/7.x/bottts/svg?seed={user_in.email}" new_user = User( email=user_in.email, name=user_in.name, google_id=user_in.google_id, avatar_url=avatar, role=user_in.role, weekly_star_quota=user_in.weekly_star_quota ) db.add(new_user) db.commit() db.refresh(new_user) return new_user @router.get("/{user_id}", response_model=UserOut) def get_user_by_id(user_id: int, db: Session = Depends(get_db), current_user: User = Depends(get_current_user)): user = db.query(User).filter(User.id == user_id).first() if not user: raise HTTPException(status_code=404, detail="User not found") return user @router.patch("/{user_id}", response_model=UserOut) def update_user(user_id: int, user_in: UserUpdate, db: Session = Depends(get_db), current_user: User = Depends(get_current_user)): # Regular users can only update their own avatar and name. Admins can update role, quota, active status. if current_user.role != UserRole.ADMIN.value and current_user.id != user_id: raise HTTPException(status_code=403, detail="Cannot edit another user's account") user = db.query(User).filter(User.id == user_id).first() if not user: raise HTTPException(status_code=404, detail="User not found") if user_in.name is not None: user.name = user_in.name if user_in.avatar_url is not None: user.avatar_url = user_in.avatar_url # Admin-only fields if current_user.role == UserRole.ADMIN.value: if user_in.role is not None: user.role = user_in.role if user_in.weekly_star_quota is not None: user.weekly_star_quota = user_in.weekly_star_quota if user_in.is_active is not None: user.is_active = user_in.is_active db.commit() db.refresh(user) return user @router.delete("/{user_id}") def delete_user(user_id: int, db: Session = Depends(get_db), admin: User = Depends(get_admin_user)): if admin.id == user_id: raise HTTPException(status_code=400, detail="Cannot delete your own admin account") user = db.query(User).filter(User.id == user_id).first() if not user: raise HTTPException(status_code=404, detail="User not found") db.delete(user) db.commit() return {"message": "User deleted successfully", "id": user_id}