# Despliegue seguro y rendimiento

## Preparación

1. Servir exclusivamente la carpeta `public/`; `app/`, `writable/` y `.env` no deben ser públicos.
2. Copiar `env.production` a `.env` en el servidor y reemplazar dominio, usuario, contraseña y clave de cifrado.
3. Crear un usuario MySQL exclusivo para la aplicación. No utilizar `root`.
4. Dar escritura al usuario de PHP únicamente sobre `writable/`.
5. Instalar dependencias con `composer install --no-dev --optimize-autoloader` y compilar activos con `npm ci && npm run build`.
6. Ejecutar `php spark migrate --all`, `php spark cache:clear` y las pruebas antes de publicar.

## HTTPS y servidor

- Instalar un certificado válido y mantener `app.forceGlobalSecureRequests = true`.
- Si existe proxy inverso, registrar solo su IP en `Config\App::$proxyIPs`; nunca confiar encabezados reenviados de cualquier origen.
- Habilitar HTTP/2 o HTTP/3, compresión Brotli/Gzip y caché de un año para `/build/assets/*`, cuyos nombres contienen hash.
- No cachear páginas HTML autenticadas. La caché de aplicación se reserva para catálogos y resultados sin datos de sesión.

## PHP

- Producción: `display_errors=Off`, `log_errors=On`, `expose_php=Off`.
- Habilitar OPcache: `opcache.enable=1`, `opcache.validate_timestamps=0` y reiniciar PHP después de cada despliegue.
- Configurar límites acordes al expediente: `upload_max_filesize=20M`, `post_max_size=24M`, `memory_limit=256M`.

## Archivos e imágenes

- Las evidencias se redimensionan a un máximo configurable de 2400 px y se recomprimen al cargarse.
- Los archivos se almacenan fuera de `public/` y se entregan en streaming, con ETag y caché privada.
- Respaldar tanto MySQL como `writable/uploads`; probar restauraciones periódicamente.
- Programar limpieza de `writable/cache/importaciones` y `writable/cache/exportaciones` para archivos temporales antiguos.

## Publicación sin interrupción

1. Activar mantenimiento o retirar la instancia del balanceador.
2. Respaldar base de datos y cargas.
3. Publicar una versión etiquetada, instalar dependencias y compilar.
4. Ejecutar migraciones.
5. Limpiar caché y reiniciar PHP para renovar OPcache.
6. Verificar login, obra, estimación, PDF, evidencia y descarga ZIP.
7. Reincorporar la instancia y vigilar `writable/logs`.

Para volver atrás, restaurar primero el código de la versión anterior. Solo revertir migraciones después de confirmar que no eliminan datos nuevos.
