v1.0.26 - 2026-09-20
- simplificada la configuración inicial de Google Drive con un asistente de una sola vez dentro de la propia interfaz
- añadido botón dedicado "Guardar acceso Google" para guardar Client ID/Secret sin validar ni modificar FTP, destino local u otros ajustes de producción
- la conexión OAuth ya no ejecuta un guardado global de configuración; puede autorizar Google aunque existan campos FTP/local pendientes de edición
- cuando OAuth ya está configurado, los campos técnicos se pliegan automáticamente y el flujo normal queda reducido a "Conectar con Google", seleccionar/crear carpeta y ejecutar el backup
- si cambia el Client ID o Client Secret, se invalidan de forma segura los tokens y la carpeta asociada para evitar reutilizar una autorización de otra aplicación
- mantenido el permiso drive.file y el Google Picker oficial para seleccionar carpetas sin Finder ni Explorer
- actualizada la guía GOOGLE_DRIVE_SETUP.txt con el flujo exacto para Google Auth Platform y las URI de redirección de cada instalación
- se conserva sin cambios el proveedor Local y todas las correcciones de reanudación FTP/ZIP de las versiones anteriores

v1.0.25 - 2026-09-20
- añadido Google Drive como destino alternativo de respaldos, totalmente separado del almacenamiento local existente para no alterar el flujo estable de Windows/macOS
- autenticación Google mediante OAuth 2.0 en el navegador; la aplicación nunca solicita ni almacena la contraseña de la cuenta Google
- soporte del permiso limitado drive.file y almacenamiento cifrado de Client Secret, refresh token y access token dentro del sistema de configuración existente
- selector de carpeta existente mediante Google Picker y posibilidad de crear una nueva carpeta raíz directamente en Mi unidad; la configuración conserva el folder_id real y no rutas locales
- las carpetas por sitio/subsitio se crean o reutilizan automáticamente bajo la carpeta raíz elegida en Google Drive
- añadidas subidas reanudables en bloques de 8 MiB para backups grandes, con recuperación de sesión y continuación desde el offset confirmado por Google
- el archivo descargado desde FTP se mantiene únicamente como staging temporal; se elimina después de que Drive confirma la carga completa y se conserva cuando Drive falla para evitar volver a descargar gigas desde FTP
- si Drive ya contiene un archivo con el mismo nombre y tamaño dentro de la carpeta destino, el worker lo omite sin volver a descargarlo desde FTP
- Google Drive funciona por API y navegador: no requiere Google Drive Desktop, no monta unidades y no usa Finder ni Explorer para seleccionar la carpeta remota
- el modo Google Drive desactiva limpieza destructiva/remota en esta primera versión; el modo Local conserva su comportamiento anterior
- añadidos endpoints dedicados api/google_drive.php y api/google_oauth_callback.php, módulo includes/google_drive.php y guía GOOGLE_DRIVE_SETUP.txt
- compatibilidad sin dependencia obligatoria de mbstring; el cliente HTTP usa cURL cuando está disponible y streams PHP como fallback

v1.0.24 - 2026-09-20
- Corregido falso positivo que marcaba ZIP válidos como "ZIP inválido o corrupto" después de una transferencia FTP completa.
- La integridad de transporte ahora se decide por coincidencia exacta entre SIZE remoto y tamaño local; ZipArchive/CHECKCONS queda solo como diagnóstico no destructivo.
- Un resultado inconcluso de ZipArchive ya no borra el backup descargado, no fuerza redescarga y no convierte el item en error.
- Copias locales heredadas con tamaño remoto/local exacto ya no se eliminan por limitaciones de ZipArchive, ZIP64 o archivos multipart.
- Descarga directa, worker y descarga por navegador aplican la misma política para evitar falsos positivos entre rutas de descarga.
- Corregida también la validación JavaScript de carpetas locales en macOS/navegador: una inspección ZIP no concluyente ya no borra ni vuelve a poner como pendiente un archivo cuyo tamaño coincide exactamente con el remoto.

