System Architecture - gabrielmaialva33/innkeeper GitHub Wiki

🏗️ System Architecture

Understanding Innkeeper's architectural design and components


📋 Overview

Innkeeper is built using a modern, scalable architecture that supports multi-tenancy, high availability, and enterprise-grade performance. This document provides a comprehensive overview of the system's architecture, design patterns, and technical decisions.

Key Architectural Principles:

  • Multi-tenant by design - Single codebase serving multiple organizations
  • Domain-driven design - Clear separation of business domains
  • Event-driven architecture - Loose coupling through events
  • API-first approach - RESTful APIs with comprehensive documentation
  • Security by default - Built-in security at every layer

🎯 High-Level Architecture

graph TB
    subgraph "Client Layer"
        WEB[Web Application]
        MOBILE[Mobile App]
        API_CLIENT[API Clients]
    end
    
    subgraph "Load Balancer"
        LB[Nginx/HAProxy]
    end
    
    subgraph "Application Layer"
        APP1[App Instance 1]
        APP2[App Instance 2]
        APP3[App Instance N]
    end
    
    subgraph "Service Layer"
        AUTH[Authentication Service]
        HOTEL[Hotel Management]
        RESERVATION[Reservation Service]
        PAYMENT[Payment Service]
        NOTIFICATION[Notification Service]
    end
    
    subgraph "Data Layer"
        DB[(PostgreSQL)]
        REDIS[(Redis Cache)]
        QUEUE[Job Queue]
    end
    
    subgraph "External Services"
        EMAIL[Email Provider]
        SMS[SMS Provider]
        PAYMENT_GW[Payment Gateway]
        STORAGE[File Storage]
    end
    
    WEB --> LB
    MOBILE --> LB
    API_CLIENT --> LB
    
    LB --> APP1
    LB --> APP2
    LB --> APP3
    
    APP1 --> AUTH
    APP1 --> HOTEL
    APP1 --> RESERVATION
    APP1 --> PAYMENT
    APP1 --> NOTIFICATION
    
    AUTH --> DB
    HOTEL --> DB
    RESERVATION --> DB
    PAYMENT --> DB
    NOTIFICATION --> QUEUE
    
    APP1 --> REDIS
    APP2 --> REDIS
    APP3 --> REDIS
    
    NOTIFICATION --> EMAIL
    NOTIFICATION --> SMS
    PAYMENT --> PAYMENT_GW
    APP1 --> STORAGE
Loading

🏢 Multi-Tenant Architecture

Tenant Isolation Strategy

Innkeeper uses a single database, multi-tenant approach with row-level security:

graph LR
    subgraph "Single Application Instance"
        TENANT_A[Organization A]
        TENANT_B[Organization B]
        TENANT_C[Organization C]
    end
    
    subgraph "Shared Database"
        ORGS[(organizations)]
        HOTELS[(hotels)]
        RESERVATIONS[(reservations)]
        GUESTS[(guests)]
    end
    
    TENANT_A --> ORGS
    TENANT_B --> ORGS
    TENANT_C --> ORGS
    
    ORGS --> HOTELS
    ORGS --> RESERVATIONS
    ORGS --> GUESTS
Loading

Tenant Context Flow

sequenceDiagram
    participant Client
    participant Middleware
    participant Controller
    participant Service
    participant Database
    
    Client->>Middleware: Request with tenant info
    Middleware->>Middleware: Extract tenant context
    Middleware->>Controller: Request with tenant context
    Controller->>Service: Business logic with tenant
    Service->>Database: Query with organization_id filter
    Database-->>Service: Tenant-specific data
    Service-->>Controller: Processed data
    Controller-->>Client: Response
Loading

Benefits of This Approach

  • Cost Efficiency: Single infrastructure for all tenants
  • Maintenance: Single codebase and database to maintain
  • Scalability: Easy horizontal scaling
  • Data Isolation: Logical separation with physical security
  • Feature Consistency: All tenants get same features simultaneously

🔧 Technology Stack

