# Guía de Despliegue en Producción - Horux360

## Infraestructura

### Servidor
- **OS:** Ubuntu 24.04 LTS
- **RAM:** 22GB
- **CPU:** 8 cores
- **Dominio:** horuxfin.com (DNS en AWS Route 53)
- **SSL:** Let's Encrypt (certificado real via DNS challenge)
- **IP Interna:** 192.168.10.212

### Stack
| Componente | Tecnología | Puerto |
|-----------|-----------|--------|
| Reverse Proxy | Nginx 1.24 | 80/443 |
| API | Node.js + Express + tsx | 4000 |
| Frontend | Next.js 14 | 3000 |
| Base de datos | PostgreSQL 16 | 5432 |
| Process Manager | PM2 | — |

---

## Arquitectura de Red

```
Internet
   │
   ▼
Nginx (443/SSL)
   ├── /api/*          → 127.0.0.1:4000 (horux-api)
   ├── /api/auth/*     → 127.0.0.1:4000 (rate limit: 5r/s)
   ├── /api/webhooks/* → 127.0.0.1:4000 (rate limit: 10r/s)
   ├── /health         → 127.0.0.1:4000
   └── /*              → 127.0.0.1:3000 (horux-web)
```

---

## PM2 - Gestión de Procesos

### Configuración (`ecosystem.config.js`)

```javascript
module.exports = {
  apps: [
    {
      name: 'horux-api',
      interpreter: 'node',
      script: '/root/Horux/node_modules/.pnpm/tsx@4.21.0/node_modules/tsx/dist/cli.mjs',
      args: 'src/index.ts',
      cwd: '/root/Horux/apps/api',
      instances: 1,
      exec_mode: 'fork',
      autorestart: true,
      max_memory_restart: '1G',
      kill_timeout: 5000,
      listen_timeout: 10000,
      env: { NODE_ENV: 'production', PORT: 4000 },
    },
    {
      name: 'horux-web',
      script: 'node_modules/next/dist/bin/next',
      args: 'start',
      cwd: '/root/Horux/apps/web',
      instances: 1,
      exec_mode: 'fork',
      autorestart: true,
      max_memory_restart: '512M',
      kill_timeout: 5000,
      env: { NODE_ENV: 'production', PORT: 3000 },
    },
  ],
};
```

### Notas
- La API usa `tsx` en lugar de `tsc` compilado porque `@horux/shared` exporta TypeScript raw (ESM) que `dist/` no puede resolver.
- Next.js usa la ruta directa `node_modules/next/dist/bin/next` porque `node_modules/.bin/next` es un shell script que PM2 no puede ejecutar como script Node.js.

### Comandos Útiles
```bash
pm2 restart all           # Reiniciar todo
pm2 logs horux-api        # Ver logs del API
pm2 logs horux-web        # Ver logs del frontend
pm2 monit                 # Monitor en tiempo real
pm2 save                  # Guardar estado actual
pm2 startup               # Configurar inicio automático
```

---

## Nginx

### Archivo: `/etc/nginx/sites-available/horux360.conf`

#### Rate Limiting
| Zona | Límite | Burst | Uso |
|------|--------|-------|-----|
| `auth` | 5r/s | 10 | `/api/auth/*` |
| `webhook` | 10r/s | 20 | `/api/webhooks/*` |
| `api` | 30r/s | 50 | `/api/*` (general) |

#### Security Headers
- `Content-Security-Policy`: Restrictivo (`default-src 'self'`)
- `Strict-Transport-Security`: 1 año con includeSubDomains
- `X-Frame-Options`: SAMEORIGIN
- `X-Content-Type-Options`: nosniff
- `Permissions-Policy`: camera, microphone, geolocation deshabilitados
- `Referrer-Policy`: strict-origin-when-cross-origin

#### Body Limits
- Global: `50M` (Nginx)
- API default: `10mb` (Express)
- `/api/cfdi/bulk`: `50mb` (Express route-specific)

### Renovar SSL
```bash
certbot renew --dry-run  # Verificar
certbot renew            # Renovar
```

---

## PostgreSQL

### Configuración de Rendimiento (`postgresql.conf`)
| Parámetro | Valor | Descripción |
|-----------|-------|-------------|
| `max_connections` | 300 | Para multi-tenant con pools por tenant |
| `shared_buffers` | 4GB | ~18% de 22GB RAM |
| `work_mem` | 16MB | Memoria por operación de sort/hash |
| `effective_cache_size` | 16GB | ~72% de RAM |
| `maintenance_work_mem` | 512MB | Para VACUUM, CREATE INDEX |
| `wal_buffers` | 64MB | Write-ahead log buffers |

### Arquitectura Multi-Tenant
Cada cliente tiene su propia base de datos PostgreSQL:
```
horux360              ← Base central (tenants, users, subscriptions)
horux_cas2408138w2    ← Base del admin global
horux_<rfc>           ← Base de cada cliente
```

### Backups
```bash
# Cron job: 0 1 * * * /root/Horux/scripts/backup.sh
# Ubicación: /var/horux/backups/
# Retención: 7 diarios + 4 semanales
```

---

## Variables de Entorno

### API (`apps/api/.env`)
```env
NODE_ENV=production
PORT=4000
DATABASE_URL="postgresql://postgres:<password>@localhost:5432/horux360?schema=public"
JWT_SECRET=<min 32 chars>
JWT_EXPIRES_IN=15m
JWT_REFRESH_EXPIRES_IN=7d
CORS_ORIGIN=https://horuxfin.com
FRONTEND_URL=https://horuxfin.com
FIEL_ENCRYPTION_KEY=<min 32 chars, REQUERIDO>
FIEL_STORAGE_PATH=/var/horux/fiel

# MercadoPago
MP_ACCESS_TOKEN=<token>
MP_WEBHOOK_SECRET=<secret, REQUERIDO para producción>

# SMTP (Google Workspace)
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=ivan@horuxfin.com
SMTP_PASS=<app-password>
SMTP_FROM=Horux360 <ivan@horuxfin.com>

# Admin
ADMIN_EMAIL=carlos@horuxfin.com
```

### Web (`apps/web/.env.local`)
```env
NEXT_PUBLIC_API_URL=https://horuxfin.com/api
```

---

## Directorios Importantes

```
/root/Horux/                    ← Código fuente
/var/horux/fiel/                ← Archivos FIEL encriptados (0700)
/var/horux/backups/             ← Backups de PostgreSQL
/etc/nginx/sites-available/     ← Config de Nginx
/etc/letsencrypt/live/          ← Certificados SSL
```

---

## Despliegue de Cambios

```bash
# 1. Pull cambios
cd /root/Horux
git pull origin main

# 2. Instalar dependencias
pnpm install

# 3. Build
pnpm build

# 4. Reiniciar servicios
pm2 restart all

# 5. Si hay cambios en nginx:
cp deploy/nginx/horux360.conf /etc/nginx/sites-available/horux360.conf
nginx -t && systemctl reload nginx
```

---

## Troubleshooting

### API no inicia
```bash
pm2 logs horux-api --lines 50      # Ver logs de error
pm2 restart horux-api               # Reiniciar
```

### Puerto en uso
```bash
lsof -i :4000                      # Ver quién usa el puerto
kill <PID>                          # Matar proceso
pm2 restart horux-api
```

### Certificado SSL expirado
```bash
certbot renew
systemctl reload nginx
```

### Base de datos lenta
```bash
sudo -u postgres psql -c "SELECT * FROM pg_stat_activity WHERE state = 'active';"
```
