Skip to content
rutwik.devALL ACCESS
ALL PROJECTSWEB · CASE STUDY

RoomReserve (AirbnbLite)

Hotel Booking API.

Full-featured hotel booking backend API with user authentication, hotel/room management, booking lifecycle, and mock payment integration. It has 37 REST endpoints on a normalized relational schema with concurrency-safe double-booking prevention.

PROJECT PASSNo. 04
STACK
4 tools
STATUS
Live
VIDEO
38s
OUTCOMES
6
01

The challenge

A hotel booking system has tricky consistency requirements: two users booking the same room at the same time must not both succeed. Building this correctly from scratch, with proper auth, availability windows, and payment flow, is a systems design exercise that surfaces real database and API design decisions.

02

The solution

Designed a layered FastAPI backend with 37 REST endpoints: route handlers → service layer → SQLAlchemy repository. Booking conflicts are prevented using database-level row locking (SELECT FOR UPDATE) inside a transaction, ensuring only one booking can claim a room for overlapping dates. JWT tokens (access + refresh) handle auth with role-based access control. Auto-generated OpenAPI docs via FastAPI serve as live documentation.

ARCHITECTURE

FastAPI routers → Pydantic schemas for validation → Service layer for business logic → SQLAlchemy ORM with PostgreSQL → Alembic for migrations. JWT auth middleware with role-based access control. Row-level locking for booking conflict prevention. Mock Stripe integration in the payment service layer.

IMPACT

  • Live Swagger UI with 37 REST endpoints and fully interactive documentation
  • Zero double-booking bugs: row-level locking prevents race conditions under concurrent load
  • Full booking lifecycle: search → reserve → pay → cancel with status transitions
  • Role-based access control separates guest, host, and admin capabilities
  • JWT refresh token rotation implemented correctly, with no silent token reuse attacks
  • Alembic migrations make schema changes safe and reversible across environments

WHAT I LEARNED

  • SELECT FOR UPDATE inside a transaction is the correct primitive for booking conflict prevention. Optimistic locking would work too, but adds retry complexity
  • FastAPI's dependency injection made adding auth middleware to specific routes clean without wrapping every handler
  • Pydantic v2's model_validator enabled cross-field validation (check-out must be after check-in) at the schema layer, keeping the service layer clean
FastAPIPostgreSQLSQLAlchemyJWT
NEXT PASSRestore Wellness