{"id":51555296,"url":"https://github.com/saikatbhuiyan/flight-booking-microservices","last_synced_at":"2026-07-10T04:30:30.667Z","repository":{"id":331652925,"uuid":"1093148837","full_name":"saikatbhuiyan/flight-booking-microservices","owner":"saikatbhuiyan","description":"A scalable flight booking microservices system built with NestJS, featuring API Gateway, event-driven architecture, RabbitMQ, PostgreSQL, Redis, and distributed system design.","archived":false,"fork":false,"pushed_at":"2026-05-06T01:38:54.000Z","size":1426,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-05-06T03:27:22.207Z","etag":null,"topics":["api-gateway","backend","booking-system","event-driven","flight-booking","microservices","nestjs","postgersql","rabittmq","redis"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/saikatbhuiyan.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-11-10T01:14:16.000Z","updated_at":"2026-05-06T01:38:57.000Z","dependencies_parsed_at":null,"dependency_job_id":"f159fd53-8f49-4463-8ebf-59de321c5834","html_url":"https://github.com/saikatbhuiyan/flight-booking-microservices","commit_stats":null,"previous_names":["saikatbhuiyan/flight-bookings","saikatbhuiyan/flight-booking-microservices"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/saikatbhuiyan/flight-booking-microservices","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/saikatbhuiyan%2Fflight-booking-microservices","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/saikatbhuiyan%2Fflight-booking-microservices/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/saikatbhuiyan%2Fflight-booking-microservices/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/saikatbhuiyan%2Fflight-booking-microservices/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/saikatbhuiyan","download_url":"https://codeload.github.com/saikatbhuiyan/flight-booking-microservices/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/saikatbhuiyan%2Fflight-booking-microservices/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35321224,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-10T02:00:06.465Z","response_time":60,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api-gateway","backend","booking-system","event-driven","flight-booking","microservices","nestjs","postgersql","rabittmq","redis"],"created_at":"2026-07-10T04:30:29.516Z","updated_at":"2026-07-10T04:30:30.661Z","avatar_url":"https://github.com/saikatbhuiyan.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Flight Booking Microservices\n\nNestJS-based flight booking platform built as a multi-service system with RabbitMQ, PostgreSQL, Redis, LocalStack S3, and OpenTelemetry. The repository is structured for both engineering review and hands-on local development.\n\n## What This Project Shows\n\n- Microservice decomposition with an API gateway and service-specific responsibilities\n- Mixed sync/async communication using HTTP and RabbitMQ\n- Database-per-service boundaries with shared platform libraries\n- Booking reliability patterns such as idempotency, seat locking, audit logs, and compensation events\n- Dev tooling for local containers, Swagger, health checks, tracing, and message-driven workflows\n\n## System Overview\n\n```text\nClient\n  |\n  v\nAPI Gateway (3000)\n  |\n  +--\u003e Auth Service (3001)\n  +--\u003e Flight Service (3002)\n  +--\u003e Booking Service (3003)\n  +--\u003e Notification Service (3004)\n  +--\u003e Payment Service (3005)\n\nShared infrastructure\n  - PostgreSQL\n  - Redis\n  - RabbitMQ\n  - LocalStack S3\n  - Tempo / Jaeger / Grafana\n```\n\n## Services\n\n| Service | Port | Responsibility |\n| --- | ---: | --- |\n| API Gateway | 3000 | Public HTTP entrypoint, auth, request validation, rate limiting, API composition |\n| Auth Service | 3001 | User authentication, JWT flows, refresh tokens, RBAC support |\n| Flight Service | 3002 | Flights, cities, airports, airplanes, seats, seat inventory changes |\n| Booking Service | 3003 | Booking lifecycle, saga orchestration, payment handoff, local payment fallback |\n| Notification Service | 3004 | Event-driven booking notifications |\n| Payment Service | 3005 | Payment intents, capture, refunds, ledgers, webhook handling |\n\n## Shared Libraries\n\n| Library | Purpose |\n| --- | --- |\n| `@app/common` | DTOs, decorators, filters, guards, interceptors, logging, Redis helpers |\n| `@app/database` | TypeORM setup and per-service data source configuration |\n| `@app/message-broker` | RabbitMQ integration helpers |\n| `@app/rate-limiter` | Shared rate limiting module and guard |\n| `@app/seat-lock` | Redis-backed distributed seat lock logic |\n| `@app/storage` | Storage abstraction for S3 / LocalStack |\n| `@app/telemetry` | OpenTelemetry bootstrap and tracing helpers |\n\n## Key Technical Patterns\n\n- Database-per-service isolation\n- Event-driven workflows with RabbitMQ\n- Idempotency keys for payment and booking-sensitive flows\n- Redis-backed distributed locking for seat reservation windows\n- Audit logging and ledger tracking in the payment domain\n- OpenTelemetry tracing with Tempo and Jaeger\n- Docker Compose workflow for local infrastructure\n\n## Local Development\n\n### Prerequisites\n\n- Node.js 18+\n- npm\n- Docker Desktop or Docker Engine with Compose\n- AWS CLI if you want to create the LocalStack S3 bucket via script\n\n### 1. Install dependencies\n\n```bash\nnpm install\n```\n\n### 2. Start infrastructure\n\n```bash\ndocker-compose up -d postgres redis rabbitmq localstack tempo jaeger grafana\n```\n\n### 3. Create the local S3 bucket\n\n```bash\nnpm run setup:localstack\n```\n\n### 4. Start the services\n\nRun everything:\n\n```bash\nnpm run start:all\n```\n\nOr run only the service you need:\n\n```bash\nnpm run start:api-gateway\nnpm run start:auth\nnpm run start:flight\nnpm run start:booking\nnpm run start:notification\nnpm run start:payment\n```\n\n## Useful Commands\n\n```bash\nnpm run build\nnpm run lint:check\nnpm test\nnpm run test:e2e\nnpm run docker:up\nnpm run docker:down\n```\n\n## Local URLs\n\n| Tool | URL |\n| --- | --- |\n| API Gateway | `http://localhost:3000` |\n| Swagger Docs | `http://localhost:3000/api/docs` |\n| RabbitMQ UI | `http://localhost:15672` |\n| Jaeger UI | `http://localhost:16686` |\n| Grafana | `http://localhost:3006` |\n| Tempo | `http://localhost:3200` |\n| LocalStack | `http://localhost:4566` |\n\nRabbitMQ default credentials:\n\n```text\nusername: admin\npassword: admin\n```\n\n## Repository Layout\n\n```text\napps/\n  api-gateway/\n  auth-service/\n  booking-service/\n  flight-service/\n  notification-service/\n  payment-service/\nlibs/\n  common/\n  database/\n  message-broker/\n  rate-limiter/\n  seat-lock/\n  storage/\n  telemetry/\ndocs/\ndocker-compose.yml\nnest-cli.json\n```\n\n## Suggested Reviewer Walkthrough\n\nIf you are evaluating the project, these are the fastest places to get signal:\n\n1. Start with `apps/api-gateway` to understand the public entrypoint.\n2. Open `apps/booking-service` to see orchestration and downstream coordination.\n3. Review `apps/payment-service` for idempotency, ledgering, refunds, and audit logging.\n4. Review `libs/seat-lock` for concurrency handling around seat reservation windows.\n5. Check `libs/telemetry` and `docker-compose.yml` for the observability setup.\n\n## Notes for Developers\n\n- Top-level `npm run build` targets the default Nest project defined in `nest-cli.json`.\n- Each service has its own `tsconfig.app.json` and can be started independently.\n- Each service now loads its own `apps/\u003cservice\u003e/.env` file even when started from the monorepo root.\n- Some lint warnings still exist in older parts of the codebase, but the repo now builds cleanly and the root scripts point at real apps.\n- Stripe is the production-ready payment path in this repo. PayPal is registered but intentionally returns `NotImplemented`.\n\n## Booking Flow Without Payment Service\n\nFor local development, `booking-service` can finish the full booking flow without `payment-service`.\n\n- In development, `booking-service` defaults to a local mock payment mode when `PAYMENT_REQUIRED` is not set.\n- You can make that behavior explicit by setting `PAYMENT_REQUIRED=false` in your local `apps/booking-service/.env`.\n- In that mode, `POST /bookings` still runs the booking saga, then auto-confirms the booking with a generated local transaction id.\n- The response includes `paymentRequired`, `autoCompleted`, and `payment.provider` so the caller can tell whether the booking used the real payment-service or the local mock path.\n- To test the real RMQ payment path locally, set `PAYMENT_REQUIRED=true` in `apps/booking-service/.env` and start `payment-service`.\n\n## Current Status\n\nThis repository is a strong backend architecture project with practical patterns for:\n\n- service separation\n- async communication\n- infrastructure-backed local development\n- payment and booking reliability concerns\n- observability and operational thinking\n\nIt is a good portfolio or interview project because it shows both application logic and platform engineering decisions in one codebase.\n\n### Start all services with Docker Compose\n```bash\ndocker-compose up --build\n```\n\n### Stop all services\n```bash\ndocker-compose down\n```\n\n### View logs\n```bash\ndocker-compose logs -f [service-name]\n```\n\n## 📚 API Documentation\n\nOnce the API Gateway is running, access Swagger documentation at:\n```\nhttp://localhost:3000/api/docs\n```\n\n### Authentication Endpoints\n```\nPOST /api/v1/auth/register    - Register new user\nPOST /api/v1/auth/login       - Login user\nPOST /api/v1/auth/refresh     - Refresh access token\nGET  /api/v1/auth/me          - Get current user profile\n```\n\n### Flight Endpoints\n```\nGET    /api/v1/flights              - List all flights\nGET    /api/v1/flights/search       - Search flights\nGET    /api/v1/flights/:id          - Get flight by ID\nPOST   /api/v1/flights              - Create flight (Admin)\nPUT    /api/v1/flights/:id          - Update flight (Admin)\nDELETE /api/v1/flights/:id          - Delete flight (Admin)\nPOST   /api/v1/flights/:id/image    - Upload flight image (Admin)\n```\n\n### Booking Endpoints\n```\nGET  /api/v1/bookings              - List all bookings (Admin)\nGET  /api/v1/bookings/my-bookings  - Get user bookings\nGET  /api/v1/bookings/:id          - Get booking by ID\nPOST /api/v1/bookings              - Create booking\nPUT  /api/v1/bookings/:id/cancel   - Cancel booking\n```\n\n## 🔐 Security Features\n\n1. **JWT Authentication**\n   - Access tokens (15 minutes)\n   - Refresh tokens (7 days)\n   - Token blacklisting with Redis\n\n2. **Password Security**\n   - Bcrypt hashing (10 rounds)\n   - Password complexity requirements\n   - Secure password storage\n\n3. **Rate Limiting**\n   - 10 requests per minute per IP\n   - Configurable throttle settings\n\n4. **Input Validation**\n   - Class-validator for DTO validation\n   - Whitelist and sanitization\n   - Type transformation\n\n5. **CORS \u0026 Helmet**\n   - Cross-origin resource sharing\n   - Security headers\n   - XSS protection\n\n## 🔄 Dependency Inversion Examples\n\n### Switching Storage Provider\n\nThe storage module uses dependency inversion, making it easy to switch providers:\n\n```typescript\n// Using S3\nStorageModule.forRoot({\n  useClass: S3StorageProvider,\n});\n\n// Switching to Google Cloud Storage\nStorageModule.forRoot({\n  useClass: GCSStorageProvider,\n});\n\n// Using custom provider\nStorageModule.forRoot({\n  useFactory: () =\u003e new CustomStorageProvider(),\n});\n```\n\n### Switching Message Broker\n\nSimilarly, you can switch from RabbitMQ to any other message broker:\n\n```typescript\n// Using RabbitMQ\nMessageBrokerModule.forRoot({\n  useClass: RabbitMQProvider,\n});\n\n// Switching to Apache Kafka\nMessageBrokerModule.forRoot({\n  useClass: KafkaProvider,\n});\n```\n\n## 🧪 Testing\n\n```bash\n# Unit tests\nnpm run test\n\n# E2E tests\nnpm run test:e2e\n\n# Test coverage\nnpm run test:cov\n```\n\n## 📊 Database Migrations\n\nThe system uses a \"database-per-service\" architecture. Each service has its own PostgreSQL database and migration folder.\n\n### 🔑 Auth Service (`auth_db`)\n```bash\n# Generate migration from schema changes\nnpm run migration:generate:auth -- apps/auth-service/src/migrations/MigrationName\n\n# Create empty migration\nnpm run migration:create:auth -- apps/auth-service/src/migrations/MigrationName\n\n# Run migrations\nnpm run migration:run:auth\n\n# Revert migration\nnpm run migration:revert:auth\n```\n\n### ✈️ Flight Service (`flight_db`)\n\n```bash\ndocker exec -it flight-booking-postgres psql -U postgres -d postgres -c \"CREATE DATABASE booking_db;\"\n# Generate migration from schema changes\nnpm run migration:generate:flight -- apps/flight-service/src/migrations/MigrationName\n\n# Create empty migration\nnpm run migration:create:flight -- apps/flight-service/src/migrations/MigrationName\n\n# Run migrations\nnpm run migration:run:flight\n\n# Revert migration\nnpm run migration:revert:flight\n```\n\n### 📅 Booking Service (`booking_db`)\n```bash\n# Generate migration from schema changes\nnpm run migration:generate:booking -- apps/booking-service/src/migrations/MigrationName\n\n# Create empty migration\nnpm run migration:create:booking -- apps/booking-service/src/migrations/MigrationName\n\n# Run migrations\nnpm run migration:run:booking\n\n# Revert migration\nnpm run migration:revert:booking\n```\n\n\u003e [!IMPORTANT]\n\u003e When running `generate` or `create` commands, ensure you provide the full path including the folder (e.g., `apps/service-name/src/migrations/Name`) so TypeORM places the file in the correct location.\n\n\u003e [!TIP]\n\u003e **Running migrations from your host machine:**\n\u003e The `.env` files point to `DB_HOST=postgres` for Docker networking. When running migrations from your terminal (host machine), you may need to override the host:\n\u003e ```bash\n\u003e DB_HOST=localhost npm run migration:run:flight\n\u003e ```\n\n## 🔧 Configuration\n\n### Environment Variables\n\n| Variable | Description | Default |\n|----------|-------------|---------|\n| **Application** |\n| NODE_ENV | Environment | development |\n| PORT | Service port | 3000-3004 |\n| **Database** |\n| DB_HOST | PostgreSQL host | postgres (Docker) / localhost |\n| DB_PORT | PostgreSQL port | 5432 |\n| DB_USERNAME | Database user | postgres |\n| DB_PASSWORD | Database password | postgres |\n| DB_NAME | Database name | auth_db/flight_db/booking_db |\n| **Redis** |\n| REDIS_HOST | Redis host | redis (Docker) / localhost |\n| REDIS_PORT | Redis port | 6379 |\n| **RabbitMQ** |\n| RABBITMQ_URL | RabbitMQ URL | amqp://admin:admin@rabbitmq:5672 |\n| **Booking/Payment** |\n| PAYMENT_REQUIRED | If false, booking auto-completes with mock payment. If unset, development defaults to local mock and production defaults to real payment-service. | false in local dev |\n| PAYMENT_QUEUE | RMQ queue name for payment-service RPC | payment_queue |\n| **JWT** |\n| JWT_ACCESS_SECRET | JWT access secret | (required) |\n| JWT_REFRESH_SECRET | JWT refresh secret | (required) |\n| JWT_ACCESS_EXPIRATION | Access token expiry | 15m |\n| JWT_REFRESH_EXPIRATION | Refresh token expiry | 7d |\n| **AWS S3** |\n| AWS_REGION | AWS region | us-east-1 |\n| AWS_ACCESS_KEY_ID | AWS access key | test (LocalStack) |\n| AWS_SECRET_ACCESS_KEY | AWS secret key | test (LocalStack) |\n| AWS_S3_BUCKET | S3 bucket name | flight-booking-bucket |\n| AWS_ENDPOINT | S3 endpoint | http://localstack:4566 |\n| **Observability** |\n| OTEL_EXPORTER_OTLP_ENDPOINT | OpenTelemetry endpoint | http://tempo:4318/v1/traces |\n| **Rate Limiting** |\n| THROTTLE_TTL | Rate limit window (seconds) | 60 |\n| THROTTLE_LIMIT | Max requests per window | 10 |\n| **CORS** |\n| CORS_ORIGIN | Allowed origins | http://localhost:3000 |\n\n## 🏗️ Project Structure\n\n```\nflight-booking/\n├── apps/\n│   ├── api-gateway/              # HTTP Gateway (Port 3000)\n│   │   ├── src/\n│   │   │   ├── controllers/      # Route controllers\n│   │   │   ├── guards/           # JWT auth guards\n│   │   │   └── main.ts           # Bootstrap\n│   │   ├── Dockerfile\n│   │   └── .env\n│   ├── auth-service/             # Authentication (Port 3001)\n│   │   ├── src/\n│   │   │   ├── entities/         # User entity\n│   │   │   ├── services/         # Auth logic\n│   │   │   ├── strategies/       # Passport strategies\n│   │   │   └── migrations/       # Database migrations\n│   │   └── .env\n│   ├── flight-service/           # Flight management (Port 3002)\n│   │   ├── src/\n│   │   │   ├── entities/         # Flight, Airport, Seat entities\n│   │   │   ├── services/         # Flight CRUD, search\n│   │   │   └── migrations/       # Database migrations\n│   │   └── .env\n│   ├── booking-service/          # Booking management (Port 3003)\n│   │   ├── src/\n│   │   │   ├── entities/         # Booking, Payment entities\n│   │   │   ├── services/         # Booking logic, seat locking\n│   │   │   └── migrations/       # Database migrations\n│   │   └── .env\n│   └── notification-service/     # Notifications (Port 3004)\n│       ├── src/\n│       │   ├── services/         # Email, SMS services\n│       │   └── listeners/        # Event listeners\n│       └── .env\n├── libs/\n│   ├── common/                   # Shared utilities\n│   │   ├── decorators/           # @User, @Roles, @Public\n│   │   ├── dto/                  # Shared DTOs\n│   │   ├── enums/                # Common enums\n│   │   ├── filters/              # Global exception filter\n│   │   ├── guards/               # Auth, role guards\n│   │   ├── health/               # Health check indicators\n│   │   ├── interceptors/         # Logging, metrics, response wrapping\n│   │   ├── middleware/           # Correlation ID middleware\n│   │   └── services/             # Shared business logic\n│   ├── database/                 # TypeORM configuration\n│   │   └── data-sources/         # Per-service data sources\n│   ├── message-broker/           # RabbitMQ abstraction\n│   ├── storage/                  # S3/LocalStack abstraction\n│   ├── rate-limiter/             # Custom rate limiting\n│   ├── seat-lock/                # Distributed seat locking\n│   └── telemetry/                # OpenTelemetry integration\n├── docker-compose.yml            # Docker orchestration\n├── tempo.yaml                    # Tempo configuration\n├── init-db.sql                   # Database initialization\n├── .env                          # Environment variables\n├── nest-cli.json                 # NestJS CLI config\n├── tsconfig.json                 # TypeScript config\n└── package.json                  # Dependencies \u0026 scripts\n```\n\n## 🚦 Service Health Checks\n\nEach service exposes health check endpoints:\n\n```\nGET /health\n```\n\n## 📊 Observability \u0026 Monitoring\n\n### Distributed Tracing\n\nThe system uses **OpenTelemetry** for distributed tracing with **Tempo** as the backend and **Jaeger/Grafana** for visualization.\n\n**How it works:**\n1. Each request gets a unique **Correlation ID** via middleware\n2. OpenTelemetry automatically instruments HTTP requests, database queries, and RabbitMQ messages\n3. Traces are exported to Tempo via OTLP (OpenTelemetry Protocol)\n4. View traces in Jaeger UI at `http://localhost:16686`\n\n**Viewing Traces:**\n```bash\n# Access Jaeger UI\nopen http://localhost:16686\n\n# Access Grafana (configure Tempo data source)\nopen http://localhost:3005\n```\n\n### Correlation ID Tracking\n\nEvery request is assigned a correlation ID that flows through:\n- HTTP requests (via `X-Correlation-ID` header)\n- RabbitMQ messages (via message properties)\n- Database queries (via logging context)\n- Error responses (included in error payload)\n\n**Example:**\n```bash\ncurl -H \"X-Correlation-ID: my-custom-id\" http://localhost:3000/api/v1/flights\n```\n\n### Structured Logging\n\n- **Winston** for structured JSON logging\n- **Daily rotate files** for log management\n- **Correlation IDs** in every log entry\n- **Log levels:** error, warn, info, debug\n\n**Log format:**\n```json\n{\n  \"timestamp\": \"2026-02-15T23:46:56.000Z\",\n  \"level\": \"info\",\n  \"correlationId\": \"abc-123-def\",\n  \"service\": \"booking-service\",\n  \"message\": \"Booking created successfully\",\n  \"context\": { \"bookingId\": \"uuid\" }\n}\n```\n\n### Health Checks\n\nAll services expose health check endpoints:\n\n```bash\n# API Gateway\nGET http://localhost:3000/health\n\n# Individual services\nGET http://localhost:3001/health  # Auth\nGET http://localhost:3002/health  # Flight\nGET http://localhost:3003/health  # Booking\nGET http://localhost:3004/health  # Notification\n```\n\n**Health indicators:**\n- Database connectivity\n- Redis connectivity\n- RabbitMQ connectivity\n- Memory usage\n- Disk space\n\n### Metrics Collection\n\nCustom metrics interceptor tracks:\n- Request duration\n- Response status codes\n- Error rates\n- RPC call latency\n\n## 🔒 Advanced Features Deep Dive\n\n### Seat Locking for Concurrent Bookings\n\nThe `@app/seat-lock` library prevents double-booking using Redis distributed locks:\n\n**How it works:**\n1. User selects seats → System acquires Redis lock\n2. Lock held for 10 minutes (configurable)\n3. Booking completed → Lock released\n4. Lock expires → Seats become available again\n\n**Implementation:**\n```typescript\n// Automatically handled in booking service\nawait this.seatLockService.lockSeats(flightId, seatNumbers);\ntry {\n  await this.createBooking(...);\n} finally {\n  await this.seatLockService.unlockSeats(flightId, seatNumbers);\n}\n```\n\n### Idempotency Support\n\nCritical operations (bookings, payments) support idempotency keys:\n\n```bash\nPOST /api/v1/bookings\nHeaders:\n  X-Idempotency-Key: unique-key-123\n  \n# Duplicate request with same key returns original response\n```\n\n### Global Exception Handling\n\nStandardized error responses across all services:\n\n```json\n{\n  \"statusCode\": 400,\n  \"message\": \"Validation failed\",\n  \"error\": \"Bad Request\",\n  \"correlationId\": \"abc-123-def\",\n  \"timestamp\": \"2026-02-15T23:46:56.000Z\",\n  \"path\": \"/api/v1/bookings\",\n  \"details\": []\n}\n```\n\n## 🐛 Troubleshooting\n\n### Port Conflicts\n\n**Problem:** `Bind for 0.0.0.0:4317 failed: port is already allocated`\n\n**Solution:**\n```bash\n# Find process using the port\nlsof -i :4317\n\n# Kill the process\nkill -9 \u003cPID\u003e\n\n# Or change port in docker-compose.yml\n```\n\n### Migration Issues\n\n**Problem:** `QueryFailedError: relation already exists`\n\n**Solution:** All migrations are idempotent. Safe to re-run:\n```bash\nnpm run migration:run:booking\n```\n\n### Database Connection Errors\n\n**Problem:** `ECONNREFUSED` when connecting to PostgreSQL\n\n**Solution:**\n```bash\n# From host machine, use localhost\nDB_HOST=localhost npm run migration:run:flight\n\n# From Docker, use service name\nDB_HOST=postgres npm run start:flight\n```\n\n### RabbitMQ Connection Issues\n\n**Problem:** Services can't connect to RabbitMQ\n\n**Solution:**\n```bash\n# Check RabbitMQ is running\ndocker-compose ps rabbitmq\n\n# View RabbitMQ logs\ndocker-compose logs rabbitmq\n\n# Restart RabbitMQ\ndocker-compose restart rabbitmq\n```\n\n### Seat Locking Issues\n\n**Problem:** Seats remain locked after failed booking\n\n**Solution:** Locks auto-expire after 10 minutes, or manually clear:\n```bash\n# Connect to Redis\ndocker exec -it flight-booking-redis redis-cli\n\n# List all locks\nKEYS seat:lock:*\n\n# Delete specific lock\nDEL seat:lock:flight-123:A1\n```\n\n### Viewing Logs with Correlation IDs\n\n```bash\n# Follow logs for a specific service\ndocker-compose logs -f booking-service\n\n# Search logs by correlation ID\ndocker-compose logs | grep \"abc-123-def\"\n```\n\n## 💻 Development Workflow\n\n### Local Development (Without Docker)\n\n1. **Start infrastructure services:**\n```bash\ndocker-compose up -d postgres redis rabbitmq localstack\n```\n\n2. **Setup LocalStack S3:**\n```bash\nnpm run setup:localstack\n```\n\n3. **Run migrations:**\n```bash\nDB_HOST=localhost npm run migration:run:auth\nDB_HOST=localhost npm run migration:run:flight\nDB_HOST=localhost npm run migration:run:booking\n```\n\n4. **Start services:**\n```bash\n# All services\nnpm run start:all\n\n# Or individually\nnpm run start:api-gateway\nnpm run start:auth\nnpm run start:flight\nnpm run start:booking\nnpm run start:notification\nnpm run start:payment\n```\n\n#### Running locally without `payment-service`\n\nSet this in your local `apps/booking-service/.env` if you want to skip `payment-service`:\n\n```bash\nPAYMENT_REQUIRED=false\n```\n\nStart `booking-service` normally and booking creation will auto-complete after the saga finishes.\n\nIf you want to switch back to the real payment-service path, set:\n\n```bash\nPAYMENT_REQUIRED=true\n```\n\nand start `payment-service` as well.\n\n### Docker Development\n\n```bash\n# Build and start all services\ndocker-compose up --build\n\n# Start in detached mode\ndocker-compose up -d\n\n# View logs\ndocker-compose logs -f [service-name]\n\n# Restart a service\ndocker-compose restart booking-service\n\n# Stop all services\ndocker-compose down\n\n# Remove volumes (clean slate)\ndocker-compose down -v\n```\n\n### Debugging with Distributed Tracing\n\n1. Make a request and note the correlation ID:\n```bash\ncurl -v http://localhost:3000/api/v1/bookings\n# Response header: X-Correlation-ID: abc-123-def\n```\n\n2. Search for the trace in Jaeger:\n   - Open `http://localhost:16686`\n   - Select service: `api-gateway`\n   - Search by correlation ID or time range\n   - View full request flow across services\n\n### Testing Microservice Communication\n\n```bash\n# Test RabbitMQ message flow\n# 1. Create a booking via API Gateway\ncurl -X POST http://localhost:3000/api/v1/bookings \\\n  -H \"Authorization: Bearer \u003ctoken\u003e\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{...}'\n\n# 2. Check notification service logs\ndocker-compose logs notification-service | grep \"booking.created\"\n\n# 3. Verify in RabbitMQ UI\nopen http://localhost:15672\n```\n\n### Creating Migrations\n\n```bash\n# Generate migration from entity changes\nnpm run migration:generate:booking -- apps/booking-service/src/migrations/AddPaymentStatus\n\n# Create empty migration\nnpm run migration:create:booking -- apps/booking-service/src/migrations/CustomMigration\n\n# Run migrations\nnpm run migration:run:booking\n\n# Revert last migration\nnpm run migration:revert:booking\n```\n\n### Best Practices\n\n1. **Always use correlation IDs** when debugging cross-service issues\n2. **Check health endpoints** before debugging service issues\n3. **Use Jaeger UI** to visualize request flows\n4. **Monitor RabbitMQ queues** for message backlogs\n5. **Check Redis** for lock issues in concurrent scenarios\n6. **Run migrations** before starting services after entity changes\n7. **Use idempotency keys** for testing booking operations\n\n## 📈 Performance \u0026 Scalability\n\n### Caching Strategy\n\n- **Flight search results** cached in Redis (5 minutes TTL)\n- **User sessions** stored in Redis\n- **Rate limiting** counters in Redis\n- **Seat locks** managed via Redis distributed locks\n\n### Database Optimization\n\n- **Indexes** on frequently queried fields\n- **Connection pooling** for efficient resource usage\n- **Database-per-service** for independent scaling\n- **Read replicas** support (configurable)\n\n### Horizontal Scaling\n\nAll services are stateless and can be scaled horizontally:\n\n```yaml\n# docker-compose.yml\nbooking-service:\n  deploy:\n    replicas: 3\n```\n\n## 🤝 Contributing\n\n1. Fork the repository\n2. Create a feature branch\n3. Commit your changes\n4. Push to the branch\n5. Create a Pull Request\n\n## 📝 License\n\nThis project is licensed under the MIT License.\n\n## 🎯 Roadmap\n\n### Short Term\n- [ ] Email templates with SendGrid\n- [ ] SMS integration with Twilio\n\n### Medium Term\n- [ ] Flight tracking and status updates\n- [ ] Loyalty program integration\n- [ ] Analytics and reporting dashboard\n\n### Long Term\n- [ ] Kubernetes deployment with Helm charts\n- [ ] CI/CD pipeline (GitHub Actions)\n- [ ] Multi-region deployment\n- [ ] Real-time notifications via WebSockets\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsaikatbhuiyan%2Fflight-booking-microservices","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsaikatbhuiyan%2Fflight-booking-microservices","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsaikatbhuiyan%2Fflight-booking-microservices/lists"}