# Deployment Checklist

Complete checklist for deploying the Gym Khana Management System to production.

## Pre-Deployment Checklist

### 1. Environment Configuration

- [ ] Create production `.env` file
- [ ] Set strong `JWT_SECRET` (min 32 characters, random)
- [ ] Set strong `JWT_REFRESH_SECRET` (different from JWT_SECRET)
- [ ] Configure production database credentials
- [ ] Set `NODE_ENV=production`
- [ ] Configure SMTP settings for emails
- [ ] Configure SMS API settings (if using)
- [ ] Set proper `CORS_ORIGIN` (not `*`)
- [ ] Review and adjust rate limiting settings
- [ ] Configure upload path and file size limits

### 2. Database Setup

- [ ] Create production PostgreSQL database
- [ ] Run database schema: `psql -U user -d db -f database/schema.sql`
- [ ] Verify all tables are created
- [ ] Check indexes are in place
- [ ] Test database connection
- [ ] Set up database backup schedule
- [ ] Configure database connection pooling
- [ ] Enable PostgreSQL logging
- [ ] Set up database monitoring

### 3. Security

- [ ] Change all default passwords
- [ ] Enable HTTPS/SSL
- [ ] Configure firewall rules
- [ ] Set up fail2ban or similar
- [ ] Enable security headers (Helmet is configured)
- [ ] Review CORS settings
- [ ] Configure rate limiting
- [ ] Set up intrusion detection
- [ ] Enable audit logging
- [ ] Review file upload security
- [ ] Configure CSP (Content Security Policy)

### 4. Server Setup

