# Deploy y flujo de ramas - EnterFarmaPlus

Guia corta para no re-divergir ni romper prod. El servidor de produccion es `5.161.118.178`, corre `main` y usa Docker. El container FPM es `fpm_softlte_org_pe` y el path de la app es `/var/www/html/farmacia`.

## 1. Flujo de ramas

- Desarrolla en una feature branch por vertical: `feat/clinica`, `feat/veterinary`, etc.
- Para publicar un bloque terminado:

```bash
git checkout main
git merge feat/clinica
git push origin main
```

- No hagas deploy directo con cambios sueltos en `main`.
- Si squasheas una branch a `main`, borrala y crea una nueva desde `main` para el siguiente bloque.
- Si haces cambios chicos directamente en `main`, manten las feature branches sincronizadas con `git merge main` seguido.

## 2. Checklist de deploy

Antes de tocar el servidor, valida que el repo este listo:

```bash
git status --short --branch
./script-update.sh --check main
```

Si el check falla:

- Si hay cambios que si deben publicarse, haz commit y push.
- Si hay cambios que no forman parte del deploy, descartalos o movelos fuera del repo.
- Si `origin/main` avanzo, integra ese cambio con un fast-forward antes de desplegar.

Luego:

1. Compila el flavor de assets que corresponde a la rama antes de commitear:
   - `main` publica assets PROD minificados -> `npm run prod`.
   - feature branches publican DEV -> `npm run development`.
   - Verifica el flavor de la rama con `git show HEAD:public/js/app.js | wc -l`: unas 2 lineas = prod, unas 40k = dev.
2. Commitea solo el cambio intencional. No uses `git add -A` a ciegas.
3. `git push origin main`.
4. En el servidor, ejecuta el unico script de despliegue desde el host:

```bash
/usr/local/sbin/deploy-enterfarmaplus
```

El deploy decide las migraciones en modo `auto`: solo ejecuta `migrate` y
`tenancy:migrate` si el rango de commits que se va a publicar contiene archivos
en `database/migrations/` o en las carpetas de migraciones de los módulos. Un
cambio visual, de JavaScript o de PHP sin cambios de esquema no toca ninguna
base de datos.

Modos explícitos para casos excepcionales:

```bash
MIGRATION_MODE=force /usr/local/sbin/deploy-enterfarmaplus  # fuerza ambas migraciones
MIGRATION_MODE=skip /usr/local/sbin/deploy-enterfarmaplus   # omite ambas migraciones
```

El modo elegido y el resultado (`MIGRATIONS_RUN` o `MIGRATIONS_SKIPPED`) quedan
registrados en el log del deploy.

El repositorio es un bind mount del host. La Deploy Key de GitLab es solo lectura y vive en `/root/.ssh/enterfarmaplus_gitlab_deploy`.

El script:

- bloquea despliegues simultaneos con `flock`;
- cancela si la rama no es `main` o el arbol Git esta sucio;
- acepta solo avance fast-forward desde `origin/main`;
- instala dependencias Composer, sin ejecutar `npm`;
- aplica migraciones centrales y de todos los tenants;
- limpia caches, reinicia workers y corrige permisos solo de runtime;
- valida `https://demo.sysfarma.pe/login`;
- registra commits y resultado en `/var/lib/enterfarmaplus-deploy/` y `/var/log/enterfarmaplus-deploy.log`.

Si el script rechaza el deploy, los motivos habituales son:

- `El arbol de produccion no esta limpio`: hay cambios sin commit en `main`.
- `origin/main no es avance fast-forward`: el remoto avanzo y hay que integrarlo antes.
- `Rama inesperada`: estas parado en otra rama.
- `No existe o no es ejecutable el helper Docker`: falta preparar la instalacion del host.

Comandos de diagnostico:

```bash
git status --short --branch
git log --oneline --decorate --graph --max-count=10 HEAD..origin/main
```

Que hacer despues:

- Si los cambios son tuyos y deben salir, commit + push y vuelve a correr el deploy.
- Si solo faltaba traer el remoto, usa `git pull --ff-only` o integra el fast-forward.
- Si el arbol quedo sucio por temporales, sacalos del repo antes de reintentar.

Reglas duras:

- Nunca usar `route:cache`; rompe las rutas dinamicas por tenant.
- Nunca correr `npm` en el server; los assets van versionados en git.
- Nunca usar `git reset --hard` como deploy normal. Si el preflight falla, primero investiga la causa.

## 3. Migraciones

Si el cambio toca el schema, correr migraciones en todos los tenants, no solo en el nuevo:

```bash
docker exec fpm_softlte_org_pe php artisan tenancy:migrate
```

Regla operativa:

- Si el codigo referencia una columna nueva sin gatearla por el flag del giro, la columna debe existir en todos los tenants.
- Mejor aun: gatea la query por el flag (`is_clinic`, `is_veterinary`, etc.) para que una columna faltante no tumbe a los demas.

## 4. Rollback

El script guarda el commit anterior en:

```bash
cat /var/lib/enterfarmaplus-deploy/previous-commit
```

No existe rollback automatico porque una migracion puede no ser reversible. Si falla un deploy, revisa primero `/var/log/enterfarmaplus-deploy.log`, la BD y el alcance del cambio.

## 5. Si el deploy falla

Orden recomendado:

1. Ver `git status --short --branch`.
2. Ver el log del deploy en `/var/log/enterfarmaplus-deploy.log`.
3. Revisar si el problema es arbol sucio, fast-forward o ramas cruzadas.
4. Corregir la causa y volver a correr el script.

## 6. Seguridad

- La Deploy Key de GitLab es solo lectura y permanece en el host.
- No habilitar permisos generales de SSH o `plink` para automatizaciones.
- El password de `root` usado en soporte debe rotarse. Luego conviene migrar a un usuario de deploy con comando forzado o un job manual de CI protegido.
