83 lines
12 KiB
Markdown
83 lines
12 KiB
Markdown
|
|
# R2.0 — Contrato de despliegue, activación y rollback
|
|||
|
|
|
|||
|
|
> **Ratificación posterior — 24 de octubre de 2026:** D01–D10 y D04-R ratificadas en los términos recomendados de R2.0; variante A, Resource único con `scope` explícito. Solo se autoriza implementar R2.1a. El registro vigente de alcance y evidencias está en [11 — Lectores compatibles](11-r2-1a-lectores-compatibles.md). Los estados «propuesto», «recomendado» y «pendiente» del cuerpo se conservan como evidencia de la versión documental inicial y quedan actualizados por este registro; ratificación conceptual no equivale a ejecución de R2.1b–R2.6.
|
|||
|
|
|
|||
|
|
Estado: **RECOMENDADA D10**, con precondiciones obligatorias por compatibilidad. No hay flags, scripts ni despliegue creados en R2.0. Se distingue implementar soporte, ejecutar DDL y habilitar uso; son hitos diferentes aunque compartan una fase de desarrollo.
|
|||
|
|
|
|||
|
|
## 1. Versiones y puertas
|
|||
|
|
|
|||
|
|
| Versión conceptual | Capacidad | Compatibilidad de datos |
|
|||
|
|
| --- | --- | --- |
|
|||
|
|
| V0 actual | Solo compañía, UUID companyId y DTO Resource legacy | Solo recursos locales |
|
|||
|
|
| V1/R2.1a | Lectores/mapper preparados para legacy y scoped; respuestas locales legacy intactas | Legacy o scoped completo; ningún global creado |
|
|||
|
|
| V2/R2.1b–R2.2 | Esquema scoped, autorización/lectores por propósito, propagación y secundarios compatibles | Globales legibles; escrituras globales deshabilitadas hasta G3 |
|
|||
|
|
| V3/R2.3 | Catálogo global con permisos y proyecciones | Globales persistidos, sin asociación global operativa hasta G4/G5 |
|
|||
|
|
| V4/R2.4–R2.5 | Guardado y lectura global de software/perfil + vistas/contextos compatibles | Datos operativos locales con referencias globales |
|
|||
|
|
|
|||
|
|
Son nombres de capacidades, no tags/commits de releases que ya existan. Una instancia que ejecuta migraciones al arrancar no queda habilitada para modificar esquema porque el lector tolere scope: R2.1 separa activación de DDL del despliegue de código, siguiendo migraciones explícitas. El estado de esquema se verifica, no se inventa mediante un flag que contradiga la BD. [module.ts:39](../../../modules/resources/src/api/module.ts#L39) [identity-runtime.ts:17](../../../apps/server/src/infrastructure/http/identity-runtime.ts#L17).
|
|||
|
|
|
|||
|
|
Flags de negocio **propuestos**, gestionados en configuración validada de servidor: `RESOURCE_GLOBAL_CATALOG_ENABLED`, `RESOURCE_GLOBAL_SOFTWARE_ENABLED`, `RESOURCE_GLOBAL_PROFILE_ENABLED`, boolean false inicial. No se cambia config en R2.0 ni se usan variables del navegador como autorización. Gates de lectura no usan estos flags: resolución de registros ya persistidos permanece disponible cuando se apagan. El cliente recibe capacidades efectivas mínimas para UX, no permisos que pueda editar.
|
|||
|
|
|
|||
|
|
Estados permitidos: catálogo=false implica no crear/editar globales ni nuevas asociaciones globales; lectura/status de desactivación administrativa de seguridad de un global ya existente siguen disponibles con manage. Software/perfil solo pueden activarse si esquema/seguridad/catálogo y lectores están listos. Si se apaga catálogo tras uso, ambas flags consumidoras quedan efectivamente false para **nuevas asociaciones/reconfiguraciones dependientes**; no impide notas/retirada ni lectura/needsReview de existentes. No alterar legacy local por esas flags.
|
|||
|
|
|
|||
|
|
## 2. Secuencia y gates verificables
|
|||
|
|
|
|||
|
|
| Gate/etapa | Precondiciones | Acción posterior propuesta | Postcondiciones / evidencia |
|
|||
|
|
| --- | --- | --- | --- |
|
|||
|
|
| G0 contrato | D01 y alcance D02 ratificados para preparar R2.1; ninguna autorización de ejecutar código en esta tarea | Planificar prompt R2.1 con contrato y tests | Decisiones registradas, variante scope conocida, cambios excluidos fijados |
|
|||
|
|
| G1 lectores antes de DDL, R2.1a | Baseline limpio/revisado, tests legacy y datos test aislados | Desplegar adaptador lector dual de esquema, DTO local exacto; flags false | V1 lee legacy sin seleccionar columna ausente; todos los lectores inventariados preparados; V0 aún compatible porque solo locales |
|
|||
|
|
| G2 persistencia, R2.1b | VERSION/SHOW CREATE/FKs/índices y CHECK/foreign_key_checks ON de 11.8 ensayados; backup/restauración probado | Ventana de cambios y pausa de escrituras afectadas; expansión, backfill company, nulabilidad raíz, CHECK/FKs/índices | Cero pares inválidos/cross-scope; IDs e historia legacy intactos; scope global vacío; constraints restauradas; no globales permitidos |
|
|||
|
|
| G3 seguridad/resolución, R2.2 | D03/D04/D05/D09 ratificados; todos los backends al menos compatibles V2; lock order ensayado | Guard manager/plantillas, candidatos/batch y DTO mínimos; prueba de sesión/IDOR/propósito | T01–T15/T19–T24 pertinentes pasan; sin backend V0; CRUD global aún cerrado |
|
|||
|
|
| G3b catálogo, R2.3 | UI/backend catálogo completos, preflight de plantilla/campos, privacidad, alta idempotente, snapshot de rollback compatible | Activar flag catálogo solamente | Manager crea un Resource global; no copias locales; public/admin separados; cero asociaciones globales nuevas aún |
|
|||
|
|
| G4 software, R2.4 | Lectores de software/historia/activo/puesto/entorno/procesos, licencia local y negociación de clientes disponibles; canario test y seguridad pasan | Activar flag software para despliegue compatible | Instalación A puede usar global, B independiente; licencia local no se comparte; inactivo legible; fallback de cliente legado explícito |
|
|||
|
|
| G5 perfiles, R2.5 | Lectores/form/historia/perfil/puesto/entorno/procesos completos, schema correlacionado application-only | Activar flag perfil | Configuración A usa global con versión/delivery propios; OS global/local rechazado por perfil |
|
|||
|
|
| G6 coexistencia, R2.6 | D07 técnico ratificado y lecturas estables | Activar avisos y elección explícita en nuevas asociaciones | Locales permanecen, historia intacta; consolidación con mutación aún no existe |
|
|||
|
|
|
|||
|
|
G1/G2 son subetapas de R2.1, sin invertir orden lógico de las fases. R2.2 se puede desarrollar antes en preparación, pero no activar contra un schema incompleto. Ninguna versión de un servidor que no pueda leer globales debe compartir tráfico o tareas de propagación después del primer global. No hay despliegue «gradual por instancia» que mezcle V0 con globales usando un flag solo frontend.
|
|||
|
|
|
|||
|
|
## 3. Matriz de versiones mixtas
|
|||
|
|
|
|||
|
|
| Estado de BD | V0 backend | V1 lector compatible | V2+ lector por propósito | Cliente JS legacy |
|
|||
|
|
| --- | --- | --- | --- | --- |
|
|||
|
|
| Legacy, sin scope | P operación local actual | P adaptador pre-schema | C con modo legacy y flags false | P |
|
|||
|
|
| Scoped completo, solo locales | C solo si defaults/FKs/SQL legacy ensayados y flags false | P | P, global writes off | P DTO exactos |
|
|||
|
|
| Scoped con globales, sin vínculos globales | R: propagación/lectores transversales pueden fallar | C solo si incluye toda lectura global requerida; no asumirlo por nombre V1 | P | P en flujos locales; catálogo nuevo requiere cliente nuevo |
|
|||
|
|
| Scoped con vínculos globales | R | R si carece de resolución/guards necesarios | P | C solo local puro; 409 upgrade para respuesta/registro que necesite global |
|
|||
|
|
| Esquema parcial/interrumpido | R servicio público | R salvo proceso de migración controlado | R servicio público | Indisponibilidad explícita, no datos parciales |
|
|||
|
|
|
|||
|
|
P/C/R se usan como permitido/condicionado/rechazado. No hay promesa de soporte indefinido para JavaScript antiguo: antes de G4/G5 exigir recarga coordinada y header propuesto de versión. Las respuestas de operación con global sin capacidad de cliente se rechazan uniformemente con RESOURCE_CLIENT_UPGRADE_REQUIRED; jamás se sirve una lista recortada que oculte relaciones. El header no acredita permisos y un actor malicioso que lo falsifique sigue sujeto a servidor. Ver 04.
|
|||
|
|
|
|||
|
|
## 4. Preflight y monitorización por gate
|
|||
|
|
|
|||
|
|
Capturar artefactos sin secretos: versión código/esquema, conteos por scope y tablas, schema de constraints, checks/FKs ON, plantilla/stockKey/fields, digest del paquete de despliegue y resultados de pruebas. No exportar nombres/valores reales de usuarios/clientes para el checklist. Backfill debe dejar mismo número de Resource, IDs y revisiones que baseline, todos los previos company y dueño válido.
|
|||
|
|
|
|||
|
|
Comprobaciones SQL futuras de integridad, no ejecutadas aquí: combinaciones scope/owner inválidas; global sin serie Aplicación; global con campos locales/integración; operativos NOT NULL; local B referenciado en operación A; licencia owner distinto de instalación; filas huérfanas, índices/FKs faltantes; revisiones de última posición inconsistentes. Scope del producto y dueño de relación se evalúan por separado, no por un join que excluya NULL silenciosamente.
|
|||
|
|
|
|||
|
|
Observar requestId, operación, resultado, código de negocio y duración/locks agregados sin características/notas ni cuerpos sensibles. Vigilar 401/403, 404/409 por elegibilidad, upgrade_required, corrupción de mapper, timeout/deadlock y divergencias de total/fila en dashboard. No atribuir un umbral numérico ni probabilidad sin baseline; cualquier fallo de seguridad/integridad bloquea el gate y requiere resolver antes de avanzar. Errores técnicos no se transforman en vacío para que el canario «pase».
|
|||
|
|
|
|||
|
|
## 5. Rollback y puntos de no retorno trivial
|
|||
|
|
|
|||
|
|
| Punto | Retirada segura | Lo prohibido |
|
|||
|
|
| --- | --- | --- |
|
|||
|
|
| Antes G2 | Retirar V1, datos siguen legacy | Activar global writes para probar |
|
|||
|
|
| G2 completo, cero globales | Apagar flags, detener nuevas escrituras, verificar cero NULL/global y compatibilidad; revertir aplicación a legacy solo si DDL y writers se ensayaron | Revertir NOT NULL sin precheck/FKs; asumir transaction revierte DDL |
|
|||
|
|
| Primer Resource global persistido (G3b) | Detener creación/edición y nuevos vínculos; mantener lector compatible y controles; rollback de código a release global-compatible o corrección hacia delante | Volver a V0 aunque no haya instalaciones, borrar global automáticamente, usar compañía ficticia |
|
|||
|
|
| Primera instalación/configuración que referencia global | Detener nuevas asociaciones y reconfiguraciones dependientes, mantener lectura/notas/retirada/historia | Desactivar resolución con el flag, eliminar relaciones, cambiar owner o reescribir UUID/snapshots |
|
|||
|
|
| Adopción con mutación futura | Solo operaciones compensatorias aprobadas tras revalidar cambios posteriores | Simular rollback reescribiendo historia o borrando sucesoras |
|
|||
|
|
|
|||
|
|
Restaurar backup se refiere al conjunto coherente de BD y versión compatible, con ventana de corte y evaluación de pérdida de operaciones posteriores; requiere procedimiento operativo autorizado, no se recomienda como acción automática de esta tarea. DDL usa commits implícitos y puede requerir reanudar desde último paso verificado. Nunca desactivar FKs/checks para hacer que el rollback aparente funcionar.
|
|||
|
|
|
|||
|
|
## 6. Condición de salida
|
|||
|
|
|
|||
|
|
No se habilita globales porque «el build pasa»: son necesarias garantías de contrato, permisos, consumidores, cliente y SQL. La ausencia de prueba en una instancia real no bloquea terminar este diseño, pero **sí bloquea G2/G3b** hasta el ensayo prescrito. Todo gate pendiente queda visible en 10, sin marcar el contrato completo aprobado.
|
|||
|
|
|
|||
|
|
## 7. Precisión de G2 tras el ensayo R2.1b
|
|||
|
|
|
|||
|
|
El encargo posterior autoriza implementar R2.1b y ensayar su DDL solo en MariaDB desechable; no autoriza aplicar la migración a una base habitual ni activar R2.2–R2.6. La evidencia y el estado de gates vigente están en [12 — Persistencia](12-r2-1b-persistencia.md).
|
|||
|
|
|
|||
|
|
El esquema actual puede expandirse conservando sus FKs: no se necesita retirarlas para hacer nullable el propietario del padre en MariaDB 11.8.9 ensayada. Los hijos operativos mantienen NOT NULL. Se requiere CHECK del par con longitud exacta, porque ascii_bin por sí sola no rechaza espacios finales. No se añaden índices globales antes de disponer de las consultas reales que los justifiquen.
|
|||
|
|
|
|||
|
|
La expansión se ejecuta mediante CLI explícita, después de una pausa real de todos los escritores y de verificar backup. El arranque no invoca la nueva migración: acepta legacy o scoped completo y rechaza parcial antes de sembrar catálogos. Después del DDL se reinician procesos para renovar su modo de lectura. Mantener los cuatro pasos reanudables y comprobar datos/constraints antes de reabrir; un WAIT de metadata lock no sustituye esa ventana.
|
|||
|
|
|
|||
|
|
La copia/restauración integral y la reversión sin globales se han ensayado en la instalación desechable. La autorización de aplicar a una instalación habitual y el ensayo de su backup operativo siguen siendo gates independientes. La propagación que escribiría un global permanece cerrada hasta incorporar los guards de R2.2; no debe habilitarse por completar G2.
|