Configuration - gabrielmaialva33/innkeeper GitHub Wiki

⚙️ Configuration Guide

Customize your Innkeeper installation for optimal performance


📋 Overview

This guide covers all configuration options available in Innkeeper, from basic environment variables to advanced system settings. Proper configuration ensures optimal performance, security, and functionality for your hotel management system.

Prerequisites: Complete the Installation Guide and Quick Start first.


🔧 Environment Configuration

Core Environment Variables

Create or update your .env file with these essential settings:

# Application Settings
NODE_ENV=production
PORT=3333
HOST=0.0.0.0
LOG_LEVEL=info
APP_KEY=your-32-character-secret-key

# Application URLs
APP_URL=https://yourdomain.com
FRONTEND_URL=https://yourdomain.com
API_URL=https://yourdomain.com/api

# Database Configuration
DB_CONNECTION=pg
DB_HOST=localhost
DB_PORT=5432
DB_USER=innkeeper
DB_PASSWORD=your-secure-password
DB_DATABASE=innkeeper

# Redis Configuration (for sessions and cache)
REDIS_CONNECTION=local
REDIS_HOST=127.0.0.1
REDIS_PORT=6379
REDIS_PASSWORD=your-redis-password

# Email Configuration
MAIL_MAILER=smtp
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
[email protected]
SMTP_PASSWORD=your-app-password
[email protected]
MAIL_FROM_NAME="Innkeeper System"

# File Storage
DRIVE_DISK=local
# For S3 storage:
# DRIVE_DISK=s3
# S3_KEY=your-s3-access-key
# S3_SECRET=your-s3-secret-key
# S3_BUCKET=your-bucket-name
# S3_REGION=us-east-1

# Security Settings
SESSION_DRIVER=redis
HASH_DRIVER=bcrypt
ENCRYPTION_CIPHER=aes-256-cbc

# Rate Limiting
RATE_LIMITER_STORE=redis
RATE_LIMIT_REQUESTS=100
RATE_LIMIT_DURATION=60

# Logging
LOG_DRIVER=file
LOG_FILE_PATH=./logs/app.log
LOG_MAX_FILES=10
LOG_MAX_SIZE=10mb

Development vs Production

Development Environment

NODE_ENV=development
LOG_LEVEL=debug
APP_URL=http://localhost:3333
FRONTEND_URL=http://localhost:3000

# Enable debug features
DEBUG=true
VITE_DEV_SERVER_URL=http://localhost:5173

Production Environment

NODE_ENV=production
LOG_LEVEL=warn
APP_URL=https://yourdomain.com
FRONTEND_URL=https://yourdomain.com

# Security enhancements
SECURE_COOKIES=true
TRUST_PROXY=true
FORCE_HTTPS=true

🗄️ Database Configuration

PostgreSQL Optimization

Connection Pool Settings

// config/database.ts
export default defineConfig({
  connection: Env.get('DB_CONNECTION'),
  connections: {
    pg: {
      client: 'pg',
      connection: {
        host: Env.get('DB_HOST'),
        port: Env.get('DB_PORT'),
        user: Env.get('DB_USER'),
        password: Env.get('DB_PASSWORD'),
        database: Env.get('DB_DATABASE'),
      },
      pool: {
        min: 2,
        max: 20,
        acquireTimeoutMillis: 60000,
        createTimeoutMillis: 30000,
        destroyTimeoutMillis: 5000,
        idleTimeoutMillis: 30000,
        reapIntervalMillis: 1000,
        createRetryIntervalMillis: 200,
      },
      migrations: {
        naturalSort: true,
        paths: ['./database/migrations'],
      },
      seeders: {
        paths: ['./database/seeders'],
      },
    },
  },
})

Database Performance Tuning

-- PostgreSQL configuration recommendations
-- Add to postgresql.conf

-- Memory Settings
shared_buffers = 256MB;
effective_cache_size = 1GB;
work_mem = 4MB;
maintenance_work_mem = 64MB;

-- Connection Settings
max_connections = 100;
shared_preload_libraries = 'pg_stat_statements';

-- Logging
log_statement = 'mod';
log_min_duration_statement = 1000;
log_checkpoints = on;
log_connections = on;
log_disconnections = on;

