Holberton BnB is a comprehensive web application that enables users to discover, list, and review accommodation properties. Built with modern web technologies, it features a robust three-tier architecture that ensures scalability, maintainability, and optimal user experience. The platform allows property owners to showcase their listings with detailed information, amenities, and ratings, while providing guests with an intuitive interface to explore available accommodations.
- Property Management: Create, update, and manage accommodation listings with detailed descriptions and geolocation
- Star Rating System: 5-star rating system for places with visual star indicators and rating validation
- User Authentication & Authorization: JWT-based authentication with bcrypt password hashing and admin privileges
- Amenity Integration: Comprehensive amenity management with many-to-many relationships
- Review System: Users can leave reviews and ratings with proper validation and relationship management
- Database Persistence: MySQL database with SQLAlchemy ORM and comprehensive data relationships
- Repository Pattern: Specialized repositories for different entities with abstract base classes
- RESTful API: Well-structured API endpoints with Swagger documentation and CORS support
- Responsive Design: Modern, mobile-friendly interface built with Svelte and custom styling
- Testing Suite: Comprehensive unit and integration tests for models and API endpoints
- Database Seeding: Automated database seeding with test data for development
- About
- Key Features
- Technology Stack
- Architecture
- Database Design
- API Workflows
- Run Local Development
- Contributors
This AirBnB-like project follows a three-tier layered architecture pattern that guarantees separation of concerns, maintainability and scalability.
Each layer has responsibilities and communicates through defined interfaces.
-
- UI/UX
- Client-side interactions.
- Request/Responses formatting.
- HTTP status management.
- API Controllers.
-
- Contains core application logic and business rules.
- Manages data models and their relationships.
- Validation, processing and business operations.
- Components: User, Place, Review, Amenity.
-
- MySQL database with SQLAlchemy ORM integration
- Repository pattern with specialized repositories for different entities
- Database relationship management and foreign key constraints
- Automated database migrations and seeding capabilities
The Facade Pattern is an interface between the Presentation and Business Logic layers.
The fundamental purpose is don’t expose entities (User, Place, Review, Amenities) providing high-level operation (functions).
This approach ensures that the presentation layer doesn't need to understand the details of business logic implementation, promoting low coupling and easier maintenance.
For this project, we developed a three-layer architecture implementing the Facade pattern for separation of concern and scalability.
User-System communication, this represents the application GUI’s and the higher level logic in our app.
-
- Login: User log-in/sign-in authentication.
- User Management: Where the user can customize its profile, change user settings, see user-related information.
- Publish Offer: Manage places, create/update user listings.
- Rent a Place: Showcase listings available for rent.
-
- Authentication Endpoints: JWT-based login and registration with secure cookie handling
- CRUD Operations: Complete REST API for users, places, amenities, and reviews
- Swagger Documentation: Interactive API documentation with authentication support
- CORS Support: Cross-origin resource sharing for frontend-backend communication
- HTTP Status Management: Comprehensive HTTP status codes and error handling
Main design and logic of our application, this is where the facade pattern takes form.
The facade pattern gives the components of the business logic layer a straightforward way to communicate with higher level components.
-
- Client: User-related operations. (create user, update user information, validate information, manage user-user interactions)
- Places: Place-related operations. (create/update place, validate place information, manage status like; available, rented, hidden, etc)
- Reviews: Review moderation, calculate place rating (imagine a 5-star system based on the number of starts where each review can be 1-5 stars).
- Amenities: Create/Update/Delete amenity, categorize amenities based on their level of comfort (a jacuzzi is a premium amenity.)
-
- Validate Data: Ensures data integrity and enforces business rules before processing. Validates input information like; data type, required fields. validates email, phone and dates. Cleans up data. Handles relationship logic like: review target place exists and user rented that place within a time-frame.
- Logic Operations: Performs comprehensive validation for every entity, including data type validation, business rule enforcement, and relationship integrity checks. Handles complex operations like user authentication, password hashing, rating calculations, and amenity associations.
- Relation Management: Validates and manages relationships between entities, such as user-place ownership, place-amenity associations, and user-review authorship. Prevents orphaned entities and maintains referential integrity through proper foreign key constraints.
Database storage and retrieval with comprehensive relationship management and data integrity.
-
- SQLAlchemyRepository: Base repository with common CRUD operations
- UserRepository: Specialized user data management with email uniqueness
- PlaceRepository: Place data management with amenity and review relationships
- ReviewRepository: Review management with place and user associations
-
- MySQL Integration: Full MySQL database with PyMySQL connector
- ORM Relationships: SQLAlchemy relationships with lazy loading and cascade operations
- Data Seeding: Automated database seeding with comprehensive test data
- Migration Support: Database schema management and automated table creation
Data flow example:
- User registration request received
- API delegates to HBnBFacade
- Facade creates User model instance with validation
- UserRepository persists data to MySQL database
- Database confirms successful storage
- Response serialized and returned to client

