Presupuestador_web/doc/capitulos-esquema.md

4.9 KiB

Capítulos: cambio de esquema preparado para revisión

Estado: modelos implementados en fase 3; cambios no aplicados a ninguna base de datos. No se ha ejecutado una migración ni sync. Este documento describe la estructura requerida y las comprobaciones para su futura aplicación autorizada.

Cambios concretos

Tabla Cambio Datos históricos
quotes Añadir show_chapter_line_amounts, BOOLEAN, NOT NULL, DEFAULT TRUE Mantener importes individuales visibles por defecto
quote_chapters Crear tabla sin timestamps: quote_id UUID, chapter_id UUID, position MEDIUMINT NOT NULL, description TEXT NOT NULL No insertar capítulos automáticamente
quote_chapters PK compuesta (quote_id, chapter_id); índice quote_chapters_position_idx (quote_id, position) Sin transformación de detalles existentes
quote_chapters FK de quote_id a quotes.id, borrado en cascada La asociación Sequelize declara esta relación
quote_items Añadir chapter_id UUID nullable, DEFAULT NULL Todos los detalles antiguos permanecen libres
quote_items Añadir índice quote_items_chapter_idx (quote_id, chapter_id) Sin alterar la posición de los detalles existentes

Los modelos están en server/src/contexts/sales/infrastructure/sequelize/{quote,quoteItem,quoteChapter}.model.ts. El registro dinámico existente descubre el nuevo modelo y después configura las asociaciones. La declaración tipada dealer_id usa ForeignKey para representar la asociación ya existente; no introduce una columna adicional diferente.

Pertenencia y claves foráneas

El dominio valida que cada referencia de detalle exista entre los capítulos de su cotización. El mapper comprueba también la cotización propietaria de los capítulos al leer. No se declara una asociación Sequelize desde chapter_id de detalle hacia una clave de capítulo aislada: la identidad persistida del capítulo es compuesta y una FK simple no garantizaría la pertenencia a la misma cotización.

La FK compuesta adicional a revisar al aplicar el esquema tiene esta forma:

ALTER TABLE quote_items
  ADD CONSTRAINT quote_items_chapter_fk
  FOREIGN KEY (quote_id, chapter_id)
  REFERENCES quote_chapters (quote_id, chapter_id)
  ON DELETE RESTRICT ON UPDATE CASCADE;

Es una definición para revisión, no un script de migración ejecutado. Antes de aplicarla se deben contrastar los tipos físicos, collation, motor y restricciones existentes de las tablas reales. Con chapter_id = NULL, las líneas antiguas no requieren un capítulo. El repositorio elimina primero detalles y luego capítulos, por lo que el reemplazo completo respeta esta restricción.

Límite actual: el modelo Sequelize no representa ni instala esta FK compuesta; la garantía de pertenencia implementada ahora es de aplicación. No afirmar que la base de datos la impone hasta aplicarla y verificarla. El arranque existente ejecuta sync({ force: false, alter: true }); hay que verificar si conserva la FK manual y sus índices, también en un segundo arranque. No añadir DDL automático en hooks ni cambiar la estrategia global de sincronización dentro de esta fase.

Comprobaciones para una aplicación autorizada

  1. Trabajar con una copia aislada y recuperable del esquema existente; revisar las definiciones físicas de UUID, FK e índices antes de materializar el cambio.
  2. Verificar tabla nueva, columnas, defaults e índices, incluyendo el comportamiento del sync({ alter: true }) actual. Revisar por separado la FK compuesta anterior.
  3. Leer, editar, guardar y duplicar una cotización anterior al cambio: cero capítulos, referencias null, mismo orden y mismos importes.
  4. Crear una cotización con dos capítulos y textos; guardar y recargar. Reordenar capítulos y trasladar detalles verificando sus posiciones.
  5. Inyectar un fallo al insertar capítulos y otro al insertar detalles. Comprobar en MariaDB que cabecera, capítulos y detalles permanecen en el estado previo, sin escrituras parciales.
  6. Lanzar dos actualizaciones concurrentes: una que introduce capítulos y otra de un cliente antiguo que los omite. La comprobación bajo bloqueo debe evitar una eliminación por omisión si la agrupación ya se ha confirmado.
  7. Probar la FK compuesta, si se aplica: rechazar pertenencias inexistentes o a otra cotización, permitir líneas libres null y permitir el reemplazo transaccional de estructura.
  8. Desplegar el backend compatible antes del editor. Una vez guardados capítulos, no volver a un backend que los ignore ni retirar columnas/tablas sin conservar esos datos.

Las pruebas de fase 3 usan metadatos Sequelize y dobles transaccionales, sin abrir conexiones. Verifican contrato, mapeo, orden de operaciones, propagación de transacción y errores; no certifican el DDL, el bloqueo concurrente ni el rollback real de MariaDB. Estas comprobaciones quedan para el entorno autorizado de integración.