Database Indexes

Ensure these indexes exist for optimal performance:

-- Reservations performance indexes
CREATE INDEX CONCURRENTLY idx_reservations_dates ON reservations (check_in_date, check_out_date);
CREATE INDEX CONCURRENTLY idx_reservations_status ON reservations (status);
CREATE INDEX CONCURRENTLY idx_reservations_hotel ON reservations (hotel_id);
CREATE INDEX CONCURRENTLY idx_reservations_guest ON reservations (guest_id);

-- Rooms performance indexes
CREATE INDEX CONCURRENTLY idx_rooms_hotel_status ON rooms (hotel_id, status);
CREATE INDEX CONCURRENTLY idx_rooms_type ON rooms (room_type_id);

-- Guests search indexes
CREATE INDEX CONCURRENTLY idx_guests_email ON guests (email);
CREATE INDEX CONCURRENTLY idx_guests_phone ON guests (phone);
CREATE INDEX CONCURRENTLY idx_guests_name ON guests (first_name, last_name);

-- Audit logs indexes
CREATE INDEX CONCURRENTLY idx_audit_logs_user ON audit_logs (user_id);
CREATE INDEX CONCURRENTLY idx_audit_logs_resource ON audit_logs (resource, resource_id);
CREATE INDEX CONCURRENTLY idx_audit_logs_created ON audit_logs (created_at);

📧 Email Configuration

SMTP Providers

Gmail Configuration

MAIL_MAILER=smtp
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
[email protected]
SMTP_PASSWORD=your-app-password
SMTP_ENCRYPTION=tls

SendGrid Configuration

MAIL_MAILER=smtp
SMTP_HOST=smtp.sendgrid.net
SMTP_PORT=587
SMTP_USERNAME=apikey
SMTP_PASSWORD=your-sendgrid-api-key
SMTP_ENCRYPTION=tls

Amazon SES Configuration

MAIL_MAILER=ses
AWS_ACCESS_KEY_ID=your-access-key
AWS_SECRET_ACCESS_KEY=your-secret-key
AWS_DEFAULT_REGION=us-east-1
SES_VERSION=2010-12-01

Email Templates

Configure email templates in config/mail.ts:

export default defineConfig({
  default: Env.get('MAIL_MAILER'),

  mailers: {
    smtp: {
      driver: 'smtp',
      host: Env.get('SMTP_HOST'),
      port: Env.get('SMTP_PORT'),
      auth: {
        user: Env.get('SMTP_USERNAME'),
        pass: Env.get('SMTP_PASSWORD'),
      },
    },
  },

  // Email templates configuration
  templates: {
    reservation_confirmation: {
      subject: 'Booking Confirmation - {{hotel_name}}',
      template: 'emails/reservation_confirmation',
    },
    check_in_instructions: {
      subject: 'Check-in Instructions - {{hotel_name}}',
      template: 'emails/check_in_instructions',
    },
    payment_receipt: {
      subject: 'Payment Receipt - {{confirmation_number}}',
      template: 'emails/payment_receipt',
    },
  },
})

🔒 Security Configuration

Authentication Settings

// config/auth.ts
export default defineConfig({
  default: 'web',

  guards: {
    web: {
      driver: 'session',
      provider: 'users',
    },
    api: {
      driver: 'access_tokens',
      provider: 'users',
    },
  },

  providers: {
    users: {
      driver: 'lucid',
      identifierKey: 'id',
      uids: ['email', 'username'],
      model: () => import('#models/user'),
    },
  },

  // Session configuration
  session: {
    cookieName: 'innkeeper_session',
    clearWithBrowser: false,
    age: '2h',
    sameSite: 'lax',
    secure: Env.get('NODE_ENV') === 'production',
  },

  // Token configuration
  tokens: {
    default_expiry: '30d',
    refresh_token_expiry: '90d',
  },
})

CORS Configuration