v1.0.23 - 2026-09-20
- corregida la reanudación FTP: un reintento ya no puede truncar el .part y volver a descargar desde cero un archivo de varios GB; la escritura usa stream local con fseek + ftp_nb_fget y conserva exactamente el offset existente
- si el servidor FTP rechaza REST/reanudación, el parcial se conserva intacto y ese intento termina con error controlado; nunca se descartan gigas ya descargados para reiniciar silenciosamente el mismo archivo
- si un .part del job ya tiene exactamente el tamaño remoto, se promueve y valida directamente sin ejecutar otro RETR ni volver a descargar el archivo
- eliminada la segunda descarga completa automática cuando un ZIP termina pero falla validación: el elemento se marca como error y el worker continúa con el siguiente archivo
- el porcentaje de un archivo o trabajo activo usa floor y queda limitado a 99%; el 100% solo aparece después de que el archivo/trabajo haya terminado y sido validado
- se mantiene el aislamiento por job de locks y parciales introducido en v1.0.22, junto con las protecciones contra workers huérfanos

v1.0.22 - 2026-09-20
- eliminado el bloqueo global de workers que podía dejar la aplicación inutilizable aunque job.json ya no tuviera un trabajo activo
- cada trabajo usa desde ahora su propio flock de ejecución; un PHP huérfano de una versión anterior no puede impedir el inicio de un job nuevo
- cada job descarga a un archivo temporal .part.<job_id> independiente, evitando que un worker antiguo y uno nuevo escriban sobre el mismo parcial
- añadido control final antes del rename: si el worker perdió la propiedad lógica del job durante una espera de red, descarta su parcial y nunca publica un archivo final
- los locks por job se liberan y limpian también mediante shutdown handler ante terminaciones anómalas de PHP
- el lock global heredado de v1.0.21 se detecta únicamente para TRACE y se aísla automáticamente; ya no requiere esperar ni reiniciar Apache/MAMP
- los errores de arranque del worker se muestran en el banner de estado y ya no mediante alert() bloqueante del navegador
- se mantienen la reanudación FTP, timeout de E/S, rollback transaccional, sincronización del updater y compatibilidad Windows/macOS de v1.0.21

v1.0.21 - 2026-09-20
- corregido el bloqueo de descargas grandes que podía dejar config/job.lock.run retenido cuando ftp_nb_continue permanecía esperando durante minutos u horas cerca del final de un archivo
- separado el timeout de inactividad de E/S del tiempo total de descarga: cada operación FTP devuelve control al worker como máximo en 45 segundos, mientras archivos de varios GB pueden seguir descargándose y reanudarse sin límite artificial del tamaño total
- las transferencias sin avance fuerzan reconexión y continúan desde el archivo .part en lugar de dejar el worker colgado
- el estado del trabajo considera el flock real del worker además del heartbeat, evitando falsos estados "interrumpido" mientras el proceso todavía existe
- job_start ya no crea un segundo trabajo si el worker anterior todavía posee el lock de ejecución
- los workers actualizan job.json únicamente si el id del trabajo sigue coincidiendo; un worker antiguo nunca puede sobrescribir un trabajo nuevo
- el worker adquiere job.lock.run antes de publicar su marca de arranque, eliminando falsos positivos de worker iniciado
- mantenidas las correcciones v1.0.20 de rollback transaccional y sincronización del estado del actualizador

v1.0.20 - 2026-09-20
- rollback automático transaccional corregido: si una instalación falla después de introducir archivos nuevos, esos archivos se eliminan al restaurar el snapshot anterior y no quedan residuos de la versión fallida
- sincronización del estado automático corregida: installed_version y latest_version se actualizan con la versión realmente instalada después de una actualización manual
- al cargar la aplicación o consultar el estado del updater se autocorrige cualquier update_auto_state.json heredado que haya quedado atrasado respecto a includes/version.php
- añadido núcleo de actualizador versionado v1.0.20 para evolucionar el updater sin reemplazar en caliente los archivos protegidos de v1.0.19
- el frontend v1.0.20 usa api/updater_v1020.php; instalaciones nuevas conservan alias compatibles y las actualizadas desde v1.0.19 mantienen intacto su núcleo protegido anterior
- TRACE EXTREMO reconoce también el endpoint versionado del actualizador
- sin cambios funcionales en FTP, escaneo, retención, descarga de respaldos ni selección de carpetas de Windows/macOS

