Estado: implementación en rama de trabajo, integración cerrada por defecto. No desplegada.
Base: 1174c120dec0982b4c628a353c66cdaeab894b1e, rama original main, árbol original limpio. El HEAD remoto coincidía al consultar git ls-remote origin HEAD el 19/09/2026. Rama de trabajo: feature/client-backups-summary. No se ha hecho push ni merge.
Se admiten exclusivamente las claves exactas Backup diario y Backup diario VPS. Las definiciones comunicadas son Sí/No (optiontype=3), pero no se ha observado todavía el tipo PHP/valor de contratación que entrega el módulo. No se han usado ni IDs de opción ni el tipo de definición como indicadores de activación.
BackupOption::applicable() resuelve los grupos vinculados al producto del servicio autorizado a través de tblhosting.packageid → tblproductconfiglinks.pid/gid → tblproductconfigoptions.gid. No usa LIKE ni una selección global del primer resultado. Las definiciones duplicadas de una clave o un tipo no confirmado cierran el acceso. Si las dos claves están presentes con valores no idénticos (!==), se deniega y se registra OPTION_CONFLICT con el ID del servicio.
La regla provisional es cerrada: enabled y option_values_confirmed deben ser exactamente true; cada clave aplicable debe existir mediante array_key_exists, contener string, entero o booleano y coincidir con identidad estricta con un elemento de su propia lista active_values. Ambas listas se entregan vacías. Las pruebas usan SYNTHETIC_ACTIVE, nunca como supuesto valor real. Las claves ausentes, null, arrays, floats y textos desconocidos no conceden acceso. Se fijará la regla observada y sus tests tras el diagnóstico administrativo separado; no extrapolar automáticamente entre nombres sin evidencia.
La entrada es una función de módulo invocada por WHMCS. El registro ClientAreaCustomButtonArray conserva los cinco botones existentes y añade Backups solo si es elegible. La función vpsmanager_Backups vuelve a comprobarlo. Antes de caché/HTTP, BackupAccess comprueba CurrentUser, cuenta de cliente, permiso products, y pertenencia del servicio en la base de datos. No confunde el usuario delegado con el ID de la cuenta cliente. Versiones sin estas interfaces fallan de forma cerrada. La autorización efectiva del router WHMCS y sus accesos delegados debe comprobarse en staging de la versión instalada.
.git bajo el directorio web. Copiar únicamente el módulo y sus dependencias runtime en una ventana controlada, con la integración desactivada.Config::load() (variable O6H_VPSMANAGER_CONFIG o /etc/open6hosting/whmcs-vpsmanager.php) con la sección backups de config.example.php, manteniendo intactas las opciones de Graphite/API. Permisos ajustados al usuario PHP; nunca guardar credenciales en el repo o en URLs/comandos.cache_directory. Los archivos usan 0600. Directorios públicos o permisivos se rechazan; un error de caché no impide la consulta, pero registra CACHE y elimina la ventaja de caché entre peticiones. Programar limpieza administrativa de JSON antiguos en ese directorio si cambian muchos servicios/mapeos: no se incluye un cron automático.backuppc_host. Crear solo si falta, sin duplicados ni migraciones de dominio: texto, exclusivamente administrativo, no pedido, no factura, no campo de comunicaciones. Guardar un mapeo explícito. El código exige adminonly='on', showorder='', showinvoice='', tipo text; confirmar estos valores de esquema en la versión instalada. No modificar campos automáticamente. La plantilla completa y los emails pueden tener personalizaciones: verificar que nunca exponen el nombre ni el valor.Cache-Control: private, no-store.Una sola petición a endpoint?host=..., exclusivamente el host administrativo validado con \A[A-Za-z0-9][A-Za-z0-9._-]{0,63}\z. No se siguen redirecciones, enlaces ni formularios. TLS verificado, límite por fragmento recibido de 2 MiB, conexión 2 s y total 5 s por defecto. Códigos HTTP distintos de 200 fallan. No hay endpoint público nuevo ni consultas del navegador al origen.
DOM/libxml analiza sin resolución externa y con LIBXML_NONET. La identidad se exige en el único h1 exacto del detalle. Las tablas se reconocen por cabeceras; tamaños exigen el grupo Totals; la unión es por número interno. Se rechazan duplicados. Las filas y tablas pueden reordenarse. El número de copia, host, conteo de ficheros, HTML, enlaces y configuración no llegan a la plantilla.
El contrato público contiene disponibilidad, actualización, indicación de datos antiguos, zona, actividad reconocida, total/desglose, inicio de última completa, antigüedad en horas y hasta cinco filas con inicio/tipo/duración/tamaño/incidencias. Todas las variables se escapan en HTML. La plantilla Smarty recibe únicamente HTML propio ya escapado y reconstruido; no HTML del origen.
Las fechas son inicios, nunca finales calculados. Se normalizan a timestamps con zona explícita; minutos inexistentes o ambiguos por cambio horario fallan de forma cerrada porque el HTML no incluye offset. El formato presentado es d/m/Y H:i T, con zona IANA visible; validar coherencia con el tema/locale instalado. MiB/1024 son GiB lógicos aproximados, no ocupación ni transferencia. Filled no modifica incidencias. Cuatro contadores presentes a cero significan «Sin incidencias registradas»; alguno positivo, «Con incidencias»; faltantes, «Información no disponible». No se suma un total de errores. Idle significa solo ausencia de actividad; estados desconocidos se omiten. No hay alarmas SLA ni promesas de restauración.
Una tabla reconocida con cabecera completa y sin filas se trata como cero retenido (caso sintético probado); la ausencia de tabla es error, nunca cero. No se han aportado ejemplos reales de detalle sin copias: cualquier otra estructura fallará cerrada hasta disponer de evidencia.
La caché contiene datos normalizados sin credenciales ni host. Su clave es SHA-256 de versión/configuración/servicio/host. Autorización y contratación se repiten antes de leerla. TTL 120 s; ante fallo, datos antiguos hasta 900 s desde su obtención, con aviso y fecha originales. Caducados: indisponibilidad. Cambios de mapeo/destino/configuración no reutilizan entradas anteriores. Logs administrativos: solo códigos fijos y servicio; no excepciones ni respuestas del origen.
Desactivar backups.enabled inmediatamente en la configuración privada. Restaurar el módulo respaldado o distribuir el archivo runtime del commit base 1174c120dec0982b4c628a353c66cdaeab894b1e desde un checkout de preparación. No hacer reset destructivo en un árbol compartido. Limpiar la caché privada de esta integración y la caché de plantillas WHMCS según el procedimiento de la instalación. Retirar únicamente la sección de configuración nueva si se desea; conservar Graphite/API. No hay migraciones ni cambios en contratación que revertir. Puede conservarse el campo administrativo desactivado/documentado, o retirarlo solo tras respaldar sus valores y aprobarlo. Retirar el diagnóstico temporal y restaurar la función administrativa si sigue instalado.
Comprobar que desaparece Backups y que panel/gráficas y botones existentes conservan comportamiento. No confundir un rollback de código con revertir contratos.
Estas referencias no sustituyen la validación de la versión y tema instalados.