// config/cors.ts
export default defineConfig({
  enabled: true,
  origin: [
    'http://localhost:3000',
    'http://localhost:3333',
    'https://yourdomain.com',
  ],
  methods: ['GET', 'HEAD', 'POST', 'PUT', 'DELETE'],
  headers: true,
  exposeHeaders: [
    'cache-control',
    'content-language',
    'content-type',
    'expires',
    'last-modified',
    'pragma',
  ],
  credentials: true,
  maxAge: 90,
})

Rate Limiting

// config/limiter.ts
export default defineConfig({
  default: 'redis',

  stores: {
    redis: {
      connectionName: 'main',
    },
  },

  // Rate limiting rules
  rules: {
    api: {
      requests: 100,
      duration: '1m',
    },
    auth: {
      requests: 5,
      duration: '15m',
    },
    reservation: {
      requests: 10,
      duration: '1m',
    },
  },
})

📁 File Storage Configuration

Local Storage

// config/drive.ts
export default defineConfig({
  default: 'local',

  disks: {
    local: {
      driver: 'fs',
      root: './uploads',
      serveFiles: true,
      basePath: '/uploads',
    },
  },
})

Amazon S3 Storage

# Environment variables
DRIVE_DISK=s3
S3_KEY=your-access-key
S3_SECRET=your-secret-key
S3_BUCKET=innkeeper-files
S3_REGION=us-east-1
S3_ENDPOINT=https://s3.amazonaws.com
// config/drive.ts - S3 configuration
export default defineConfig({
  default: 's3',

  disks: {
    s3: {
      driver: 's3',
      key: Env.get('S3_KEY'),
      secret: Env.get('S3_SECRET'),
      region: Env.get('S3_REGION'),
      bucket: Env.get('S3_BUCKET'),
      endpoint: Env.get('S3_ENDPOINT'),
      // Optional: Custom domain for file URLs
      cdnUrl: 'https://cdn.yourdomain.com',
    },
  },
})

File Upload Limits

// config/bodyparser.ts
export default defineConfig({
  whitelistedMethods: ['POST', 'PUT', 'PATCH', 'DELETE'],

  json: {
    encoding: 'utf8',
    limit: '1mb',
    strict: true,
    types: ['application/json', 'application/json-patch+json'],
  },

  form: {
    encoding: 'utf8',
    limit: '1mb',
    queryString: {},
    types: ['application/x-www-form-urlencoded'],
  },

  raw: {
    encoding: 'utf8',
    limit: '1mb',
    types: ['text/*'],
  },

  multipart: {
    autoProcess: true,
    processManually: [],
    encoding: 'utf8',
    maxFields: 1000,
    limit: '20mb',
    types: ['multipart/form-data'],
  },
})

🏨 Hotel-Specific Configuration

Multi-Tenant Settings

// config/tenant.ts
export default defineConfig({
  // Tenant identification strategy
  identification: {
    strategy: 'subdomain', // 'subdomain' | 'domain' | 'header'
    header: 'X-Tenant-ID',
  },

  // Database strategy
  database: {
    strategy: 'single_db', // 'single_db' | 'multi_db'
    tenant_column: 'organization_id',
  },

  // Cache strategy
  cache: {
    prefix_with_tenant: true,
    tenant_separator: ':',
  },

  // File storage strategy
  storage: {
    tenant_folders: true,
    folder_structure: 'organization_id/hotel_id',
  },
})

Business Rules Configuration

// config/business.ts
export default defineConfig({
  reservations: {
    // Advance booking limits
    max_advance_days: 365,
    min_advance_hours: 2,

    // Cancellation policies
    free_cancellation_hours: 24,
    partial_refund_hours: 48,

    // Overbooking settings
    allow_overbooking: false,
    overbooking_percentage: 5,
  },

  rooms: {
    // Housekeeping settings
    cleaning_time_minutes: 30,
    inspection_required: true,
    maintenance_window_hours: 2,
  },

  payments: {
    // Payment processing
    require_deposit: true,
    deposit_percentage: 50,
    payment_timeout_minutes: 15,

    // Supported currencies
    default_currency: 'USD',
    supported_currencies: ['USD', 'EUR', 'GBP', 'BRL'],
  },

  notifications: {
    // Email notifications
    send_confirmation: true,
    send_reminders: true,
    reminder_hours_before: 24,

    // SMS notifications (if enabled)
    sms_enabled: false,
    sms_provider: 'twilio',
  },
})