v1.0.19 - 2026-09-20
- corregido el fallo por el que la descarga se quedaba en "pendiente" para siempre: el lanzamiento del worker ya no se da por bueno solo porque se abriera el socket
- job_start.php espera y confirma la marca de arranque real del worker antes de responder; si no arranca, devuelve el motivo exacto en vez de un ok falso
- api/worker.php escribe su marca de arranque (arranque, pid, latido) nada más autorizarse, antes del bloqueo, para que ningún fallo posterior deje el trabajo mudo
- si otro proceso retiene config/job.lock.run sin latido, el trabajo pasa a error con instrucciones en pantalla; si el otro worker sigue vivo, el duplicado se retira en silencio como antes
- respaldo CLI reescrito con proc_open (popen como segunda opción) y salida a NUL/dev-null: funciona en Windows 10/11 con start /B y en macOS/Linux sin dejar la conexión de Apache colgada
- detección del binario de PHP ampliada: MAMP, Homebrew (Intel y Apple Silicon), MacPorts, sistema, XAMPP, Laragon y WAMP
- el lanzamiento HTTP usa stream_socket_client, acepta certificados locales autofirmados, comprueba la escritura completa de la petición y no cierra el socket de golpe (algunos Apache descartaban la petición antes de ejecutar worker.php)
- las salidas por trabajo inexistente o clave inválida quedan registradas en el error_log del servidor
- la interfaz muestra el estado real del trabajo cuando Iniciar falla, con el mensaje del servidor
- sin cambios en FTP, escaneo, retención, validación de ZIP, conciliación macOS, updater protegido ni flujo de Windows

v1.0.17 - 2026-09-20
- macOS híbrido corregido de extremo a extremo: DirectoryHandle cuando existe; ruta local real de PHP cuando el navegador solo entrega FileList
- el selector fallback de macOS ahora enlaza la carpeta elegida con su ruta POSIX real usando huella de archivos y Spotlight/rutas habituales, sin adivinar por nombre
- scan.php ya no anula siempre directorio_local en macOS; usa local_mode=server o local_mode=browser según la capacidad real disponible
- cuando macOS usa ruta local real, PHP compara nombre/tamaño/ZIP/manifiesto, elimina copias inválidas y el worker vuelve a descargarlas con el mismo nombre sin crear duplicados (1)
- el modo servidor se reutiliza también para descargar en macOS cuando la carpeta quedó resuelta y escribible
- si la carpeta no puede resolverse con seguridad, la aplicación no finge capacidad de borrado: conserva el modo navegador y lo deja explícito en TRACE
- Windows conserva IFileOpenDialog, comparación local PHP, worker, reanudación, validación y limpieza sin cambios de arquitectura
- TRACE EXTREMO registra el modo local efectivo (server/browser), resolución de carpeta y cada decisión de sincronización

v1.0.16
- corregida la validación de Guardar configuración en macOS: ya no exige directorio_local porque el destino puede ser un permiso del navegador sin ruta POSIX visible para PHP
- la carpeta elegida mediante el fallback nativo de Safari/Firefox/Brave sin File System Access se conserva después de guardar configuración durante la sesión actual y sigue disponible para comparar los respaldos locales
- el selector con DirectoryHandle sigue persistiendo el permiso en IndexedDB y ahora limpia cualquier selección fallback anterior para evitar estados ambiguos
- en macOS Iniciar se bloquea de forma segura si no existe un DirectoryHandle autorizado ni un FileList de carpeta activo; así no se marcan todos los respaldos remotos como nuevos por falta de acceso local
- el TRACE EXTREMO registra explícitamente cuando el escaneo se bloquea por no tener acceso a la carpeta local
- se mantienen sin cambios funcionales FTP, retención, updater protegido y flujo de Windows

