initial commit
This commit is contained in:
70
backend/app/routers/users.py
Normal file
70
backend/app/routers/users.py
Normal file
@@ -0,0 +1,70 @@
|
||||
"""FluentGerman.ai — User management router (admin only)."""
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException, status
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.auth import hash_password, require_admin
|
||||
from app.database import get_db
|
||||
from app.models import User
|
||||
from app.schemas import UserCreate, UserOut, UserUpdate
|
||||
|
||||
router = APIRouter(prefix="/api/users", tags=["users"], dependencies=[Depends(require_admin)])
|
||||
|
||||
|
||||
@router.get("/", response_model=list[UserOut])
|
||||
async def list_users(db: AsyncSession = Depends(get_db)):
|
||||
result = await db.execute(select(User).where(User.is_admin == False).order_by(User.created_at.desc())) # noqa: E712
|
||||
return result.scalars().all()
|
||||
|
||||
|
||||
@router.post("/", response_model=UserOut, status_code=status.HTTP_201_CREATED)
|
||||
async def create_user(body: UserCreate, db: AsyncSession = Depends(get_db)):
|
||||
# Check uniqueness
|
||||
existing = await db.execute(
|
||||
select(User).where((User.username == body.username) | (User.email == body.email))
|
||||
)
|
||||
if existing.scalar_one_or_none():
|
||||
raise HTTPException(status_code=status.HTTP_409_CONFLICT, detail="Username or email already exists")
|
||||
|
||||
user = User(
|
||||
username=body.username,
|
||||
email=body.email,
|
||||
hashed_password=hash_password(body.password),
|
||||
)
|
||||
db.add(user)
|
||||
await db.commit()
|
||||
await db.refresh(user)
|
||||
return user
|
||||
|
||||
|
||||
@router.put("/{user_id}", response_model=UserOut)
|
||||
async def update_user(user_id: int, body: UserUpdate, db: AsyncSession = Depends(get_db)):
|
||||
result = await db.execute(select(User).where(User.id == user_id))
|
||||
user = result.scalar_one_or_none()
|
||||
if not user:
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="User not found")
|
||||
|
||||
if body.username is not None:
|
||||
user.username = body.username
|
||||
if body.email is not None:
|
||||
user.email = body.email
|
||||
if body.password is not None:
|
||||
user.hashed_password = hash_password(body.password)
|
||||
if body.is_active is not None:
|
||||
user.is_active = body.is_active
|
||||
|
||||
await db.commit()
|
||||
await db.refresh(user)
|
||||
return user
|
||||
|
||||
|
||||
@router.delete("/{user_id}", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def delete_user(user_id: int, db: AsyncSession = Depends(get_db)):
|
||||
result = await db.execute(select(User).where(User.id == user_id))
|
||||
user = result.scalar_one_or_none()
|
||||
if not user:
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="User not found")
|
||||
|
||||
await db.delete(user)
|
||||
await db.commit()
|
||||
Reference in New Issue
Block a user