Backend Technologies

Component Technology Purpose
Runtime Node.js 20+ JavaScript runtime environment
Framework AdonisJS 6 Full-stack web framework
Language TypeScript Type-safe JavaScript
Database PostgreSQL 15+ Primary data storage
Cache Redis 7+ Session storage and caching
Queue Bull Queue Background job processing
ORM Lucid ORM Database abstraction layer
Validation VineJS Request validation
Authentication AdonisJS Auth User authentication
Authorization Custom RBAC Role-based access control

Frontend Technologies

Component Technology Purpose
Framework React 18+ User interface library
Language TypeScript Type-safe JavaScript
Bundler Vite Fast build tool
Styling Tailwind CSS Utility-first CSS framework
State Management Zustand Lightweight state management
HTTP Client Axios API communication
Forms React Hook Form Form handling
UI Components Headless UI Accessible UI components

Infrastructure & DevOps

Component Technology Purpose
Web Server Nginx Reverse proxy and static files
Process Manager PM2 Node.js process management
Containerization Docker Application containerization
Orchestration Docker Compose Multi-container applications
Monitoring Prometheus + Grafana Metrics and monitoring
Logging Winston + ELK Stack Centralized logging
CI/CD GitHub Actions Automated deployment

📊 Database Architecture

Entity Relationship Overview