v1.0.15
- añadido TRACE EXTREMO correlacionado de extremo a extremo con session_id, request_id, secuencia, timestamp UTC, tiempos, PID y memoria actual/pico por evento
- el mismo interruptor de Depuración activa ahora el nivel máximo: trace, debug, info, warn, error y fatal
- el panel del navegador conserva hasta 25.000 eventos y registra entorno del navegador, plataforma, viewport, red, peticiones, respuestas, polling, conciliación macOS y descargas binarias
- cada petición TRACE propaga debug_session al backend para unir en una sola sesión navegador, API, PHP, FTP y workers
- añadido registro persistente NDJSON en logs/debug, con rotación por segmentos de 50 MiB y limpieza de trazas de más de 14 días
- añadido botón TRACE para descargar el registro persistente completo del servidor correspondiente a la sesión activa
- redacción profunda de contraseñas, tokens, secretos, Authorization, cookies y credenciales embebidas en querystrings/texto antes de guardar o mostrar eventos
- instrumentadas decisiones de sincronización archivo por archivo: rutas, tamaños, mtimes, manifiesto, ZIP, SHA-256, omitir/pendiente, eliminación y motivo exacto
- instrumentadas conexiones FTP, métodos de listado, cache hits, metadatos, retención, reintentos, offsets de reanudación, progreso y validación de transferencias
- el worker hereda la sesión TRACE del trabajo para que la descarga en segundo plano quede correlacionada aunque el navegador se cierre
- añadida captura de errores PHP incluidos warnings suprimidos, notices, deprecated y fatales, además de errores y promesas rechazadas de JavaScript
- el updater estable protegido permanece intacto; sus solicitudes/respuestas se trazan desde el navegador y debug_log activa compatibilidad de trazado básico sin reemplazar el núcleo protegido
- se conservan sin cambios funcionales la conciliación real de macOS, el selector de destino, la lógica de archivos corruptos, el escaneo FTP, la retención y el flujo de Windows

v1.0.14
- macOS compara realmente los respaldos remotos contra la carpeta elegida mediante el DirectoryHandle del navegador antes de marcarlos como nuevos
- Safari/Firefox también comparan los archivos seleccionados mediante el FileList del selector de carpeta; si una copia es inválida queda pendiente para reemplazarla al guardar
- se reconocen copias válidas tanto en la raíz de la carpeta elegida como en subcarpetas por sitio para conservar compatibilidad con respaldos anteriores
- archivos locales vacíos, de tamaño distinto o ZIP estructuralmente corruptos se eliminan y permanecen pendientes para descargarse de nuevo
- el resumen, las fichas por sitio y el contador de pendientes se recalculan después de la comparación local real en macOS
- la comparación se repite al reconstruir la pantalla desde el último escaneo, evitando falsos "nuevos" después de recargar
- tras cada descarga en macOS se valida la copia escrita; si falla se elimina y se repite una descarga completa una vez
- se conserva sin cambios el escaneo FTP, la retención, el updater y el flujo de Windows

v1.0.13
- corregido el modo macOS para que vuelva a mostrarse el campo Directorio local de destino con el botón Examinar...
- eliminadas reglas CSS heredadas de v1.0.11 que ocultaban por error el selector de directorio en macOS
- se mantiene el selector nativo del navegador en macOS y el flujo existente de Windows

