Skip to content

hassonor/wiser

Repository files navigation

🏨 Wiser - Hotel Reservation Microservices Platform

License: MIT NestJS TypeScript MongoDB

Production-grade hotel reservation system built with NestJS microservices

Features β€’ Quick Start β€’ Architecture β€’ Deployment


πŸ“‹ Table of Contents


🌟 Overview

Wiser is a comprehensive hotel reservation platform demonstrating enterprise-grade microservices architecture using NestJS. The project showcases modern backend development practices including dependency injection, event-driven communication, database per service pattern, and cloud-native deployment.

Why Wiser?

  • βœ… NestJS Best Practices: Modules, services, controllers, guards, interceptors
  • βœ… Cloud-Native: Designed for Google Cloud Platform with Kubernetes
  • βœ… Production-Ready: Authentication, validation, error handling, logging
  • βœ… Scalable Architecture: Independent services, horizontal scaling
  • βœ… CI/CD Pipeline: Automated builds and deployments with CloudBuild
  • βœ… Educational: Clean code, comprehensive documentation, real-world patterns

✨ Features

Core Functionality

  • πŸ” Authentication & Authorization: JWT-based auth with passport.js
  • 🏨 Reservation Management: Create, update, cancel hotel bookings
  • πŸ’³ Payment Processing: Payment integration with Stripe
  • πŸ“§ Notification System: Email notifications for bookings, cancellations
  • πŸ“Š Admin Dashboard: Manage reservations, users, hotels

Technical Features

  • 🎯 Microservices Architecture: Independent, deployable services
  • πŸ”„ Event-Driven Communication: RabbitMQ/NATS for async messaging
  • πŸ’Ύ Database Per Service: MongoDB with Mongoose
  • 🐳 Containerized: Docker for local development
  • ☸️ Kubernetes-Ready: Helm charts for production deployment
  • πŸš€ GCP Integration: Cloud Build, Artifact Registry, GKE

πŸ›  Tech Stack

Backend Framework

  • NestJS 10.x - Progressive Node.js framework
  • TypeScript 5.x - Type-safe development
  • Node.js 20.x - Runtime environment

Microservices

Service Responsibility Database
Reservations Booking management MongoDB
Auth Authentication & authorization MongoDB
Payments Payment processing MongoDB
Notifications Email/SMS alerts MongoDB

Infrastructure

  • Database: MongoDB with Mongoose ODM
  • Message Broker: RabbitMQ / NATS
  • Containerization: Docker & Docker Compose
  • Orchestration: Kubernetes with Helm
  • Cloud Platform: Google Cloud Platform (GCP)
    • Google Artifact Registry
    • Google Kubernetes Engine (GKE)
    • Cloud Build for CI/CD

Testing

  • Unit Tests: Jest
  • E2E Tests: Supertest
  • Integration Tests: Testcontainers

πŸ— Architecture

High-Level System Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    Client Layer                         β”‚
β”‚          (Web App, Mobile App, Admin Panel)            β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                      β”‚ HTTPS/REST
                      β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                   API Gateway                          β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”       β”‚
β”‚  β”‚  Auth    │─▢│   Rate   │─▢│   Routing    β”‚       β”‚
β”‚  β”‚  Guard   β”‚  β”‚  Limit   β”‚  β”‚   Logic      β”‚       β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜       β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                    β”‚
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β–Ό           β–Ό           β–Ό
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β”‚  Auth   β”‚ β”‚Reserva- β”‚ β”‚Payments β”‚ β”‚ Notif   β”‚
   β”‚ Service β”‚ β”‚  tions  β”‚ β”‚ Service β”‚ β”‚ Service β”‚
   β”‚         β”‚ β”‚ Service β”‚ β”‚         β”‚ β”‚         β”‚
   β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”˜
        β”‚           β”‚           β”‚           β”‚
        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                    β”‚
              β”Œβ”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”
              β–Ό           β–Ό
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β”‚ RabbitMQ β”‚ β”‚ MongoDB  β”‚
        β”‚ (Events) β”‚ β”‚(Per Svc) β”‚
        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Microservices Communication

  1. Synchronous: REST API for immediate responses
  2. Asynchronous: RabbitMQ/NATS for events (booking confirmation, payments)
  3. Database Per Service: Each service owns its data

πŸš€ Quick Start

Get Wiser running locally in 5 minutes:

Prerequisites

  • Node.js >= 20.x
  • Docker & Docker Compose
  • Git

Local Development

# 1. Clone the repository
git clone https://github.com/hassonor/wiser.git
cd wiser

# 2. Install dependencies
npm install

# 3. Start MongoDB and RabbitMQ via Docker
docker-compose up -d

# 4. Set up environment variables
cp .env.example .env
# Edit .env with your configuration

# 5. Run database migrations (if any)
npm run migration:run

# 6. Start all microservices in development mode
npm run start:dev

# Access the API at http://localhost:3000

Verification

# Health check
curl http://localhost:3000/health

# Test authentication
curl -X POST http://localhost:3000/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email":"test@example.com","password":"password"}'

πŸ“ Project Structure