erDiagram
    organizations ||--o{ hotels : owns
    organizations ||--o{ users : employs
    organizations ||--o{ guests : manages
    
    hotels ||--o{ room_types : has
    hotels ||--o{ rooms : contains
    hotels ||--o{ reservations : receives
    hotels ||--o{ services : offers
    hotels ||--o{ staff : employs
    
    room_types ||--o{ rooms : defines
    room_types ||--o{ reservations : books
    
    guests ||--o{ reservations : makes
    guests ||--o{ payments : pays
    
    reservations ||--o{ payments : generates
    reservations ||--o{ folios : creates
    reservations ||--o{ reservation_services : includes
    
    users ||--o{ reservations : creates
    users ||--o{ payments : processes
    users ||--o{ audit_logs : generates
    
    roles ||--o{ user_roles : assigns
    permissions ||--o{ role_permissions : grants
Loading

Data Partitioning Strategy

Horizontal Partitioning (Sharding)

  • By Organization: Each organization's data can be logically separated
  • By Date: Historical data can be archived to separate partitions
  • By Geography: Multi-region deployments with data locality

Vertical Partitioning

  • Hot vs Cold Data: Frequently accessed vs archived data
  • Read vs Write: Separate read replicas for reporting
  • Sensitive Data: PII data in separate encrypted tables

🔄 Service Architecture

Domain Services

graph TB
    subgraph "Core Domain Services"
        HOTEL_SVC[Hotel Management Service]
        RESERVATION_SVC[Reservation Service]
        GUEST_SVC[Guest Management Service]
        ROOM_SVC[Room Management Service]
        PAYMENT_SVC[Payment Service]
        STAFF_SVC[Staff Management Service]
    end
    
    subgraph "Supporting Services"
        AUTH_SVC[Authentication Service]
        NOTIFICATION_SVC[Notification Service]
        AUDIT_SVC[Audit Service]
        REPORT_SVC[Reporting Service]
        FILE_SVC[File Management Service]
    end
    
    subgraph "External Integrations"
        EMAIL_SVC[Email Service]
        SMS_SVC[SMS Service]
        PAYMENT_GW[Payment Gateway]
        CHANNEL_MGR[Channel Manager]
    end
    
    RESERVATION_SVC --> HOTEL_SVC
    RESERVATION_SVC --> GUEST_SVC
    RESERVATION_SVC --> ROOM_SVC
    RESERVATION_SVC --> PAYMENT_SVC
    
    PAYMENT_SVC --> PAYMENT_GW
    NOTIFICATION_SVC --> EMAIL_SVC
    NOTIFICATION_SVC --> SMS_SVC
    
    AUTH_SVC --> AUDIT_SVC
    HOTEL_SVC --> AUDIT_SVC
    RESERVATION_SVC --> AUDIT_SVC
Loading

Service Communication Patterns

Synchronous Communication

  • HTTP/REST APIs: For real-time operations
  • Direct Database Access: Within same service boundary
  • Caching Layer: Redis for frequently accessed data

Asynchronous Communication

  • Event Bus: Domain events for loose coupling
  • Job Queues: Background processing
  • Webhooks: External system notifications

🔐 Security Architecture

Authentication & Authorization Flow

sequenceDiagram
    participant User
    participant Frontend
    participant API Gateway
    participant Auth Service
    participant Resource Service
    participant Database
    
    User->>Frontend: Login credentials
    Frontend->>API Gateway: POST /auth/login
    API Gateway->>Auth Service: Validate credentials
    Auth Service->>Database: Check user & permissions
    Database-->>Auth Service: User data & roles
    Auth Service-->>API Gateway: JWT token + refresh token
    API Gateway-->>Frontend: Authentication response
    Frontend-->>User: Login success
    
    User->>Frontend: Access protected resource
    Frontend->>API Gateway: GET /api/resource (with JWT)
    API Gateway->>Auth Service: Validate JWT
    Auth Service-->>API Gateway: Token valid + user context
    API Gateway->>Resource Service: Request with user context
    Resource Service->>Database: Query with tenant filter
    Database-->>Resource Service: Filtered data
    Resource Service-->>API Gateway: Response
    API Gateway-->>Frontend: Protected resource data
Loading

Security Layers

1. Network Security

  • HTTPS/TLS 1.3: All communications encrypted
  • CORS Policy: Controlled cross-origin requests
  • Rate Limiting: DDoS protection and abuse prevention
  • IP Whitelisting: Restricted admin access

2. Application Security

  • Input Validation: All inputs validated and sanitized
  • SQL Injection Prevention: Parameterized queries only
  • XSS Protection: Content Security Policy headers
  • CSRF Protection: Token-based CSRF prevention

3. Data Security

  • Encryption at Rest: Database encryption
  • Encryption in Transit: TLS for all communications
  • PII Protection: Sensitive data hashing/encryption
  • Audit Logging: Complete audit trail

4. Access Control

  • Role-Based Access Control (RBAC): Granular permissions
  • Multi-Factor Authentication: Optional 2FA/MFA
  • Session Management: Secure session handling
  • Token Expiration: Short-lived access tokens

📈 Scalability Architecture

Horizontal Scaling Strategy

graph TB
    subgraph "Load Balancer Layer"
        LB1[Load Balancer 1]
        LB2[Load Balancer 2]
    end
    
    subgraph "Application Layer"
        APP1[App Instance 1]
        APP2[App Instance 2]
        APP3[App Instance 3]
        APP4[App Instance 4]
    end
    
    subgraph "Database Layer"
        MASTER[(Master DB)]
        REPLICA1[(Read Replica 1)]
        REPLICA2[(Read Replica 2)]
    end
    
    subgraph "Cache Layer"
        REDIS1[(Redis Cluster 1)]
        REDIS2[(Redis Cluster 2)]
        REDIS3[(Redis Cluster 3)]
    end
    
    LB1 --> APP1
    LB1 --> APP2
    LB2 --> APP3
    LB2 --> APP4
    
    APP1 --> MASTER
    APP2 --> REPLICA1
    APP3 --> REPLICA2
    APP4 --> MASTER
    
    APP1 --> REDIS1
    APP2 --> REDIS2
    APP3 --> REDIS3
    APP4 --> REDIS1
Loading

Performance Optimization Strategies

1. Database Optimization

  • Connection Pooling: Efficient database connections
  • Query Optimization: Indexed queries and query planning
  • Read Replicas: Separate read and write operations
  • Caching: Redis for frequently accessed data

2. Application Optimization

  • Code Splitting: Lazy loading of application modules
  • Asset Optimization: Minification and compression
  • CDN Integration: Static asset delivery
  • HTTP/2: Multiplexed connections

3. Infrastructure Optimization

  • Auto Scaling: Dynamic resource allocation
  • Load Balancing: Traffic distribution
  • Geographic Distribution: Multi-region deployment
  • Container Orchestration: Efficient resource utilization

🔄 Event-Driven Architecture

Domain Events

graph LR
    subgraph "Event Producers"
        RESERVATION[Reservation Service]
        PAYMENT[Payment Service]
        GUEST[Guest Service]
        ROOM[Room Service]
    end
    
    subgraph "Event Bus"
        EVENTS[(Event Store)]
    end
    
    subgraph "Event Consumers"
        NOTIFICATION[Notification Service]
        AUDIT[Audit Service]
        REPORTING[Reporting Service]
        INTEGRATION[External Integrations]
    end
    
    RESERVATION --> EVENTS
    PAYMENT --> EVENTS
    GUEST --> EVENTS
    ROOM --> EVENTS
    
    EVENTS --> NOTIFICATION
    EVENTS --> AUDIT
    EVENTS --> REPORTING
    EVENTS --> INTEGRATION
Loading

Event Types

Reservation Events

  • ReservationCreated
  • ReservationModified
  • ReservationCancelled
  • CheckInCompleted
  • CheckOutCompleted

Payment Events

  • PaymentProcessed
  • PaymentFailed
  • RefundIssued
  • InvoiceGenerated

Guest Events

  • GuestRegistered
  • GuestProfileUpdated
  • LoyaltyPointsEarned

Room Events

  • RoomStatusChanged
  • MaintenanceScheduled
  • CleaningCompleted

🔍 Monitoring & Observability

Monitoring Stack

graph TB
    subgraph "Application"
        APP[Innkeeper App]
        METRICS[Metrics Collector]
        LOGS[Log Aggregator]
    end
    
    subgraph "Monitoring Infrastructure"
        PROMETHEUS[Prometheus]
        GRAFANA[Grafana]
        ELASTICSEARCH[Elasticsearch]
        KIBANA[Kibana]
        ALERTMANAGER[Alert Manager]
    end
    
    subgraph "Notification Channels"
        EMAIL[Email Alerts]
        SLACK[Slack Notifications]
        PAGERDUTY[PagerDuty]
    end
    
    APP --> METRICS
    APP --> LOGS
    
    METRICS --> PROMETHEUS
    LOGS --> ELASTICSEARCH
    
    PROMETHEUS --> GRAFANA
    PROMETHEUS --> ALERTMANAGER
    ELASTICSEARCH --> KIBANA
    
    ALERTMANAGER --> EMAIL
    ALERTMANAGER --> SLACK
    ALERTMANAGER --> PAGERDUTY
Loading

Key Metrics

Application Metrics

  • Response Time: API endpoint performance
  • Throughput: Requests per second
  • Error Rate: 4xx/5xx error percentages
  • Availability: Uptime and health checks

Business Metrics

  • Reservation Volume: Bookings per time period
  • Revenue Metrics: Daily/monthly revenue tracking
  • Occupancy Rates: Room utilization statistics
  • Guest Satisfaction: Review scores and feedback

Infrastructure Metrics

  • CPU Usage: Server resource utilization
  • Memory Usage: RAM consumption patterns
  • Disk I/O: Storage performance metrics
  • Network Traffic: Bandwidth utilization

🚀 Deployment Architecture

Container Strategy

# Multi-stage build for optimization
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production

FROM node:20-alpine AS runtime
WORKDIR /app
COPY --from=builder /app/node_modules ./node_modules
COPY . .
EXPOSE 3333
CMD ["node", "bin/server.js"]

Orchestration with Docker Compose

version: '3.8'
services:
  app:
    build: .
    ports:
      - "3333:3333"
    environment:
      - NODE_ENV=production
    depends_on:
      - database
      - redis

  database:
    image: postgres:15
    environment:
      POSTGRES_DB: innkeeper
      POSTGRES_USER: innkeeper
      POSTGRES_PASSWORD: ${DB_PASSWORD}
    volumes:
      - postgres_data:/var/lib/postgresql/data

  redis:
    image: redis:7-alpine
    volumes:
      - redis_data:/data

  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
    depends_on:
      - app

volumes:
  postgres_data:
  redis_data:

🔧 Development Architecture

Development Workflow

graph LR
    DEV[Developer] --> LOCAL[Local Development]
    LOCAL --> GIT[Git Repository]
    GIT --> CI[CI Pipeline]
    CI --> TEST[Automated Tests]
    TEST --> BUILD[Build & Package]
    BUILD --> STAGING[Staging Environment]
    STAGING --> PROD[Production Deployment]
    
    subgraph "Quality Gates"
        LINT[Code Linting]
        SECURITY[Security Scan]
        COVERAGE[Test Coverage]
    end
    
    CI --> LINT
    CI --> SECURITY
    CI --> COVERAGE
Loading

Environment Strategy

Local Development

  • Hot Reloading: Instant code changes
  • Debug Mode: Detailed error messages
  • Mock Services: External service simulation
  • Seed Data: Consistent test data

Staging Environment

  • Production Mirror: Identical to production
  • Integration Testing: End-to-end testing
  • Performance Testing: Load and stress testing
  • Security Testing: Vulnerability scanning

Production Environment

  • High Availability: Multiple instances
  • Monitoring: Comprehensive observability
  • Backup Strategy: Automated backups
  • Disaster Recovery: Failover procedures

📚 Architecture Decisions

Key Design Decisions

1. Multi-Tenancy Approach

Decision: Single database with row-level security Rationale:

  • Cost-effective for SaaS model
  • Easier maintenance and updates
  • Better resource utilization
  • Simplified backup and disaster recovery

2. Technology Stack

Decision: Node.js + TypeScript + AdonisJS Rationale:

  • Rapid development and prototyping
  • Strong typing with TypeScript
  • Mature ecosystem and community
  • Excellent performance for I/O operations

3. Database Choice

Decision: PostgreSQL as primary database Rationale:

  • ACID compliance for financial data
  • Advanced features (JSON, full-text search)
  • Excellent performance and scalability
  • Strong community and tooling

4. Caching Strategy

Decision: Redis for caching and sessions Rationale:

  • High performance in-memory storage
  • Rich data structures
  • Pub/sub capabilities for real-time features
  • Excellent Node.js integration

🔮 Future Architecture Considerations

Microservices Migration Path

As the system grows, consider migrating to microservices:

graph TB
    subgraph "Current Monolith"
        MONOLITH[Innkeeper Monolith]
    end
    
    subgraph "Future Microservices"
        AUTH_MS[Auth Microservice]
        HOTEL_MS[Hotel Microservice]
        RESERVATION_MS[Reservation Microservice]
        PAYMENT_MS[Payment Microservice]
        NOTIFICATION_MS[Notification Microservice]
    end
    
    subgraph "Service Mesh"
        ISTIO[Istio Service Mesh]
    end
    
    MONOLITH -.-> AUTH_MS
    MONOLITH -.-> HOTEL_MS
    MONOLITH -.-> RESERVATION_MS
    MONOLITH -.-> PAYMENT_MS
    MONOLITH -.-> NOTIFICATION_MS
    
    AUTH_MS --> ISTIO
    HOTEL_MS --> ISTIO
    RESERVATION_MS --> ISTIO
    PAYMENT_MS --> ISTIO
    NOTIFICATION_MS --> ISTIO
Loading

Cloud-Native Evolution

  • Kubernetes: Container orchestration
  • Service Mesh: Inter-service communication
  • Serverless Functions: Event-driven processing
  • Managed Services: Database and cache as a service

📚 Related Documentation


🆘 Need Help?


← Previous: Configuration | Wiki Home | Next: Database Schema →

⚠️ **GitHub.com Fallback** ⚠️