📊 Monitoring & Logging

Application Logging

// config/logger.ts
export default defineConfig({
  default: 'app',

  loggers: {
    app: {
      enabled: true,
      name: Env.get('APP_NAME'),
      level: Env.get('LOG_LEVEL', 'info'),
      redact: {
        paths: ['password', 'email', 'phone'],
        censor: '***REDACTED***',
      },
    },
  },

  // Log targets
  targets: [
    {
      target: 'pino/file',
      options: {
        destination: './logs/app.log',
      },
      level: 'info',
    },
    {
      target: 'pino-pretty',
      options: {
        colorize: true,
      },
      level: 'debug',
    },
  ],
})

Performance Monitoring

# Environment variables for monitoring
MONITORING_ENABLED=true
METRICS_ENDPOINT=/metrics
HEALTH_CHECK_ENDPOINT=/health

# APM Integration (optional)
APM_SERVICE_NAME=innkeeper
APM_SERVER_URL=https://apm.yourdomain.com
APM_SECRET_TOKEN=your-apm-token

Health Checks

// config/health.ts
export default defineConfig({
  checks: [
    {
      name: 'database',
      checker: 'database',
      timeout: 5000,
    },
    {
      name: 'redis',
      checker: 'redis',
      timeout: 3000,
    },
    {
      name: 'disk_space',
      checker: 'disk_space',
      threshold: '80%',
    },
    {
      name: 'memory',
      checker: 'memory',
      threshold: '90%',
    },
  ],
})

🔄 Backup Configuration

Database Backups

#!/bin/bash
# backup-database.sh

DB_NAME="innkeeper"
DB_USER="innkeeper"
BACKUP_DIR="/var/backups/innkeeper"
DATE=$(date +%Y%m%d_%H%M%S)

# Create backup directory
mkdir -p $BACKUP_DIR

# Create database backup
pg_dump -U $DB_USER -h localhost $DB_NAME | gzip > $BACKUP_DIR/db_backup_$DATE.sql.gz

# Keep only last 7 days of backups
find $BACKUP_DIR -name "db_backup_*.sql.gz" -mtime +7 -delete

echo "Database backup completed: db_backup_$DATE.sql.gz"

File Backups

#!/bin/bash
# backup-files.sh

SOURCE_DIR="/path/to/innkeeper/uploads"
BACKUP_DIR="/var/backups/innkeeper/files"
DATE=$(date +%Y%m%d_%H%M%S)

# Create backup directory
mkdir -p $BACKUP_DIR

# Create file backup
tar -czf $BACKUP_DIR/files_backup_$DATE.tar.gz -C $SOURCE_DIR .

# Keep only last 30 days of file backups
find $BACKUP_DIR -name "files_backup_*.tar.gz" -mtime +30 -delete

echo "Files backup completed: files_backup_$DATE.tar.gz"

Automated Backup Schedule

# Add to crontab (crontab -e)

# Database backup every 6 hours
0 */6 * * * /path/to/backup-database.sh

# File backup daily at 2 AM
0 2 * * * /path/to/backup-files.sh

# Weekly full system backup
0 3 * * 0 /path/to/full-backup.sh

🚀 Performance Optimization

Application Performance

// config/app.ts - Performance settings
export default defineConfig({
  // Enable HTTP compression
  compression: {
    enabled: true,
    level: 6,
    threshold: 1024,
  },

  // Static file caching
  static: {
    enabled: true,
    maxAge: '1y',
    etag: true,
  },

  // Request timeout
  timeout: 30000,

  // Body parser limits
  bodyParser: {
    limit: '10mb',
  },
})

Database Query Optimization

// Enable query logging in development
if (Env.get('NODE_ENV') === 'development') {
  Database.on('query', (query) => {
    console.log('Query:', query.sql)
    console.log('Bindings:', query.bindings)
    console.log('Duration:', query.duration, 'ms')
  })
}

Redis Caching