v1.0.12
- restaurado el selector de directorio de descarga en macOS; ya no se sustituye por una tarjeta informativa
- en macOS Chromium/Brave/Edge se usa el selector nativo del navegador con permiso de escritura y el destino se conserva en IndexedDB
- Safari/Firefox usan su selector nativo de directorios como fallback y el cuadro Guardar como del navegador para la escritura final
- si una copia local existente es inválida, vacía, corrupta o deja de coincidir con el remoto, se elimina y vuelve a quedar pendiente
- un ZIP heredado del mismo tamaño ya no se acepta automáticamente: se valida antes de crear el baseline
- si una descarga termina corrupta o con tamaño incorrecto, la copia se elimina y se realiza un segundo ciclo completo de descarga desde FTP
- las descargas gestionadas por el navegador en macOS se validan en un temporal antes de entregarse; si el temporal es inválido se borra y se vuelve a descargar

v1.0.11
- macOS descarga los respaldos mediante el navegador con Content-Disposition attachment, usando el diálogo nativo de guardado del navegador
- macOS ya no exige ni muestra un directorio_local para poder descargar
- Windows conserva el flujo de descarga local y su selector moderno de carpetas
- la configuración guarda client_platform para preservar una ruta de Windows cuando la app se usa desde macOS
- añadido endpoint api/browser_download.php para transmitir cada backup FTP directamente al navegador sin guardarlo primero en una ruta local del servidor

v1.0.10
- macOS ya no abre Finder, AppleScript ni una app temporal al escoger el directorio de descarga
- en macOS el botón Examinar abre directamente el explorador de carpetas dentro de iRaffe, sin salir del navegador
- macOS inicia el explorador interno en /Users cuando todavía no hay una carpeta configurada
- Linux mantiene el explorador interno y Windows conserva el selector moderno IFileOpenDialog
- la detección de plataforma decide el selector antes de hacer ninguna llamada externa, para que la apertura sea inmediata y fluida

v1.0.9
- corregido fallo de v1.0.8 que impedía Iniciar cuando la ruta local pertenecía a otro sistema operativo
- Iniciar vuelve a escanear los FTP aunque todavía no haya una carpeta local válida para el sistema actual
- sin carpeta local válida se omite solo la comparación local; el descubrimiento remoto sigue funcionando
- Descargar permanece bloqueado hasta seleccionar una carpeta válida para Windows/macOS/Linux
- una ruta de otro sistema operativo ya no se borra de la configuración cifrada al abrir la aplicación
- get_config oculta temporalmente la ruta incompatible en la interfaz sin destruirla

v1.0.8
- detección explícita del sistema operativo real: Windows, macOS o Linux
- las rutas heredadas de otro sistema operativo se descartan automáticamente (por ejemplo C:\... en macOS)
- el explorador interno de macOS inicia en / cuando no hay una ruta POSIX válida
- selector nativo de macOS reforzado con una applet GUI temporal vía LaunchServices y fallback a osascript
- el selector de Windows mantiene IFileOpenDialog moderno
- la respuesta de depuración informa plataforma, selector utilizado y ruta de fallback

v1.0.7
- Windows ahora usa el selector moderno nativo de carpetas basado en IFileOpenDialog/FOS_PICKFOLDERS
- eliminado FolderBrowserDialog/WinForms del selector de directorios en Windows
- se conserva Finder nativo en macOS y el explorador interno como fallback
- el selector moderno respeta la carpeta inicial, permite crear carpetas y valida acceso de escritura

v1.0.6
- añadido selector nativo de carpetas en macOS mediante Finder/osascript
- el botón Examinar intenta primero el selector nativo en Windows y macOS y usa el explorador interno como fallback
- el campo de directorio local ya no está limitado visualmente a Windows y permite rutas POSIX de macOS/Linux
- la creación de carpetas respeta reglas de nombres Windows o POSIX según el sistema operativo
- en instalaciones nuevas sobre macOS/Linux ya no se propone C:\backups_diarios como ruta predeterminada
- se informa si MAMP/PHP no tiene permiso de escritura sobre la carpeta elegida

v1.0.5
- eliminado el icono delante del nombre iRaffe FTP Backups
- en modo claro la rueda de configuración ahora se muestra sin círculo ni fondo alrededor
- en modo claro los botones activos y el control segmentado usan azul con tipografía blanca
- refinados botones secundarios claros para mantener fondo blanco y lectura limpia