wiser/
β”œβ”€β”€ apps/                          # Microservices
β”‚   β”œβ”€β”€ reservations/              # Reservation service
β”‚   β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”‚   β”œβ”€β”€ dto/               # Data transfer objects
β”‚   β”‚   β”‚   β”œβ”€β”€ entities/          # Database entities
β”‚   β”‚   β”‚   β”œβ”€β”€ reservations.controller.ts
β”‚   β”‚   β”‚   β”œβ”€β”€ reservations.service.ts
β”‚   β”‚   β”‚   β”œβ”€β”€ reservations.module.ts
β”‚   β”‚   β”‚   └── main.ts
β”‚   β”‚   β”œβ”€β”€ test/
β”‚   β”‚   └── Dockerfile
β”‚   β”‚
β”‚   β”œβ”€β”€ auth/                      # Authentication service
β”‚   β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”‚   β”œβ”€β”€ strategies/        # Passport strategies (JWT, local)
β”‚   β”‚   β”‚   β”œβ”€β”€ guards/            # Auth guards
β”‚   β”‚   β”‚   β”œβ”€β”€ auth.controller.ts
β”‚   β”‚   β”‚   β”œβ”€β”€ auth.service.ts
β”‚   β”‚   β”‚   └── main.ts
β”‚   β”‚   └── Dockerfile
β”‚   β”‚
β”‚   β”œβ”€β”€ payments/                  # Payment service
β”‚   └── notifications/             # Notification service
β”‚
β”œβ”€β”€ libs/                          # Shared libraries
β”‚   β”œβ”€β”€ common/                    # Common utilities
β”‚   β”‚   β”œβ”€β”€ database/              # Database connection
β”‚   β”‚   β”œβ”€β”€ decorators/            # Custom decorators
β”‚   β”‚   β”œβ”€β”€ filters/               # Exception filters
β”‚   β”‚   β”œβ”€β”€ interceptors/          # Logging, transform
β”‚   β”‚   └── guards/                # Shared guards
β”‚   └── config/                    # Configuration module
β”‚
β”œβ”€β”€ k8s/                           # Kubernetes manifests
β”‚   └── wiser/                     # Helm chart
β”‚       β”œβ”€β”€ Chart.yaml
β”‚       β”œβ”€β”€ values.yaml
β”‚       └── templates/
β”‚           β”œβ”€β”€ reservations/
β”‚           β”‚   β”œβ”€β”€ deployment.yaml
β”‚           β”‚   └── service.yaml
β”‚           β”œβ”€β”€ auth/
β”‚           └── payments/
β”‚
β”œβ”€β”€ .cursorrules                   # AI coding standards
β”œβ”€β”€ .github/
β”‚   β”œβ”€β”€ dependabot.yml            # Automated dependency updates
β”‚   └── workflows/                 # CI/CD pipelines
β”‚
β”œβ”€β”€ cloudbuild.yaml               # Google Cloud Build config
β”œβ”€β”€ docker-compose.yaml           # Local development
β”œβ”€β”€ nest-cli.json                 # NestJS configuration
β”œβ”€β”€ package.json                  # Dependencies
└── README.md

πŸ”§ Microservices

Reservations Service

Manages hotel bookings

Endpoints:

POST   /reservations              # Create booking
GET    /reservations              # List all bookings
GET    /reservations/:id          # Get booking details
PATCH  /reservations/:id          # Update booking
DELETE /reservations/:id          # Cancel booking

Events Published:

  • reservation.created
  • reservation.updated
  • reservation.cancelled

Auth Service

JWT-based authentication

Endpoints:

POST   /auth/register            # User registration
POST   /auth/login               # User login
POST   /auth/refresh             # Refresh access token
GET    /auth/profile             # Get user profile

Guards:

  • JwtAuthGuard - Protect routes with JWT
  • LocalAuthGuard - Email/password authentication

Payments Service

Stripe integration

Endpoints:

POST   /payments/charge          # Process payment
POST   /payments/refund          # Refund payment
GET    /payments/:id             # Get payment details

Notifications Service

Email/SMS notifications

Events Consumed:

  • reservation.created β†’ Send confirmation email
  • reservation.cancelled β†’ Send cancellation email
  • payment.completed β†’ Send receipt

πŸ’» Development

Running Individual Services

# Start specific service
npm run start:dev reservations

# Build for production
npm run build reservations

# Run tests
npm run test reservations
npm run test:e2e reservations

Environment Variables

Each service requires environment variables:

# Reservations Service
MONGODB_URI=mongodb://localhost:27017/reservations
RABBITMQ_URL=amqp://localhost:5672
JWT_SECRET=your-secret-key
PORT=3001

# Auth Service
MONGODB_URI=mongodb://localhost:27017/auth
JWT_SECRET=your-secret-key
JWT_EXPIRES_IN=1h
PORT=3002

# Payments Service
STRIPE_SECRET_KEY=sk_test_...
MONGODB_URI=mongodb://localhost:27017/payments
PORT=3003

Code Generation

# Generate new module
nest g module users apps/reservations

# Generate service
nest g service users apps/reservations

# Generate controller
nest g controller users apps/reservations

