from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession from app.core.security import hash_password from app.database import get_db from app.deps import get_current_admin from app.models.user import User from app.schemas.user import UserAdminCreate, UserAdminOut router = APIRouter() @router.get("/users", response_model=list[UserAdminOut]) async def list_users( _admin: User = Depends(get_current_admin), db: AsyncSession = Depends(get_db), ) -> list[User]: result = await db.execute(select(User).order_by(User.email)) return list(result.scalars().all()) @router.post("/users", response_model=UserAdminOut, status_code=status.HTTP_201_CREATED) async def create_user( body: UserAdminCreate, _admin: User = Depends(get_current_admin), db: AsyncSession = Depends(get_db), ) -> User: existing = await db.execute(select(User).where(User.email == body.email)) if existing.scalar_one_or_none(): raise HTTPException(status_code=400, detail="Email already registered") user = User( email=body.email, hashed_password=hash_password(body.password), full_name=body.full_name, is_superuser=body.is_admin, ) db.add(user) await db.commit() await db.refresh(user) return user @router.delete("/users/{user_id}", status_code=status.HTTP_204_NO_CONTENT) async def delete_user( user_id: str, admin: User = Depends(get_current_admin), db: AsyncSession = Depends(get_db), ) -> None: if user_id == admin.id: raise HTTPException(status_code=400, detail="Cannot delete your own account") result = await db.execute(select(User).where(User.id == user_id)) user = result.scalar_one_or_none() if not user: raise HTTPException(status_code=404, detail="User not found") await db.delete(user) await db.commit() @router.patch("/users/{user_id}/active", response_model=UserAdminOut) async def toggle_active( user_id: str, admin: User = Depends(get_current_admin), db: AsyncSession = Depends(get_db), ) -> User: if user_id == admin.id: raise HTTPException(status_code=400, detail="Cannot change your own active status") result = await db.execute(select(User).where(User.id == user_id)) user = result.scalar_one_or_none() if not user: raise HTTPException(status_code=404, detail="User not found") user.is_active = not user.is_active await db.commit() await db.refresh(user) return user