// config/cache.ts
export default defineConfig({
  default: 'redis',

  stores: {
    redis: {
      driver: 'redis',
      connectionName: 'main',
      ttl: 3600, // 1 hour default TTL
    },
  },

  // Cache strategies
  strategies: {
    hotels: {ttl: 86400}, // 24 hours
    room_types: {ttl: 43200}, // 12 hours
    amenities: {ttl: 86400}, // 24 hours
    user_sessions: {ttl: 7200}, // 2 hours
  },
})

🔧 Advanced Configuration

Custom Middleware

// config/kernel.ts
export default defineConfig({
  middleware: {
    global: [
      () => import('#middleware/container_bindings_middleware'),
      () => import('#middleware/force_json_response_middleware'),
      () => import('#middleware/cors_middleware'),
      () => import('#middleware/tenant_context_middleware'),
    ],

    named: {
      auth: () => import('#middleware/auth_middleware'),
      guest: () => import('#middleware/guest_middleware'),
      admin: () => import('#middleware/admin_middleware'),
      rateLimit: () => import('#middleware/rate_limit_middleware'),
    },
  },
})

Custom Validators

// config/validator.ts
export default defineConfig({
  bail: true,
  existsStrict: true,

  // Custom validation rules
  rules: {
    phone: () => import('#validators/rules/phone'),
    currency: () => import('#validators/rules/currency'),
    dateRange: () => import('#validators/rules/date_range'),
    roomAvailability: () => import('#validators/rules/room_availability'),
  },
})

Queue Configuration

// config/queue.ts
export default defineConfig({
  default: 'redis',

  queues: {
    redis: {
      driver: 'redis',
      connectionName: 'main',

      // Queue settings
      defaultJobOptions: {
        removeOnComplete: 10,
        removeOnFail: 50,
        attempts: 3,
        backoff: {
          type: 'exponential',
          delay: 2000,
        },
      },
    },
  },

  // Job types
  jobs: {
    email: {
      queue: 'emails',
      attempts: 5,
      delay: 1000,
    },
    reports: {
      queue: 'reports',
      attempts: 3,
      delay: 5000,
    },
    cleanup: {
      queue: 'maintenance',
      attempts: 1,
      delay: 0,
    },
  },
})

✅ Configuration Validation

Environment Validation

Create a validation script to check your configuration:

#!/bin/bash
# validate-config.sh

echo "🔍 Validating Innkeeper Configuration..."

# Check required environment variables
required_vars=(
  "NODE_ENV"
  "PORT"
  "APP_KEY"
  "DB_CONNECTION"
  "DB_HOST"
  "DB_USER"
  "DB_PASSWORD"
  "DB_DATABASE"
)

for var in "${required_vars[@]}"; do
  if [ -z "${!var}" ]; then
    echo "❌ Missing required environment variable: $var"
    exit 1
  else
    echo "$var is set"
  fi
done

# Test database connection
echo "🔍 Testing database connection..."
node ace db:check || exit 1

# Test Redis connection
echo "🔍 Testing Redis connection..."
node ace redis:check || exit 1

# Validate configuration files
echo "🔍 Validating configuration files..."
node ace config:validate || exit 1

echo "🎉 Configuration validation completed successfully!"

Configuration Checklist

  • Environment variables properly set
  • Database connection working
  • Redis connection established
  • Email configuration tested
  • File storage accessible
  • Security settings configured
  • Logging properly configured
  • Backup scripts in place
  • Performance optimizations applied
  • Health checks responding

🆘 Troubleshooting

Common Configuration Issues

Database Connection Issues

# Test database connection
node ace db:check

# Check database logs
tail -f /var/log/postgresql/postgresql-*.log

Redis Connection Issues

# Test Redis connection
redis-cli ping

# Check Redis logs
tail -f /var/log/redis/redis-server.log

Email Configuration Issues

# Test email configuration
node ace mail:test [email protected]

File Upload Issues

# Check file permissions
ls -la uploads/
chmod -R 755 uploads/
chown -R www-data:www-data uploads/

📚 Next Steps

After completing the configuration:

  1. System Architecture - Understand the system design
  2. Security Model - Learn about security features
  3. API Documentation - Explore the API endpoints
  4. Performance Optimization - Advanced performance tuning

🆘 Need Help?


← Previous: Quick Start | Wiki Home | Next: System Architecture →

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