Represents a client using the app.
- id: Primary Key.
- first_name: User’s first name.
- last_name: User’s last name.
- email: User’s email.
- is_admin: if True, this instance of User has elevated privileges.
- created_at: auto-generated creation date.
- updated_at: auto-generated update date.
Characteristics and relations:
- One user can have none or many places listed.
- An user can be either regular or administrator.
- Can create, update and delete his account.
- One user can author one reviews for each place he rented.
Represents asset locations, whatever a User registers as a listing that can be rented and be rated according to its amenities.
- id: Primary Key.
- owner_id: Foreign Key of user who created the place.
- title: listing's title.
- description: a short description made by the User who owns it.
- price: rent price per day.
- longitude: longitude of this place.
- latitude: latitude of this place.
- rating: numerical rating from 0-5 stars for the place.
- created_at: auto-generated creation date.
- updated_at: auto-generated update date.
Characteristics and relations:
- One place can have one User who owns it.
- The owner can create, update and delete this place.
- One place can have many reviews by many Users who rented it.
- Each place is rated according to User reviews, amenities’ quality and quantity.
Can be features or services registered to a specific place like; WiFi, free parking, a jacuzzi and so on.
Amenities are created and managed only by Admin Users.
After the amenities are created, normal users can select them from a list to append it to places.
- id: Primary Key.
- name: the name of the amenity
- description: a short description.
- created_at: auto-generated creation date.
- updated_at: auto-generated update date.
Characteristics and relations:
- One amenity can be shared across many Places through many-to-many relationships.
- Amenities enhance place attractiveness and can influence user booking decisions.
- Can only be created, updated and deleted by Admin Users with elevated privileges.
It’s the feedback a User who rented a Place gave it.
- id: Primary Key.
- rating: the user’s rating of a place he rented.
- comment: a public comment that will describe the rating’s reason to other users.
- created_at: auto-generated creation date.
- updated_at: auto-generated update date.
Characteristics and relations:
- One User can author many reviews.
- One review can rate one Place.
- One Place can have many reviews from different users.
- Can be created, updated and deleted by the author.
Relational Many-To-Many table between places and amenities.
- place_id: Foreign key of place.
- amenity_id: Foreign key of amenity.
The following diagrams illustrates the core operations of our AirBnB-like implementation.
The purpose is to demonstrate the interaction flow between system layers, capturing the four primary workflows (listing creation, user registration, listings retrieval and review submission).
Process:
- A new user fills the registration form and submits the request.
- API receives the request and delegates to Business Logic through create_user().
- Business logic operations (data integrity, required fields, and business rules check)
- Valid data is saved into a database, the confirmation flows back to the client with HTTP 201 Created response.
On failure:
- Business Logic determines that the data is invalid.
- Business Logic responds “Invalid user data request” back to the API.
- API returns HTTP 400 Bad Request status to the Client App.
Process:
- Listing creation request.
- API receives request and calls create_listing(data)
- Business logic operation (Ensures data integrity and business rules compliance)
- Valid data is saved in the database with HTTP 201 Created response.
On failure:
- Business Logic determines that the listing data is invalid.
- Business Logic responds “Invalid data request” back to the API.
- API returns HTTP 400 Bad Request status to the Client App.
Process:
- Client App initiates a "Review Submission" request to the API.
- API calls the post_review() function on the Business Logic layer.
- Business Logic validates the review data internally.
- Business Logic commands the Database for review storing.
- Database confirms the review storage with "Review stored confirmation".
- Business Logic responds "Review posted successfully" back to the API.
- API returns HTTP 201 Created response to the Client App.
On failure:
- Business Logic determines that the data is invalid.
- Business Logic responds “Review not valid” back to the API.
- API returns HTTP 400 Bad Request status to the Client App.
Process:
- Available places list request.
- API receives requests and calls get_places() from Business Logic.
- Business Logic queries database for listing.
- Results returned with HTTP 200 OK Response. If no matches are found, an empty list is returned. Front-end is then refreshed with returned listings.
- Swagger UI at:
localhost:5000/swag/ - Vite Client at:
localhost:5173
To run the Flask Server and connect it to the database you must export the MySQL credentials. I use this script to run it from inside a python virtual environment (I'm assuming you're on linux (Ubuntu 22.04 LTS), instructions for Windows will not be provided (figure it out yourself >:V)):
- Create and activate virtual environment:
python3 -m venv <environment_name>
source <environment_name>/bin/activate- Export your credentials using this script (place it inside your venv directory so it's included in gitignore) and run it with
source venv/db_credentials.sh
*Double check that git ignores the script
If you're running MySQL inside a docker container, you can export the environment variables directly when creating the container. Make sure to specifyhost.docker.internalas theDB_PORT.
#!/usr/bin/env bash
# I've named this script db_credentials.sh
export DB_USER=<your_MySQL_username>
export DB_PASSWORD=<your_password>
export DB_HOST=localhost
export DB_PORT=<Pick_a_port_not_5000_cause_its_flask>
export DB_NAME=hbnb_v1
export SECRET_KEY=unset
echo "Env Vars loaded"- Run the Flask server:
# from the project root
python3 app.pyYou should see this:
$ python3 app.py
* Serving Flask app 'app'
* Debug mode: on
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on http://127.0.0.1:5000
Press CTRL+C to quit
* Restarting with stat
CREATED DB!
* Debugger is active!
* Debugger PIN: 839-298-012- Run the Vite server.
- Open a new terminal.
- Navigate to
holbertonschool-hbnb/client - Run the Vite server:
npm run devYou should see this:
npm run dev
> [email protected] dev
> vite
[Routify 3] build completed (34 ms)
VITE v6.3.5 ready in 258 ms
➜ Local: http://localhost:5173/
➜ Network: http://192.168.1.90:5173/
➜ press h + enter to show help
*Ignore any warning about svelte packages with no exports conditions.