πŸ§ͺ Testing

Unit Tests

# Run all tests
npm run test

# Watch mode
npm run test:watch

# Coverage
npm run test:cov

E2E Tests

# Run E2E tests for a service
npm run test:e2e reservations

Integration Tests

# Uses Testcontainers for real MongoDB
npm run test:integration

🚒 Deployment

Docker Compose (Local/Staging)

# Build and start all services
docker-compose up --build

# Scale a service
docker-compose up --scale reservations=3

# View logs
docker-compose logs -f reservations

# Stop all
docker-compose down

☁️ Google Cloud Platform (GCP) Deployment

1. Enable Required APIs

# Enable Container Registry and Artifact Registry
gcloud services enable containerregistry.googleapis.com
gcloud services enable artifactregistry.googleapis.com

2. Create Artifact Registry Repository

# Set your project
gcloud config set project YOUR_PROJECT_ID

# Create repository for each service
gcloud artifacts repositories create reservations \
  --repository-format=docker \
  --location=us-central1 \
  --description="Reservations service images"

# Repeat for auth, payments, notifications

3. Build & Push Docker Images

# Authenticate Docker
gcloud auth configure-docker us-central1-docker.pkg.dev

# Build and push (example for reservations)
cd apps/reservations/
docker build -t reservations -f ./Dockerfile ../../
docker tag reservations us-central1-docker.pkg.dev/YOUR_PROJECT/reservations/production
docker push us-central1-docker.pkg.dev/YOUR_PROJECT/reservations/production

4. Automated CI/CD with Cloud Build

Create cloudbuild.yaml at project root:

steps:
  # Build reservations service
  - name: 'gcr.io/cloud-builders/docker'
    args:
      - 'build'
      - '-t'
      - 'us-central1-docker.pkg.dev/$PROJECT_ID/reservations/production'
      - '-f'
      - './apps/reservations/Dockerfile'
      - '.'

  # Push reservations service
  - name: 'gcr.io/cloud-builders/docker'
    args:
      - 'push'
      - 'us-central1-docker.pkg.dev/$PROJECT_ID/reservations/production'

  # Repeat for other services...

images:
  - 'us-central1-docker.pkg.dev/$PROJECT_ID/reservations/production'
  - 'us-central1-docker.pkg.dev/$PROJECT_ID/auth/production'
  - 'us-central1-docker.pkg.dev/$PROJECT_ID/payments/production'
  - 'us-central1-docker.pkg.dev/$PROJECT_ID/notifications/production'

Set up Cloud Build Trigger:

  1. Go to Cloud Build β†’ Triggers
  2. Connect your GitHub repository
  3. Create trigger to run on push to main branch
  4. Use cloudbuild.yaml as build configuration

☸️ Kubernetes Deployment

Local Kubernetes Setup

# Enable Kubernetes in Docker Desktop
# Settings β†’ Kubernetes β†’ Enable Kubernetes

# Install Helm
brew install helm  # macOS
choco install helm # Windows

# Verify installation
kubectl version
helm version

Create Helm Chart

# Create Helm chart
cd k8s/
helm create wiser

# Create deployments for each service
kubectl create deployment reservations \
  --image=us-central1-docker.pkg.dev/PROJECT/reservations/production \
  --dry-run=client -o yaml > ./wiser/templates/reservations/deployment.yaml

# Create services
kubectl create service clusterip reservations \
  --tcp=3001:3001 \
  --dry-run=client -o yaml > ./wiser/templates/reservations/service.yaml

# Repeat for other services

Deploy to Kubernetes

# Install/upgrade the Helm chart
helm upgrade --install wiser ./k8s/wiser \
  --set reservations.image=us-central1-docker.pkg.dev/PROJECT/reservations/production \
  --set auth.image=us-central1-docker.pkg.dev/PROJECT/auth/production

# Check deployment status
kubectl get pods
kubectl get services

# View logs
kubectl logs -f deployment/reservations

# Scale deployment
kubectl scale deployment reservations --replicas=3

Google Kubernetes Engine (GKE)

# Create GKE cluster
gcloud container clusters create wiser-cluster \
  --zone=us-central1-a \
  --num-nodes=3 \
  --machine-type=n1-standard-2

# Get credentials
gcloud container clusters get-credentials wiser-cluster --zone=us-central1-a

# Deploy using Helm
helm upgrade --install wiser ./k8s/wiser

# Set up Ingress for external access
kubectl apply -f k8s/ingress.yaml

🀝 Contributing

Contributions are welcome! Please see CONTRIBUTING.md for guidelines.

Development Workflow

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/amazing-feature
  3. Make your changes following .cursorrules
  4. Write/update tests
  5. Run linter: npm run lint
  6. Commit: git commit -m "feat: add amazing feature"
  7. Push: git push origin feature/amazing-feature
  8. Open a Pull Request

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.


πŸ™ Acknowledgments

  • Built with NestJS - A progressive Node.js framework
  • Inspired by production hotel booking platforms
  • Created for educational purposes to demonstrate microservices architecture

Made with ❀️ by Or Hasson

⭐ Star this repo if you find it helpful!

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •