from typing import Any from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy.orm import Session from app.api.deps import get_current_user from app.core.logging import app_logger from app.crud.crud_user import create_user, delete_user, get_user, get_user_by_email, update_user from app.db.session import get_db from app.models.user import User from app.schemas.user import User as UserSchema from app.schemas.user import UserCreate, UserUpdate from app.utils.activity import log_activity router = APIRouter() @router.post("/", response_model=UserSchema, status_code=status.HTTP_201_CREATED) def create_user_route( *, db: Session = Depends(get_db), user_in: UserCreate, ) -> Any: """ Create new user """ user = get_user_by_email(db, email=user_in.email) if user: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="A user with this email already exists", ) user = create_user(db, obj_in=user_in) app_logger.info(f"New user created: {user.email}") return user @router.get("/me", response_model=UserSchema) def read_user_me( current_user: User = Depends(get_current_user), ) -> Any: """ Get current user information """ return current_user @router.put("/me", response_model=UserSchema) def update_user_me( *, db: Session = Depends(get_db), user_in: UserUpdate, current_user: User = Depends(get_current_user), ) -> Any: """ Update current user information """ user = update_user(db, db_obj=current_user, obj_in=user_in) # Log activity log_activity( db=db, user_id=current_user.id, action="update", entity_type="user", entity_id=current_user.id, details="User updated their profile" ) app_logger.info(f"User updated their profile: {user.email}") return user @router.get("/{user_id}", response_model=UserSchema) def read_user_by_id( user_id: int, current_user: User = Depends(get_current_user), db: Session = Depends(get_db), ) -> Any: """ Get a specific user by id - only the same user can access this """ user = get_user(db, user_id=user_id) if not user: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="User not found" ) # Only allow users to access their own information if user.id != current_user.id: raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="Not enough permissions to access this user" ) return user @router.delete("/{user_id}", response_model=None, status_code=status.HTTP_204_NO_CONTENT) def delete_user_by_id( user_id: int, db: Session = Depends(get_db), current_user: User = Depends(get_current_user), ) -> Any: """ Delete a user by id - only the same user can delete their account """ user = get_user(db, user_id=user_id) if not user: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="User not found" ) # Only allow users to delete their own account if user.id != current_user.id: raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="Not enough permissions to delete this user" ) user = delete_user(db, user_id=user_id) app_logger.info(f"User deleted their account: {user.email}") return None