chore: sincronizar cambios pendientes de desarrollo a produccion
This commit is contained in:
@@ -0,0 +1,276 @@
|
||||
# Manual de despliegue a produccion: paginacion de GET /api/trips
|
||||
|
||||
## Alcance
|
||||
|
||||
Este despliegue publica el cambio del backend para que `GET /api/trips` aplique paginacion y filtros en SQL.
|
||||
|
||||
Incluye:
|
||||
|
||||
- Cambios en `src/controllers/tripsController.js`.
|
||||
- Tests de integracion en `test/trips.list.integration.test.js`.
|
||||
- Documentacion en `README.md`.
|
||||
- Migracion de indices: `src/sql/migrations/20260630_trips_list_pagination_indexes.sql`.
|
||||
|
||||
No incluye cambios en la app React Native.
|
||||
|
||||
## Supuestos
|
||||
|
||||
- El servidor Node de produccion usa este proyecto: `/var/www/node.gestion.abianservice.com`.
|
||||
- La API escucha en `127.0.0.1:3001` salvo que se sobreescriba `PORT`.
|
||||
- El restart operativo se hace con `src/scripts/restartNodeApi.sh`.
|
||||
- Las variables `DB_HOST`, `DB_USER`, `DB_PASSWORD` y `DB_NAME` de produccion estan configuradas en `.env` o disponibles en shell.
|
||||
- Las migraciones SQL se aplican manualmente con `mysql`.
|
||||
|
||||
Si alguno de estos puntos no coincide con produccion, parar y ajustar el manual antes de ejecutar.
|
||||
|
||||
## Criterios de exito
|
||||
|
||||
- `GET /api/trips` sin parametros responde `200` con maximo 25 viajes por defecto.
|
||||
- La respuesta incluye `trips`, `page`, `limit`, `total` y `has_more`.
|
||||
- Las llamadas con `page`, `limit`, `status_ids`, `date_from` y `date_to` filtran en base de datos.
|
||||
- La API arranca correctamente y `/health` responde `200`.
|
||||
- `/api/trips/active` sin token responde `401`.
|
||||
- No aparecen errores nuevos en el log de la API.
|
||||
|
||||
## 1. Precheck antes de tocar produccion
|
||||
|
||||
Desde la raiz del proyecto:
|
||||
|
||||
```bash
|
||||
cd /var/www/node.gestion.abianservice.com
|
||||
|
||||
git status --short
|
||||
node --version
|
||||
npm --version
|
||||
```
|
||||
|
||||
Revisar que no haya cambios locales no esperados. Si hay cambios ajenos, no sobrescribirlos.
|
||||
|
||||
Ejecutar tests antes de desplegar:
|
||||
|
||||
```bash
|
||||
npm test
|
||||
```
|
||||
|
||||
Tambien se puede ejecutar solo la cobertura del endpoint:
|
||||
|
||||
```bash
|
||||
node --test test/trips.list.integration.test.js
|
||||
```
|
||||
|
||||
## 2. Backup rapido de base de datos
|
||||
|
||||
Antes de aplicar indices, sacar al menos backup de las tablas tocadas por la migracion:
|
||||
|
||||
```bash
|
||||
mkdir -p /tmp/abian-db-backups
|
||||
|
||||
mysqldump -h "$DB_HOST" -u "$DB_USER" -p"$DB_PASSWORD" "$DB_NAME" \
|
||||
c_viajes c_viajes_proveedor c_cambios_estado \
|
||||
> /tmp/abian-db-backups/trips_indexes_$(date +%Y%m%d_%H%M%S).sql
|
||||
```
|
||||
|
||||
Si `DB_PASSWORD` no esta exportada en shell, cargar `.env` de forma controlada o introducir la password manualmente con `-p`.
|
||||
|
||||
## 3. Aplicar codigo
|
||||
|
||||
Actualizar el codigo de produccion con el mecanismo habitual del equipo. Si se usa Git en el servidor:
|
||||
|
||||
```bash
|
||||
cd /var/www/node.gestion.abianservice.com
|
||||
|
||||
git fetch --all --prune
|
||||
git status --short
|
||||
```
|
||||
|
||||
Antes de cambiar de revision, confirmar que `git status --short` no muestra cambios locales que no deban pisarse.
|
||||
|
||||
Despues de actualizar la rama o revision objetivo, instalar dependencias solo si `package-lock.json` cambio:
|
||||
|
||||
```bash
|
||||
npm ci --omit=dev
|
||||
```
|
||||
|
||||
Para este cambio no deberia ser necesario si solo se despliega la paginacion de viajes.
|
||||
|
||||
## 4. Aplicar migracion de indices
|
||||
|
||||
La migracion es idempotente: comprueba `information_schema.statistics` antes de crear cada indice.
|
||||
|
||||
```bash
|
||||
cd /var/www/node.gestion.abianservice.com
|
||||
|
||||
mysql -h "$DB_HOST" -u "$DB_USER" -p"$DB_PASSWORD" "$DB_NAME" \
|
||||
< src/sql/migrations/20260630_trips_list_pagination_indexes.sql
|
||||
```
|
||||
|
||||
Validar que los indices existen:
|
||||
|
||||
```bash
|
||||
mysql -h "$DB_HOST" -u "$DB_USER" -p"$DB_PASSWORD" "$DB_NAME" -e "
|
||||
SHOW INDEX FROM c_viajes WHERE Key_name = 'idx_c_viajes_id_estado';
|
||||
SHOW INDEX FROM c_viajes_proveedor WHERE Key_name IN (
|
||||
'idx_c_viajes_proveedor_fecha_salida',
|
||||
'idx_c_viajes_proveedor_fecha_llegada',
|
||||
'idx_c_viajes_proveedor_dni_estado_dates'
|
||||
);
|
||||
SHOW INDEX FROM c_cambios_estado WHERE Key_name = 'idx_c_cambios_estado_viaje_estado_fecha';
|
||||
"
|
||||
```
|
||||
|
||||
Si la tabla es grande, esta fase puede tardar. No reiniciar la API hasta que termine correctamente.
|
||||
|
||||
## 5. Reiniciar API
|
||||
|
||||
Usar el script incluido en el repo:
|
||||
|
||||
```bash
|
||||
cd /var/www/node.gestion.abianservice.com
|
||||
|
||||
bash src/scripts/restartNodeApi.sh
|
||||
```
|
||||
|
||||
El script valida:
|
||||
|
||||
- Proceso Node arrancado.
|
||||
- Puerto `127.0.0.1:3001` escuchando.
|
||||
- `/health` responde `200`.
|
||||
- `/api/trips/active` sin token responde `401`.
|
||||
|
||||
Si produccion usa otro puerto o ruta, exportar variables antes de ejecutar:
|
||||
|
||||
```bash
|
||||
PORT=3001 HOST=127.0.0.1 bash src/scripts/restartNodeApi.sh
|
||||
```
|
||||
|
||||
## 6. Smoke tests post-deploy
|
||||
|
||||
### Sin token
|
||||
|
||||
Debe devolver `401`:
|
||||
|
||||
```bash
|
||||
curl -i "http://127.0.0.1:3001/api/trips"
|
||||
```
|
||||
|
||||
### Con token real de conductor
|
||||
|
||||
Usar un JWT valido de la app o de una sesion de pruebas.
|
||||
|
||||
```bash
|
||||
TOKEN="<JWT_VALIDO>"
|
||||
|
||||
curl -sS "http://127.0.0.1:3001/api/trips?page=1&limit=25" \
|
||||
-H "Authorization: Bearer $TOKEN"
|
||||
```
|
||||
|
||||
Comprobar que la respuesta contiene:
|
||||
|
||||
```json
|
||||
{
|
||||
"trips": [],
|
||||
"page": 1,
|
||||
"limit": 25,
|
||||
"total": 0,
|
||||
"has_more": false
|
||||
}
|
||||
```
|
||||
|
||||
`trips` puede traer datos reales, pero `page`, `limit`, `total` y `has_more` deben existir.
|
||||
|
||||
Probar historico:
|
||||
|
||||
```bash
|
||||
curl -sS "http://127.0.0.1:3001/api/trips?page=1&limit=25&status_ids=7,8,9" \
|
||||
-H "Authorization: Bearer $TOKEN"
|
||||
```
|
||||
|
||||
Probar proximos desde una fecha:
|
||||
|
||||
```bash
|
||||
curl -sS "http://127.0.0.1:3001/api/trips?page=1&limit=25&date_from=2026-06-30" \
|
||||
-H "Authorization: Bearer $TOKEN"
|
||||
```
|
||||
|
||||
Probar rango de fechas:
|
||||
|
||||
```bash
|
||||
curl -sS "http://127.0.0.1:3001/api/trips?page=1&limit=25&date_from=2026-06-01&date_to=2026-06-30" \
|
||||
-H "Authorization: Bearer $TOKEN"
|
||||
```
|
||||
|
||||
### Validaciones negativas
|
||||
|
||||
Deben devolver `400`:
|
||||
|
||||
```bash
|
||||
curl -i "http://127.0.0.1:3001/api/trips?page=0" -H "Authorization: Bearer $TOKEN"
|
||||
curl -i "http://127.0.0.1:3001/api/trips?limit=101" -H "Authorization: Bearer $TOKEN"
|
||||
curl -i "http://127.0.0.1:3001/api/trips?status_ids=7,x" -H "Authorization: Bearer $TOKEN"
|
||||
curl -i "http://127.0.0.1:3001/api/trips?date_from=2026-02-30" -H "Authorization: Bearer $TOKEN"
|
||||
```
|
||||
|
||||
## 7. Logs a revisar
|
||||
|
||||
Log por defecto del script de restart:
|
||||
|
||||
```bash
|
||||
tail -n 100 /tmp/node-gestion-api.log
|
||||
```
|
||||
|
||||
Buscar entradas del listado:
|
||||
|
||||
```bash
|
||||
grep "\[TripsList\]" /tmp/node-gestion-api.log | tail -n 20
|
||||
```
|
||||
|
||||
Cada entrada debe mostrar `page`, `limit`, `rows`, `total` y `elapsed_ms`.
|
||||
|
||||
Senales de problema:
|
||||
|
||||
- `Error getting trips list`.
|
||||
- `ER_PARSE_ERROR`.
|
||||
- `ER_BAD_FIELD_ERROR`.
|
||||
- Tiempos `elapsed_ms` altos de forma sostenida.
|
||||
- Respuestas sin `page`, `limit`, `total` o `has_more`.
|
||||
|
||||
## 8. Rollback
|
||||
|
||||
### Rollback de codigo
|
||||
|
||||
Volver a la revision anterior con el mecanismo habitual del equipo y reiniciar:
|
||||
|
||||
```bash
|
||||
cd /var/www/node.gestion.abianservice.com
|
||||
|
||||
bash src/scripts/restartNodeApi.sh
|
||||
```
|
||||
|
||||
### Rollback de indices
|
||||
|
||||
Normalmente no hace falta retirar indices: son compatibles y no cambian datos. Solo retirarlos si se confirma impacto operativo.
|
||||
|
||||
Comandos de retirada, si fueran necesarios:
|
||||
|
||||
```sql
|
||||
ALTER TABLE c_viajes DROP INDEX idx_c_viajes_id_estado;
|
||||
ALTER TABLE c_viajes_proveedor DROP INDEX idx_c_viajes_proveedor_fecha_salida;
|
||||
ALTER TABLE c_viajes_proveedor DROP INDEX idx_c_viajes_proveedor_fecha_llegada;
|
||||
ALTER TABLE c_viajes_proveedor DROP INDEX idx_c_viajes_proveedor_dni_estado_dates;
|
||||
ALTER TABLE c_cambios_estado DROP INDEX idx_c_cambios_estado_viaje_estado_fecha;
|
||||
```
|
||||
|
||||
Ejecutarlos solo tras confirmar que esos indices no existian antes del despliegue.
|
||||
|
||||
## 9. Checklist final
|
||||
|
||||
- [ ] Tests ejecutados antes del despliegue.
|
||||
- [ ] Backup de tablas creado.
|
||||
- [ ] Codigo actualizado.
|
||||
- [ ] Migracion de indices aplicada sin errores.
|
||||
- [ ] API reiniciada con `restartNodeApi.sh`.
|
||||
- [ ] `/health` responde `200`.
|
||||
- [ ] `/api/trips/active` sin token responde `401`.
|
||||
- [ ] `GET /api/trips?page=1&limit=25` con token responde metadata de paginacion.
|
||||
- [ ] Filtros `status_ids`, `date_from` y `date_to` verificados.
|
||||
- [ ] Logs sin errores nuevos.
|
||||
Reference in New Issue
Block a user