v1.0.4
- refinado el modo claro con una paleta más equilibrada y menos agresiva sobre fondo blanco
- suavizados los botones principales/secundarios y el control segmentado en tema claro
- la rueda de configuración en modo claro ahora usa líneas oscuras y fondo neutro, sin burbuja azul sólida
- ajustado el encabezado, el badge de marca y los componentes claros para un aspecto más limpio y profesional

iRaffe FTP Backups — Cambios

v1.0.3
- Eliminado el botón Resumen: el panel principal vuelve a ser la vista base de la aplicación.
- Configuración pasa a abrirse desde un botón de rueda dentada en la cabecera.
- Añadido selector de tema claro/oscuro con sol y luna; la preferencia queda guardada en el navegador.
- Añadido modo claro completo mediante variables visuales para fondo, paneles, formularios, tablas, modales y estados.
- Al salir se elimina el historial visible de la sesión: last_scan.json se descarta y job.json terminado se elimina inmediatamente.
- Si se sale durante una descarga, el trabajo se oculta de inmediato, se cancela y el worker elimina job.json al finalizar.
- Se conservan las correcciones FTP/DNS, validación y rendimiento de las versiones anteriores.

v1.0.2
- Corregidos falsos positivos de DNS en conexiones FTP.
- La aplicación ya no usa gethostbyname() como barrera previa ni cancela una conexión antes de probar el FTP real.
- ftp_connect()/ftp_ssl_connect() se ejecutan primero; solo si fallan se hace diagnóstico DNS.
- El diagnóstico posterior distingue entre host no resuelto y host resuelto con FTP/puerto inaccesible.
- Eliminado el mensaje engañoso que afirmaba que el dominio podía no existir sin haber intentado la conexión FTP.
- Se conservan las mejoras de rendimiento y validación de backups de v1.0.1.

v1.0.1
- Corregida la lentitud del primer escaneo tras migrar: los backups heredados ya no calculan SHA-256 completo durante la exploración.
- Los backups existentes se registran mediante un baseline ligero con tamaño remoto/local y mtimes remoto/local.
- Si un archivo heredado cambia localmente después del baseline, deja de considerarse sincronizado y se vuelve a validar/descargar.
- Los archivos descargados por la aplicación siguen registrándose con SHA-256 completo después de una descarga verificada.
- Se mantiene intacto el auto-descubrimiento de WordPress, incluidos WordPress anidados y múltiples carpetas wp-content/backups.

v1.0.0
- Nueva línea de versionado 1.0.x.
- Actualizaciones automáticas desde https://carlosraffe.sensatoweb.com/actualizaciones/ibackup/info.php.
- Comprobación automática al abrir la aplicación y antes de la tarea programada de backup.
- Descarga y validación de actualización por tamaño, SHA-256, estructura ZIP y versión interna.
- Snapshot automático antes de cada actualización.
- Rollback automático si falla una instalación.
- Restauración manual de versiones anteriores desde Configuración > Actualizaciones.
- Un rollback manual pausa la actualización automática para no deshacer la restauración.
- Copia limpia de código v1.7.0 disponible como primer rollback, sin configuración ni credenciales.
- Validación de backups remotos/locales por tipo de archivo, tamaño remoto y manifiesto de sincronización.
- SHA-256 local persistente para detectar copias locales alteradas o corruptas.
- MLSD/RAWLIST priorizados sobre NLIST para reducir falsos positivos.

v1.0.1 - hotfix de actualización en Windows/MAMP
- Corregido el fallo "No se pudo activar api/update.php" al actualizar desde v1.0.0.
- Se reemplaza el updater autorreemplazable por un núcleo estable: api/updater.php + includes/updater_core.php.
- El núcleo estable queda protegido para que futuras actualizaciones no intenten sobrescribir archivos que están ejecutándose.
- Se mantiene la mejora de rendimiento del baseline de backups heredados sin SHA-256 masivo durante el escaneo.
