- Backend NestJS con módulos de autenticación, inventario, créditos - Frontend React con dashboard y componentes UI - Base de datos PostgreSQL con migraciones - Tests E2E configurados - Configuración de Docker y deployment Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
304 lines
6.9 KiB
Markdown
304 lines
6.9 KiB
Markdown
# Configuracion de Produccion - MiInventario
|
|
|
|
Este documento describe la configuracion necesaria para desplegar MiInventario en produccion.
|
|
|
|
## Variables de Entorno Requeridas
|
|
|
|
### Base de Datos (PostgreSQL)
|
|
|
|
```env
|
|
DATABASE_HOST=your-postgres-host.com
|
|
DATABASE_PORT=5432
|
|
DATABASE_NAME=miinventario
|
|
DATABASE_USER=miinventario_user
|
|
DATABASE_PASSWORD=<strong-password>
|
|
```
|
|
|
|
**Recomendaciones:**
|
|
- Usar PostgreSQL 14+
|
|
- Habilitar SSL para conexiones
|
|
- Configurar pool de conexiones (min: 5, max: 20)
|
|
- Habilitar extension `uuid-ossp`
|
|
|
|
### JWT (Autenticacion)
|
|
|
|
```env
|
|
JWT_SECRET=<random-string-256-bits>
|
|
JWT_EXPIRES_IN=15m
|
|
JWT_REFRESH_SECRET=<different-random-string-256-bits>
|
|
JWT_REFRESH_EXPIRES_IN=7d
|
|
```
|
|
|
|
**Generar secretos seguros:**
|
|
```bash
|
|
openssl rand -base64 32
|
|
```
|
|
|
|
### Redis (Colas y Cache)
|
|
|
|
```env
|
|
REDIS_HOST=your-redis-host.com
|
|
REDIS_PORT=6379
|
|
REDIS_PASSWORD=<redis-password>
|
|
```
|
|
|
|
**Recomendaciones:**
|
|
- Usar Redis 6+
|
|
- Habilitar persistencia RDB
|
|
- Configurar maxmemory-policy: allkeys-lru
|
|
|
|
### AWS S3 / MinIO (Almacenamiento de Videos)
|
|
|
|
```env
|
|
S3_ENDPOINT=https://s3.us-east-1.amazonaws.com
|
|
S3_ACCESS_KEY=<aws-access-key>
|
|
S3_SECRET_KEY=<aws-secret-key>
|
|
S3_BUCKET=miinventario-prod
|
|
S3_REGION=us-east-1
|
|
```
|
|
|
|
**Para MinIO en produccion:**
|
|
```env
|
|
S3_ENDPOINT=https://your-minio-domain.com
|
|
S3_ACCESS_KEY=<minio-access-key>
|
|
S3_SECRET_KEY=<minio-secret-key>
|
|
S3_BUCKET=miinventario
|
|
S3_REGION=us-east-1
|
|
```
|
|
|
|
**Recomendaciones:**
|
|
- Configurar lifecycle rules para eliminar videos despues de 30 dias
|
|
- Habilitar versionado para backups
|
|
- Configurar CORS para el dominio de la app
|
|
|
|
### Stripe (Pagos)
|
|
|
|
```env
|
|
STRIPE_SECRET_KEY=sk_live_...
|
|
STRIPE_WEBHOOK_SECRET=whsec_...
|
|
```
|
|
|
|
**Pasos para configurar Stripe:**
|
|
|
|
1. Crear cuenta en [Stripe Dashboard](https://dashboard.stripe.com)
|
|
2. Obtener API keys de produccion
|
|
3. Configurar webhook:
|
|
- URL: `https://api.miinventario.com/api/v1/payments/webhook/stripe`
|
|
- Eventos a escuchar:
|
|
- `payment_intent.succeeded`
|
|
- `payment_intent.payment_failed`
|
|
- `payment_intent.processing`
|
|
- `charge.succeeded`
|
|
- `charge.pending`
|
|
4. Copiar el Webhook signing secret
|
|
|
|
**Metodos de pago soportados:**
|
|
- Tarjetas de credito/debito
|
|
- OXXO (efectivo)
|
|
- 7-Eleven (en desarrollo con Conekta)
|
|
|
|
### Firebase (Notificaciones Push)
|
|
|
|
```env
|
|
FIREBASE_PROJECT_ID=miinventario-prod
|
|
FIREBASE_CLIENT_EMAIL=firebase-adminsdk-xxxxx@miinventario-prod.iam.gserviceaccount.com
|
|
FIREBASE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n"
|
|
```
|
|
|
|
**Pasos para configurar Firebase:**
|
|
|
|
1. Crear proyecto en [Firebase Console](https://console.firebase.google.com)
|
|
2. Ir a Project Settings > Service accounts
|
|
3. Generar nueva private key
|
|
4. Copiar los valores del JSON generado:
|
|
- `project_id` -> `FIREBASE_PROJECT_ID`
|
|
- `client_email` -> `FIREBASE_CLIENT_EMAIL`
|
|
- `private_key` -> `FIREBASE_PRIVATE_KEY`
|
|
|
|
**Configuracion de Android:**
|
|
1. Agregar app Android en Firebase
|
|
2. Descargar `google-services.json`
|
|
3. Configurar en la app movil
|
|
|
|
**Configuracion de iOS:**
|
|
1. Agregar app iOS en Firebase
|
|
2. Descargar `GoogleService-Info.plist`
|
|
3. Configurar en la app movil
|
|
|
|
### IA Providers (Vision AI)
|
|
|
|
```env
|
|
# Proveedor activo: 'openai' o 'claude'
|
|
IA_PROVIDER=openai
|
|
|
|
# OpenAI (GPT-4 Vision)
|
|
OPENAI_API_KEY=sk-...
|
|
|
|
# Anthropic (Claude Vision) - alternativo
|
|
ANTHROPIC_API_KEY=sk-ant-...
|
|
```
|
|
|
|
**Notas:**
|
|
- Se requiere al menos una API key configurada
|
|
- OpenAI usa el modelo `gpt-4o` para vision
|
|
- Claude usa el modelo `claude-sonnet-4-20250514`
|
|
- En desarrollo sin API keys, usa deteccion mock
|
|
- Los frames se extraen del video cada 2 segundos (max 10 frames)
|
|
|
|
**Costos aproximados:**
|
|
- OpenAI GPT-4o Vision: ~$0.01 por imagen
|
|
- Claude Vision: ~$0.003 por imagen
|
|
- Costo por video (10 frames): $0.03 - $0.10
|
|
|
|
### Aplicacion
|
|
|
|
```env
|
|
NODE_ENV=production
|
|
PORT=3142
|
|
CORS_ORIGINS=https://miinventario.com,https://app.miinventario.com
|
|
```
|
|
|
|
## Ejemplo Completo de .env.production
|
|
|
|
```env
|
|
# Database
|
|
DATABASE_HOST=prod-db.miinventario.com
|
|
DATABASE_PORT=5432
|
|
DATABASE_NAME=miinventario
|
|
DATABASE_USER=miinventario_prod
|
|
DATABASE_PASSWORD=super-secret-db-password
|
|
|
|
# JWT
|
|
JWT_SECRET=your-256-bit-random-string
|
|
JWT_EXPIRES_IN=15m
|
|
JWT_REFRESH_SECRET=another-256-bit-random-string
|
|
JWT_REFRESH_EXPIRES_IN=7d
|
|
|
|
# Redis
|
|
REDIS_HOST=prod-redis.miinventario.com
|
|
REDIS_PORT=6379
|
|
REDIS_PASSWORD=redis-password
|
|
|
|
# S3
|
|
S3_ENDPOINT=https://s3.us-east-1.amazonaws.com
|
|
S3_ACCESS_KEY=AKIAIOSFODNN7EXAMPLE
|
|
S3_SECRET_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
|
|
S3_BUCKET=miinventario-prod
|
|
S3_REGION=us-east-1
|
|
|
|
# Stripe
|
|
STRIPE_SECRET_KEY=sk_live_51...
|
|
STRIPE_WEBHOOK_SECRET=whsec_...
|
|
|
|
# Firebase
|
|
FIREBASE_PROJECT_ID=miinventario-prod
|
|
FIREBASE_CLIENT_EMAIL=firebase-adminsdk@miinventario-prod.iam.gserviceaccount.com
|
|
FIREBASE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n"
|
|
|
|
# IA Provider
|
|
IA_PROVIDER=openai
|
|
OPENAI_API_KEY=sk-proj-...
|
|
ANTHROPIC_API_KEY=sk-ant-...
|
|
|
|
# App
|
|
NODE_ENV=production
|
|
PORT=3142
|
|
CORS_ORIGINS=https://miinventario.com
|
|
```
|
|
|
|
## Checklist de Seguridad
|
|
|
|
- [ ] Todas las claves secretas son unicas y generadas aleatoriamente
|
|
- [ ] Base de datos solo accesible desde el servidor de la aplicacion
|
|
- [ ] Redis protegido con password y no expuesto a internet
|
|
- [ ] S3 bucket con acceso privado (no publico)
|
|
- [ ] HTTPS habilitado en todos los endpoints
|
|
- [ ] Rate limiting configurado en el API Gateway/Nginx
|
|
- [ ] Logs de acceso habilitados
|
|
- [ ] Backups automaticos de base de datos configurados
|
|
- [ ] Monitoring y alertas configurados (e.g., Sentry, CloudWatch)
|
|
|
|
## Despliegue
|
|
|
|
### Con Docker
|
|
|
|
```bash
|
|
# Build
|
|
docker build -t miinventario-api:latest .
|
|
|
|
# Run
|
|
docker run -d \
|
|
--name miinventario-api \
|
|
--env-file .env.production \
|
|
-p 3142:3142 \
|
|
miinventario-api:latest
|
|
```
|
|
|
|
### Con Docker Compose
|
|
|
|
```yaml
|
|
version: '3.8'
|
|
services:
|
|
api:
|
|
build: ./apps/backend
|
|
env_file: .env.production
|
|
ports:
|
|
- "3142:3142"
|
|
depends_on:
|
|
- postgres
|
|
- redis
|
|
restart: unless-stopped
|
|
|
|
postgres:
|
|
image: postgres:14-alpine
|
|
environment:
|
|
POSTGRES_DB: miinventario
|
|
POSTGRES_USER: miinventario_prod
|
|
POSTGRES_PASSWORD: ${DATABASE_PASSWORD}
|
|
volumes:
|
|
- postgres_data:/var/lib/postgresql/data
|
|
restart: unless-stopped
|
|
|
|
redis:
|
|
image: redis:6-alpine
|
|
command: redis-server --requirepass ${REDIS_PASSWORD}
|
|
volumes:
|
|
- redis_data:/data
|
|
restart: unless-stopped
|
|
|
|
volumes:
|
|
postgres_data:
|
|
redis_data:
|
|
```
|
|
|
|
### Migraciones en Produccion
|
|
|
|
```bash
|
|
# Ejecutar migraciones
|
|
npm run migration:run
|
|
|
|
# Verificar estado
|
|
npm run typeorm migration:show -d src/config/typeorm.config.ts
|
|
```
|
|
|
|
## Monitoreo
|
|
|
|
### Health Checks
|
|
|
|
- `GET /api/v1/health` - Estado general
|
|
- `GET /api/v1/health/ready` - Readiness check
|
|
|
|
### Metricas Recomendadas
|
|
|
|
- Request rate por endpoint
|
|
- Latencia P50, P95, P99
|
|
- Tasa de errores 4xx y 5xx
|
|
- Uso de creditos por usuario
|
|
- Pagos completados vs fallidos
|
|
- Videos procesados por hora
|
|
- FCM deliveries exitosos
|
|
|
|
## Contacto
|
|
|
|
Para problemas de configuracion contactar al equipo de desarrollo.
|