# Design AirBnB or a Hotel Booking System

## Design AirBnB or a Hotel Booking System

## Requirements

### Guests

* search rooms by locations, dates, and number of guests
* get room details(like picture, name, review, address, etc) and prices
* pay and book room from inventory by date and by room\_id
  * checkout as a guest
  * user is logged in already
* notification via Email and mobile push notification

### Hotel or Rental Admin

* manage room inventory and help the guest to check-in and check out
* housekeeper: clean up rooms routinely

***

## High-level architecture

![](https://2407442552-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lpv9LvHzpublmUWisvz%2Fuploads%2Fgit-blob-6ea952c3f73b371c3c225dda2d9ec1069988b375%2Fairbnb.png?alt=media)

***

## Detailed Design

### Data Structure for User, Room and Booking

> Ref: [Designing a Data Model for a Hotel Room Booking System](https://www.vertabelo.com/blog/designing-a-data-model-for-a-hotel-room-booking-system/)

* The basic tables are: reservation, guest and room.
* use `status` to represent the status of a room: `EMPTY`, `RESERVED`

![](https://2407442552-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lpv9LvHzpublmUWisvz%2Fuploads%2Fgit-blob-d5a6183b2107f0677dbc4f0dcf68a4f2c293cf9a%2F1.png?alt=media)

![](https://2407442552-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lpv9LvHzpublmUWisvz%2Fuploads%2Fgit-blob-eec476bd14f1551ba46ba784e0ef11a0777c9ea7%2F2.png?alt=media)

![](https://2407442552-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lpv9LvHzpublmUWisvz%2Fuploads%2Fgit-blob-23f9983c6c273a70eb2bebaa456da2e6742c8cb3%2F3.png?alt=media)

***

### How to find available rooms?

#### Method 1: By location

* geo-search with [spatial indexing](https://en.wikipedia.org/wiki/Spatial_database)
  * e.g. geo-hash or quad-tree

#### Method 2: By room metadata

* apply filters or search conditions when query the database

#### Method 3: By data-in and data-out availability

* option 1(recommended): for each `room_id`, create an entry for an occupied day. It will be easier to query unavailable slots by dates
* option 2: for each `room_id`, check all `occupied_room` from today.
  * transform the data structure to an array of occupied days
  * keep searching until got the available slots
  * this is time-consuming, so we can build the **availability index**

***

### External Hotel Supplier

![](https://2407442552-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lpv9LvHzpublmUWisvz%2Fuploads%2Fgit-blob-6a8a41378160158ee74db82412a626f4f1714a62%2F4.png?alt=media)

* provide **webhook callback APIs** to external vendors to update status in the internal system

***

### Payment

> Ref: [Stripe Idempotency](https://stripe.com/blog/idempotency)

* retry with [idempotency](https://stripe.com/blog/idempotency) to improve the success rate of the external calls and ensure no duplicate orders

#### Bookkeeping

* data model: [double-entry bookkeeping](https://en.wikipedia.org/wiki/Double-entry_bookkeeping)
* sync data across transaction table and external banks and vendors

***

### Notification

The notification system is essentially a delayer scheduler (**priority queue + subscriber**) plus API integrations.

* For example, a daily cronjob will query the database for notifications to be sent out today and put them into the priority queue by date.
* The subscriber will get the earliest ones from the priority queue and send out if reaching the expected timestamp.
* Otherwise, put the task back to the queue and sleep to make the CPU idle for other work, which can be interrupted if there are new alerts added for today.
