Suite 101 · arquitectura

Lo que se archiva no se borra, y lo que se anota va relativo

Un plano de taller se corrige tres veces antes de que la pieza se fabrique, y encima de él hay notas de quien la va a fabricar. Guardar eso parece un problema de subir archivos. Son en realidad dos problemas: qué significa «la versión vigente» cuando dos personas suben a la vez, y en qué unidades se guarda una marca hecha con el dedo.

Al 21 de septiembre de 2026Contrato de la API 0.41.0

«Sin borrar la anterior» no es una costumbre: es una columna

El encargo trae la regla escrita: la versión nueva del plano reemplaza a la anterior a la vista, y la anterior se archiva sin borrarse, para poder consultarla cuando haya dudas.

La manera obvia de hacerlo es desde la pantalla: marcar la vieja como archivada y luego subir la nueva. Funciona los primeros nueve meses. El día que dos supervisores suban versión al mismo segundo, el ítem se queda con dos planos vigentes y nadie sabe cuál manda — y lo va a descubrir el de taller, cortando.

Lo que lo impide de verdad son dos renglones de SQL:

ÍndiceQué prohíbe
quell_docs_un_principal
sobre element_id, WHERE rol = 'principal' AND archivado_at IS NULL
Dos planos principales vigentes en el mismo ítem.
quell_docs_una_viva
sobre familia_id, WHERE archivado_at IS NULL
Dos versiones vigentes del mismo documento.

La pieza que hace que esto funcione es el WHERE. Un índice único normal no sirve, porque el ítem tiene que poder guardar diez versiones del mismo plano; el índice parcial dice «de las vigentes, una». SQLite los soporta y D1 también.

De paso, el índice obliga al orden correcto en la ruta que sube una versión: primero se archiva la vieja, luego se inserta la nueva. Al revés revienta. Y es el orden que se quiere aunque el índice no existiera: entre los dos pasos, es preferible quedarse un instante sin versión vigente que con dos.

La regla general: cuando un requisito dice «sólo puede haber uno», la pregunta correcta no es dónde ponerlo en el código, sino qué restricción de la base lo vuelve imposible. Si no hay ninguna, el requisito es una intención.

Una marca en píxeles se ve bien exactamente en una pantalla

Sobre el plano se pueden clavar notas y rayar a mano alzada, desde el celular en obra o desde la computadora en la oficina. Es lo mismo que hace cualquier lector de PDF, y tiene una trampa que no se nota al construirlo.

El mismo plano mide 390 puntos de ancho en un celular y 1200 en un monitor. Si la marca se guarda donde cayó el dedo en la pantalla, una nota puesta en obra aparece sobre otra pieza al abrirla en la oficina. Y nadie lo reporta, porque quien anota no ve las dos pantallas al mismo tiempo: cada quien ve la suya, y cada quien la ve bien.

Las marcas se guardan relativas: x e y de 0 a 1 sobre la página, y el trazo como una lista de pares en esas mismas unidades. Eso es evidente una vez dicho. Lo que no es evidente son las dos consecuencias:

Copiar o no copiar no lo decide el esquema

Al subir una versión nueva hay una pregunta real: ¿se traen las anotaciones de la anterior?

Las dos respuestas son defendibles y por razones opuestas. Un plano corregido normalmente invalida las notas que pedían la corrección, así que copiarlas siempre deja notas viejas señalando cosas que ya se arreglaron. Pero cuando el cambio fue chico, volver a clavar catorce notas a mano es exactamente lo que hace que la siguiente vez nadie las use.

Así que no se elige en el esquema: viaja como un campo del formulario, y la pantalla lo pregunta cada vez, con dos botones y la consecuencia escrita debajo de cada uno. Cuando las dos respuestas son defendibles, el sistema no escoge: pregunta, y dice qué implica cada una antes de que respondan.

Lo que sólo se ve probándolo

Dos defectos de la pantalla sobrevivieron a la lectura del código y cayeron en el primer recorrido con un navegador de verdad. Los dos son de la misma familia: se ven bien y guardan mal.

Ninguno de los dos aparece en una prueba que lea el código fuente, y ninguno rompe nada: el primero guarda una línea plausible, el segundo guarda una coordenada perfectamente válida. La única forma de verlos es hacer el gesto y comparar lo que viajó contra lo que se hizo.

Cómo quedó medido

538 pruebas de la API, con un bloque nuevo que sube el principal y el soporte, anota nota y trazo, sube versión con y sin copiar marcas, y comprueba que la archivada sigue consultable pero no se puede anotar. Una prueba de la migración corre sobre una base con datos antes de cada despliegue: un solo principal vivo, las marcas se quedan con su versión, ninguna llave foránea rota.

Y del lado de la pantalla, un recorrido en Chromium a 390×844 y a 1280×800 que clava una nota tocando el 25 % / 75 % de la hoja y comprueba que lo que viaja es el mismo par en las dos pantallas. Esa prueba es la que existe por la sección de en medio: si algún día alguien cambia las unidades, no se va a notar mirando.