- [ ] Install Node.js v24.11.1+
- [ ] Install PostgreSQL 18+
- [ ] Install PM2 or similar process manager
- [ ] Configure reverse proxy (Nginx/Apache)
- [ ] Set up SSL certificates (Let's Encrypt)
- [ ] Configure server firewall
- [ ] Set up log rotation
- [ ] Configure automatic restarts
- [ ] Set up health monitoring
- [ ] Configure backup scripts

### 5. Application

- [ ] Install dependencies: `npm ci --production`
- [ ] Build application if needed
- [ ] Create super admin account
- [ ] Test all critical endpoints
- [ ] Verify file upload works
- [ ] Test authentication flow
- [ ] Verify email/SMS sending
- [ ] Check logging works
- [ ] Test error handling
- [ ] Verify database transactions work

### 6. Monitoring & Logging

- [ ] Set up application monitoring (PM2, New Relic, DataDog)
- [ ] Configure log aggregation
- [ ] Set up error tracking (Sentry, Rollbar)
- [ ] Configure uptime monitoring
- [ ] Set up alerts for critical errors
- [ ] Monitor database performance
- [ ] Track API response times
- [ ] Monitor disk space
- [ ] Monitor memory usage
- [ ] Set up daily backup verification

## Deployment Steps

### Option 1: Manual Deployment

```bash
# 1. SSH to server
ssh user@your-server.com

# 2. Clone repository
git clone <repository-url>
cd gym-khana-new-backend

# 3. Install dependencies
npm ci --production

# 4. Set up environment
cp .env.example .env
nano .env  # Configure production settings

# 5. Create uploads directory
mkdir -p uploads logs

# 6. Install PM2
npm install -g pm2

# 7. Start application
pm2 start src/server.js --name gym-khana-api

# 8. Configure PM2 to start on boot
pm2 startup
pm2 save

# 9. Configure Nginx
sudo nano /etc/nginx/sites-available/gym-khana-api
# Add configuration (see below)

# 10. Enable site
sudo ln -s /etc/nginx/sites-available/gym-khana-api /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx
```

### Option 2: Using PM2 Ecosystem File

Create `ecosystem.config.js`:

```javascript
module.exports = {
  apps: [{
    name: 'gym-khana-api',
    script: './src/server.js',
    instances: 2,
    exec_mode: 'cluster',
    env: {
      NODE_ENV: 'production',
      PORT: 3000
    },
    error_file: './logs/pm2-error.log',
    out_file: './logs/pm2-out.log',
    log_date_format: 'YYYY-MM-DD HH:mm:ss',
    max_memory_restart: '1G',
    autorestart: true,
    watch: false
  }]
};
```

Deploy:
```bash
pm2 start ecosystem.config.js
pm2 save
```

## Nginx Configuration

Create `/etc/nginx/sites-available/gym-khana-api`:

```nginx
upstream gym_khana_backend {
    server 127.0.0.1:3000;
    keepalive 64;
}

server {
    listen 80;
    server_name api.gymkhana.pk;

    # Redirect HTTP to HTTPS
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name api.gymkhana.pk;

    # SSL Configuration
    ssl_certificate /etc/letsencrypt/live/api.gymkhana.pk/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/api.gymkhana.pk/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;

    # Logging
    access_log /var/log/nginx/gym-khana-api-access.log;
    error_log /var/log/nginx/gym-khana-api-error.log;

    # Max upload size
    client_max_body_size 10M;

    # Security headers
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

    # API endpoints
    location /api/ {
        proxy_pass http://gym_khana_backend;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_cache_bypass $http_upgrade;

        # Timeouts
        proxy_connect_timeout 60s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;
    }

    # Uploads
    location /uploads/ {
        alias /path/to/gym-khana-new-backend/uploads/;
        expires 1y;
        add_header Cache-Control "public, immutable";
    }
}
```

## SSL Certificate Setup (Let's Encrypt)

```bash
# Install certbot
sudo apt install certbot python3-certbot-nginx

# Obtain certificate
sudo certbot --nginx -d api.gymkhana.pk

# Test auto-renewal
sudo certbot renew --dry-run
```

## Database Backup Setup

Create `/usr/local/bin/backup-gym-khana-db.sh`:

```bash
#!/bin/bash

# Configuration
DB_NAME="gym_khana_db"
DB_USER="postgres"
BACKUP_DIR="/backups/gym-khana"
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="$BACKUP_DIR/gym_khana_backup_$DATE.sql.gz"
RETENTION_DAYS=30

# Create backup directory
mkdir -p $BACKUP_DIR

# Create backup
pg_dump -U $DB_USER -d $DB_NAME | gzip > $BACKUP_FILE

# Delete old backups
find $BACKUP_DIR -name "gym_khana_backup_*.sql.gz" -mtime +$RETENTION_DAYS -delete

# Log
echo "$(date): Backup completed: $BACKUP_FILE" >> $BACKUP_DIR/backup.log
```

Make it executable and add to crontab:

```bash
chmod +x /usr/local/bin/backup-gym-khana-db.sh

# Run daily at 2 AM
crontab -e
# Add: 0 2 * * * /usr/local/bin/backup-gym-khana-db.sh
```

## Post-Deployment Verification

### 1. Health Check

```bash
curl https://api.gymkhana.pk/api/v1/health
```

Expected: `{"success":true,"message":"API is running"}`

### 2. Test Authentication

```bash
curl -X POST https://api.gymkhana.pk/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"your_password"}'
```

Expected: JWT tokens in response

### 3. Check Logs

```bash
# PM2 logs
pm2 logs gym-khana-api

# Application logs
tail -f logs/combined.log

# Nginx logs
sudo tail -f /var/log/nginx/gym-khana-api-access.log
```

### 4. Monitor Resources

```bash
# PM2 monitoring
pm2 monit

# System resources
htop

# Database connections
psql -U postgres -d gym_khana_db -c "SELECT count(*) FROM pg_stat_activity;"
```

## Rollback Plan

If deployment fails:

```bash
# 1. Stop the application
pm2 stop gym-khana-api

# 2. Revert to previous version
git checkout <previous-commit>

# 3. Restore database backup
gunzip -c /backups/gym-khana/gym_khana_backup_<date>.sql.gz | psql -U postgres -d gym_khana_db

# 4. Restart application
pm2 restart gym-khana-api

# 5. Verify
curl https://api.gymkhana.pk/api/v1/health
```

## Maintenance Mode

To enable maintenance mode, create a temporary Nginx configuration:

```nginx
server {
    listen 80;
    server_name api.gymkhana.pk;

    location / {
        return 503 '{"success":false,"message":"API under maintenance. Please try again later."}';
        add_header Content-Type application/json;
    }
}
```

## Performance Optimization

### 1. Node.js Clustering

Already configured in PM2 ecosystem file (2 instances)

### 2. Database Optimization

```sql
-- Vacuum database
VACUUM ANALYZE;

-- Reindex
REINDEX DATABASE gym_khana_db;

-- Check slow queries
SELECT query, calls, total_time, mean_time
FROM pg_stat_statements
ORDER BY mean_time DESC
LIMIT 10;
```

### 3. Nginx Caching

Add to Nginx configuration:

```nginx
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=api_cache:10m max_size=100m;

location /api/v1/menu {
    proxy_cache api_cache;
    proxy_cache_valid 200 5m;
    proxy_pass http://gym_khana_backend;
}
```

## Monitoring Scripts

### CPU & Memory Alert

Create `/usr/local/bin/resource-monitor.sh`:

```bash
#!/bin/bash

CPU_THRESHOLD=80
MEM_THRESHOLD=80

CPU_USAGE=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | cut -d% -f1)
MEM_USAGE=$(free | grep Mem | awk '{print ($3/$2) * 100.0}')

if [ $(echo "$CPU_USAGE > $CPU_THRESHOLD" | bc) -eq 1 ]; then
    echo "High CPU usage: $CPU_USAGE%"
    # Send alert (email/SMS)
fi

if [ $(echo "$MEM_USAGE > $MEM_THRESHOLD" | bc) -eq 1 ]; then
    echo "High memory usage: $MEM_USAGE%"
    # Send alert (email/SMS)
fi
```

## Security Hardening

### 1. Fail2ban for API

Create `/etc/fail2ban/filter.d/gym-khana-api.conf`:

```
[Definition]
failregex = .*"ip":"<HOST>".*"message":"Invalid username or password"
ignoreregex =
```

Add jail in `/etc/fail2ban/jail.local`:

```
[gym-khana-api]
enabled = true
port = http,https
filter = gym-khana-api
logpath = /path/to/gym-khana-new-backend/logs/combined.log
maxretry = 5
bantime = 3600
```

### 2. UFW Firewall

```bash
sudo ufw allow 22/tcp    # SSH
sudo ufw allow 80/tcp    # HTTP
sudo ufw allow 443/tcp   # HTTPS
sudo ufw allow 5432/tcp from <your-ip>  # PostgreSQL (restricted)
sudo ufw enable
```

## Troubleshooting

### Application Won't Start

```bash
# Check logs
pm2 logs gym-khana-api --lines 50

# Check port availability
sudo netstat -tulpn | grep 3000

# Check environment
pm2 env gym-khana-api
```

### Database Connection Issues

```bash
# Test connection
psql -U postgres -d gym_khana_db -c "SELECT NOW();"

# Check PostgreSQL status
sudo systemctl status postgresql

# Check connection limits
psql -U postgres -c "SHOW max_connections;"
```

### High Memory Usage

```bash
# Restart application
pm2 restart gym-khana-api

# Check for memory leaks
pm2 monit

# Increase PM2 max memory restart
pm2 start ecosystem.config.js --max-memory-restart 1G
```

## Update Procedure

```bash
# 1. Backup database
/usr/local/bin/backup-gym-khana-db.sh

# 2. Pull latest code
git pull origin main

# 3. Install dependencies
npm ci --production

# 4. Run migrations (if any)
# npm run migrate

# 5. Reload application (zero-downtime)
pm2 reload gym-khana-api

# 6. Verify
curl https://api.gymkhana.pk/api/v1/health
```

## Support Contacts

- **System Administrator**: sysadmin@gymkhana.pk
- **Database Administrator**: dba@gymkhana.pk
- **Development Team**: dev@gymkhana.pk
- **Emergency Hotline**: +92-XXX-XXXXXXX

---

**Last Updated**: January 2025
