diff --git a/backend/src/backend/routers/rooms.py b/backend/src/backend/routers/rooms.py new file mode 100644 index 00000000..f7fa0e4d --- /dev/null +++ b/backend/src/backend/routers/rooms.py @@ -0,0 +1,163 @@ +"""Routes for room-related operations in the backend.""" + +import logging +from typing import List + +from fastapi import APIRouter +from fastapi import HTTPException +from fastapi import status +from sqlalchemy.exc import NoResultFound +from sqlalchemy.exc import SQLAlchemyError + +from backend.dependencies.db import DBSession +from backend.models import Room +from backend.schemas.rooms import RoomCreate +from backend.schemas.rooms import RoomResponse +from backend.schemas.rooms import RoomUpdate +from backend.services.rooms import delete_room +from backend.services.rooms import get_room +from backend.services.rooms import get_rooms +from backend.services.rooms import new_room +from backend.services.rooms import update_room + + +logger = logging.getLogger(__name__) + +router = APIRouter(prefix="/rooms", tags=["rooms"]) + + +@router.get("/", response_model=List[RoomResponse]) +async def read_rooms(session: DBSession): + """Endpoint to retrieve all rooms.""" + logger.debug("Received request to fetch all rooms") + try: + rooms = await get_rooms(session) + logger.info(f"Successfully retrieved {len(rooms)} rooms") + return rooms + except SQLAlchemyError as e: + logger.error(f"Database error while fetching rooms: {str(e)}") + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail="Database error occurred", + ) from e + except Exception as e: + logger.error(f"Unexpected error while fetching rooms: {str(e)}") + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail="An unexpected error occurred", + ) from e + + +@router.get("/{room_id}", response_model=RoomResponse) +async def read_room(room_id: int, session: DBSession): + """Endpoint to retrieve a room by ID.""" + logger.debug(f"Received request to fetch room with id: {room_id}") + try: + room = await get_room(session, room_id) + logger.info(f"Successfully retrieved room with id: {room_id}") + return room + except NoResultFound as e: + logger.warning(f"Room with id {room_id} not found") + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail=f"Room with id {room_id} not found", + ) from e + except SQLAlchemyError as e: + logger.error(f"Database error while fetching room with id {room_id}: {str(e)}") + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail="Database error occurred", + ) from e + except Exception as e: + logger.error( + f"Unexpected error while fetching room with id {room_id}: {str(e)}" + ) + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail="An unexpected error occurred", + ) from e + + +@router.post("/", response_model=RoomResponse, status_code=status.HTTP_201_CREATED) +async def create_room(room: RoomCreate, session: DBSession): + """Endpoint to create a new room.""" + logger.debug("Received request to create a new room") + try: + db_room = Room(**room.model_dump()) + created_room = await new_room(session, db_room) + logger.info(f"Successfully created room with id: {created_room.id}") + return created_room + except SQLAlchemyError as e: + logger.error(f"Database error while creating room: {str(e)}") + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, detail="Database error occurred" + ) from e + except Exception as e: + logger.error(f"Unexpected error while creating room: {str(e)}") + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail="An unexpected error occurred", + ) from e + + +@router.put("/{room_id}", response_model=RoomResponse) +async def update_existing_room( + room_id: int, room_update: RoomUpdate, session: DBSession +): + """Endpoint to update an existing room.""" + logger.debug(f"Received request to update room with id: {room_id}") + try: + room_params = { + k: v for k, v in room_update.model_dump(exclude_unset=True).items() + } + updated_room = await update_room(session, room_id, **room_params) + logger.info(f"Successfully updated room with id: {room_id}") + return updated_room + except NoResultFound as e: + logger.warning(f"Room with id {room_id} not found") + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail=f"Room with id {room_id} not found", + ) from e + except SQLAlchemyError as e: + logger.error(f"Database error while updating room with id {room_id}: {str(e)}") + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, detail="Database error occurred" + ) from e + except Exception as e: + logger.error( + f"Unexpected error while updating room with id {room_id}: {str(e)}" + ) + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail="An unexpected error occurred", + ) from e + + +@router.delete("/{room_id}", status_code=status.HTTP_204_NO_CONTENT) +async def delete_existing_room(room_id: int, session: DBSession): + """Endpoint to delete a room.""" + logger.debug(f"Received request to delete room with id: {room_id}") + try: + await delete_room(session, room_id) + logger.info(f"Successfully deleted room with id: {room_id}") + except NoResultFound as e: + logger.warning(f"Room with id {room_id} not found") + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail=f"Room with id {room_id} not found", + ) from e + except SQLAlchemyError as e: + logger.error(f"Database error while deleting room with id {room_id}: {str(e)}") + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail="Database error occurred", + ) from e + except Exception as e: + logger.error( + f"Unexpected error while deleting room with id {room_id}: {str(e)}" + ) + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail="An unexpected error occurred", + ) from e diff --git a/backend/src/backend/routers/users.py b/backend/src/backend/routers/users.py index fef86c9c..b49d1ba5 100644 --- a/backend/src/backend/routers/users.py +++ b/backend/src/backend/routers/users.py @@ -1,5 +1,7 @@ """Routes for user-related operations in the Numinar coding project backend.""" +import logging + from fastapi import APIRouter from fastapi import HTTPException from pydantic import EmailStr @@ -12,36 +14,49 @@ from backend.services.users import get_user from backend.services.users import get_users +logger = logging.getLogger(__name__) + router = APIRouter(prefix="/users", tags=["users"]) @router.get("/", response_model=list[UserResponse]) async def read_users(session: DBSession): """Endpoint to retrieve all users.""" + logger.debug("Received request to fetch all users") try: users = await get_users(session) + logger.info(f"Successfully retrieved {len(users)} users") + return users except SQLAlchemyError as e: + logger.error(f"Database error while fetching users: {str(e)}") raise HTTPException(status_code=500, detail="Database error occurred") from e except Exception as e: + logger.error(f"Unexpected error while fetching users: {str(e)}") raise HTTPException( status_code=500, detail="An unexpected error occurred" ) from e - return users @router.get("/{email}", response_model=UserResponse) async def read_user(email: EmailStr, session: DBSession): """Endpoint to retrieve a user by email.""" + logger.debug(f"Received request to fetch user with email: {email}") try: user = await get_user(session, email) + logger.info(f"Successfully retrieved user with email: {email}") + return user except NoResultFound as e: + logger.warning(f"User with email {email} not found") raise HTTPException( status_code=404, detail=f"User with email {email} not found" ) from e except SQLAlchemyError as e: + logger.error(f"Database error while fetching user with email {email}: {str(e)}") raise HTTPException(status_code=500, detail="Database error occurred") from e except Exception as e: + logger.error( + f"Unexpected error while fetching user with email {email}: {str(e)}" + ) raise HTTPException( status_code=500, detail="An unexpected error occurred" ) from e - return user diff --git a/backend/src/backend/schemas/rooms.py b/backend/src/backend/schemas/rooms.py index 7e5446eb..111e46ff 100644 --- a/backend/src/backend/schemas/rooms.py +++ b/backend/src/backend/schemas/rooms.py @@ -19,6 +19,17 @@ class RoomCreate(RoomBase): model_config = ConfigDict(from_attributes=True) +class RoomUpdate(BaseModel): + """Schema for updating an existing Room.""" + + name: str | None = None + location: str | None = None + equipment: str | None = None + capacity: int | None = None + + model_config = ConfigDict(from_attributes=True) + + class RoomResponse(RoomBase): """Response schema for Room, including ID."""