app.routes.rooms

Rooms Routing Module.

Provides the two room-browsing endpoints used by the portal page:

  • GET /api/rooms?date={date} — list all rooms with slot availability
  • GET /api/rooms/{id} — fetch a single room by primary key

Both endpoints require a valid authenticated user (401 if missing). Business logic is fully delegated to the room_service layer.

Traces to: UC-2

 1"""
 2Rooms Routing Module.
 3
 4Provides the two room-browsing endpoints used by the portal page:
 5  - GET /api/rooms?date={date}  — list all rooms with slot availability
 6  - GET /api/rooms/{id}         — fetch a single room by primary key
 7
 8Both endpoints require a valid authenticated user (401 if missing).
 9Business logic is fully delegated to the room_service layer.
10
11Traces to: UC-2
12"""
13
14from datetime import date
15from typing import List
16
17from fastapi import APIRouter, Depends, HTTPException, Query, status
18from sqlmodel.ext.asyncio.session import AsyncSession
19
20from app.database import get_session
21from app.models.user import User
22from app.schemas.room import RoomBasicRead, RoomRead
23from app.services.auth import current_active_user
24from app.services.room_service import (
25    RoomNotFoundError,
26    get_available_dates,
27    get_room,
28    get_rooms_with_availability,
29)
30
31router = APIRouter(prefix="/api/rooms", tags=["rooms"])
32
33
34@router.get("", response_model=List[RoomRead])
35async def list_rooms(
36    target_date: date = Query(..., alias="date"),
37    user: User = Depends(current_active_user),
38    session: AsyncSession = Depends(get_session),
39):
40    """
41    Return all rooms with their time-slot availability for the requested date.
42
43    The ``date`` query parameter is required. Each room in the response includes
44    its name, capacity, and the list of time slots for that date (with
45    ``start_time``, ``end_time``, and ``status``).  Rooms that have no slots
46    on the given date are still returned but with an empty ``time_slots`` list.
47
48    Requires a valid authenticated user — unauthenticated requests receive 401.
49    """
50    return await get_rooms_with_availability(target_date, session)
51
52
53@router.get("/dates", response_model=List[date])
54async def list_available_dates(
55    year: int = Query(...),
56    month: int = Query(..., ge=1, le=12),
57    user: User = Depends(current_active_user),
58    session: AsyncSession = Depends(get_session),
59):
60    """
61    Return a list of dates in the given year/month that have at least one
62    available time slot across any room.
63
64    Requires a valid authenticated user — unauthenticated requests receive 401.
65    """
66    return await get_available_dates(year, month, session)
67
68
69@router.get("/{id}", response_model=RoomBasicRead)
70async def retrieve_room(
71    id: int,
72    user: User = Depends(current_active_user),
73    session: AsyncSession = Depends(get_session),
74):
75    """
76    Return the details of a single room identified by its integer primary key.
77
78    Raises a 404 HTTP error if no room with the given ``id`` exists.
79    Requires a valid authenticated user — unauthenticated requests receive 401.
80    """
81    try:
82        return await get_room(id, session)
83    except RoomNotFoundError as exc:
84        raise HTTPException(
85            status_code=status.HTTP_404_NOT_FOUND, detail=str(exc)
86        ) from exc
router = <fastapi.routing.APIRouter object>
@router.get('', response_model=List[RoomRead])
async def list_rooms( target_date: datetime.date = Query(PydanticUndefined), user: app.models.User = Depends(dependency=<function Authenticator.current_user.<locals>.current_user_dependency>, use_cache=True, scope=None), session: sqlmodel.ext.asyncio.session.AsyncSession = Depends(dependency=<function get_session>, use_cache=True, scope=None)):
35@router.get("", response_model=List[RoomRead])
36async def list_rooms(
37    target_date: date = Query(..., alias="date"),
38    user: User = Depends(current_active_user),
39    session: AsyncSession = Depends(get_session),
40):
41    """
42    Return all rooms with their time-slot availability for the requested date.
43
44    The ``date`` query parameter is required. Each room in the response includes
45    its name, capacity, and the list of time slots for that date (with
46    ``start_time``, ``end_time``, and ``status``).  Rooms that have no slots
47    on the given date are still returned but with an empty ``time_slots`` list.
48
49    Requires a valid authenticated user — unauthenticated requests receive 401.
50    """
51    return await get_rooms_with_availability(target_date, session)

Return all rooms with their time-slot availability for the requested date.

The date query parameter is required. Each room in the response includes its name, capacity, and the list of time slots for that date (with start_time, end_time, and status). Rooms that have no slots on the given date are still returned but with an empty time_slots list.

Requires a valid authenticated user — unauthenticated requests receive 401.

@router.get('/dates', response_model=List[date])
async def list_available_dates( year: int = Query(PydanticUndefined), month: int = Query(PydanticUndefined), user: app.models.User = Depends(dependency=<function Authenticator.current_user.<locals>.current_user_dependency>, use_cache=True, scope=None), session: sqlmodel.ext.asyncio.session.AsyncSession = Depends(dependency=<function get_session>, use_cache=True, scope=None)):
54@router.get("/dates", response_model=List[date])
55async def list_available_dates(
56    year: int = Query(...),
57    month: int = Query(..., ge=1, le=12),
58    user: User = Depends(current_active_user),
59    session: AsyncSession = Depends(get_session),
60):
61    """
62    Return a list of dates in the given year/month that have at least one
63    available time slot across any room.
64
65    Requires a valid authenticated user — unauthenticated requests receive 401.
66    """
67    return await get_available_dates(year, month, session)

Return a list of dates in the given year/month that have at least one available time slot across any room.

Requires a valid authenticated user — unauthenticated requests receive 401.

@router.get('/{id}', response_model=RoomBasicRead)
async def retrieve_room( id: int, user: app.models.User = Depends(dependency=<function Authenticator.current_user.<locals>.current_user_dependency>, use_cache=True, scope=None), session: sqlmodel.ext.asyncio.session.AsyncSession = Depends(dependency=<function get_session>, use_cache=True, scope=None)):
70@router.get("/{id}", response_model=RoomBasicRead)
71async def retrieve_room(
72    id: int,
73    user: User = Depends(current_active_user),
74    session: AsyncSession = Depends(get_session),
75):
76    """
77    Return the details of a single room identified by its integer primary key.
78
79    Raises a 404 HTTP error if no room with the given ``id`` exists.
80    Requires a valid authenticated user — unauthenticated requests receive 401.
81    """
82    try:
83        return await get_room(id, session)
84    except RoomNotFoundError as exc:
85        raise HTTPException(
86            status_code=status.HTTP_404_NOT_FOUND, detail=str(exc)
87        ) from exc

Return the details of a single room identified by its integer primary key.

Raises a 404 HTTP error if no room with the given id exists. Requires a valid authenticated user — unauthenticated requests receive 401.