Desplegar el backend
Esta guía asume un servidor Linux con Docker instalado y un dominio con registro DNS apuntando a ese servidor. El dominio de referencia usado en el resto de este manual (y ya configurado en el build de release de la app Android) es api.agrotrack.corall.pe — si se usa un dominio distinto, ver la nota correspondiente en Compilar y distribuir la app Android.
Base de datos — Supabase
Section titled “Base de datos — Supabase”- Crear un proyecto nuevo en Supabase.
- Abrir el SQL Editor del proyecto y ejecutar, en orden numérico, cada archivo de
agrotrack-back/migrations/:
001_initial_schema.sql002_wifi_calibration_maintenance.sql003_gateway_pin.sql004_operator_scoping.sql005_gateway_battery.sql006_threshold_enable_persistence.sql007_dashboard_alias_and_maintenance.sql008_helpdesk_tickets.sql009_calibration_ack.sql010_gateway_online_status.sql011_gateway_mqtt_topic.sql012_gateway_sensor_count.sql013_gateway_general_reports.sql014_threshold_delete_ownership.sql015_gateway_wifi_password.sqlEs un proceso manual — no hay una herramienta de migración automática (tipo ORM) que las aplique por sí sola. Cada archivo debe pegarse y ejecutarse completo, en este orden, una sola vez.
Variables de entorno
Section titled “Variables de entorno”Crear un archivo .env.production (nunca comiteado al repositorio) con estas variables, agrupadas igual que agrotrack-back/example.env:
NODE_ENV=productionPORT=3000
# ─── Supabase PostgreSQL (Session Pooler — IPv4) ─────────────────────────────# Supabase Dashboard → Settings → Database → Session PoolerDB_HOST=aws-0-<region>.pooler.supabase.comDB_PORT=5432DB_NAME=postgresDB_USER=postgres.<project-ref>DB_PASSWORD=<password-de-bd-de-supabase>DB_MAX_POOL_SIZE=10DB_SSL=true
# ─── Supabase API ─────────────────────────────────────────────────────────────# Supabase Dashboard → Settings → APISUPABASE_URL=https://<project-ref>.supabase.coSUPABASE_ANON_KEY=sb_publishable_...SUPABASE_SERVICE_ROLE_KEY=sb_secret_...
# ─── Auth ─────────────────────────────────────────────────────────────────────JWT_SECRET=<secreto-largo-y-aleatorio-propio>JWT_EXPIRE_IN=604800
# ─── MQTT ──────────────────────────────────────────────────────────────────────MQTT_ENABLED=trueMQTT_BROKER_URL=mqtt://<host-del-broker>:1883MQTT_USERNAME=<usuario-del-broker>MQTT_PASSWORD=<password-del-broker>MQTT_CLIENT_ID=agrotrack-serverMQTT_TOPIC_SUBSCRIBE=MQTT_GATEWAY_UID=
TEAM_NAME=Corall D&RTZ=America/LimaJWT_SECRET debe ser un valor propio, largo y aleatorio — nunca el change_me_in_production de ejemplo. DB_PASSWORD/SUPABASE_* se obtienen del panel de Supabase creado en el paso anterior.
Bróker MQTT
Section titled “Bróker MQTT”El backend no incluye un bróker MQTT — es el único suscriptor, no el servidor. Se necesita uno propio. La forma más simple es correr Eclipse Mosquitto en un contenedor Docker aparte:
docker run -d --name mosquitto \ -p 1883:1883 \ -v mosquitto-data:/mosquitto/data \ eclipse-mosquitto:2Para producción, configurar autenticación (usuario/contraseña) siguiendo la documentación de Mosquitto y usar esas credenciales en MQTT_USERNAME/MQTT_PASSWORD del .env.production.
Build y ejecución del contenedor
Section titled “Build y ejecución del contenedor”El repo ya incluye un Dockerfile en agrotrack-back/:
cd agrotrack-backdocker build -t agrotrack-back:latest .docker run -d --name agrotrack-back \ -p 3000:3000 \ --env-file .env.production \ agrotrack-back:latestEl contenedor expone el puerto 3000. Delante de él va un reverse proxy con TLS — la app Android usa wss:// en producción, así que un certificado válido no es opcional. Con Caddy (TLS automático vía Let’s Encrypt, sin configuración manual de certificados), el Caddyfile completo es:
api.agrotrack.corall.pe { reverse_proxy localhost:3000}(Nginx con Certbot es una alternativa equivalente si ya se usa en la infraestructura existente.)
Primer usuario administrador
Section titled “Primer usuario administrador”No hay un flujo de aprovisionamiento de administrador pensado para producción — el único mecanismo que existe hoy es el script de seed, pensado originalmente para pruebas:
cd agrotrack-backbun installbun run scripts/seed.tsEsto crea 3 cuentas con contraseñas fijas y conocidas (Operador2024!, Tecnico2024!, Admin2024!). Paso obligatorio inmediatamente después: cambiar las 3 contraseñas antes de dar el sistema por disponible. La app no tiene todavía una pantalla para esto, así que se hace directamente contra la API:
# 1. Login para obtener el tokencurl -X POST https://api.agrotrack.corall.pe/api/auth/login \ -H "Content-Type: application/json" \ -d '{"email":"admin@agrotrack.com","password":"Admin2024!"}'# copiar el valor de "token" de la respuesta
# 2. Cambiar la contraseña con ese tokencurl -X PUT https://api.agrotrack.corall.pe/api/auth/update-password \ -H "Content-Type: application/json" \ -H "Authorization: Bearer <token-copiado>" \ -d '{"currentPassword":"Admin2024!","newPassword":"<contraseña-nueva-de-al-menos-8-caracteres>"}'Repetir para las 3 cuentas (operador@agrotrack.com, tecnico@agrotrack.com, admin@agrotrack.com).
Verificación
Section titled “Verificación”- Repetir el comando de login (
POST /api/auth/login) con la contraseña ya cambiada debe devolver un token (200). - Iniciar sesión desde la app Android (ver Compilar y distribuir la app Android) y confirmar que el Dashboard carga.
- Si hay un gateway físico transmitiendo, confirmar que su lectura llega en tiempo real al Dashboard (WebSocket funcionando de extremo a extremo).