Estado: NOTA DE INVESTIGACIÓN (previa al plan). Sin código. Según docs/PROCESS.md §1.1, el análisis exploratorio vive en docs/research/ hasta que se compromete a un sprint. Fecha: 2026-07-23 Procedencia: reconstruido en conversación a partir de la memoria del operador sobre un taller de reparación de computadoras que corrió hace unos 6 años sobre osTicket. Los códigos de departamento son aproximados (recordados, no leídos del sistema). La estructura — la alternancia de turno, el departamento como área, la plantilla por departamento, las barreras — se describió de forma consistente a lo largo de todo el flujo y es el contenido de la ruta crítica. La instancia original de osTicket y sus datos todavía existen y se pretende migrarlos; esos datos son la verdad de campo y se imponen sobre esta nota donde no coincidan.
Relacionados: `attestation-and-informed-consent.md` (el contrato de recepción, los medios de custodia, la disciplina de desecho) y `red-lab.md`.
---
1. Qué era esto en realidad
osTicket, doblado hasta volverse una línea de producción de taller. osTicket trae de fábrica Departamentos, Respuestas Prefabricadas y números de ticket aleatorios. No trae un motor de flujo de trabajo — su propio campo de estado es grueso (abierto / resuelto / cerrado). Así que los Departamentos se reutilizaron como estados del flujo, porque un Departamento era el único contenedor por etapa que además cargaba sus propias respuestas prefabricadas.
Todo lo que lo hacía funcionar era disciplina operativa puesta encima, impuesta con plástico y marcador — nada de eso existía en el software:
- cada departamento atado a un área física (el estante de CI, la mesa de
recuperación de datos, el rack de PU)
- el bote como unidad de custodia: máquina + piezas pedidas + componentes
encintados y guardados juntos
- etiqueta de borrado en seco en cada bote, reescrita con ticket + departamento +
fecha, para que el envejecimiento se viera de reojo
- barreras entre departamentos (el pago se libera antes de DIAG; la aprobación
antes de WFO)
- alternancia de turno — de quién es el turno — que no aparece en ninguna parte de
osTicket
La propiedad intelectual es el proceso, no el código.
---
2. El modelo de departamento
Un departamento no es una unidad organizativa. Es un nodo de estado que posee seis cosas:
| faceta | significado |
|---|---|
| área | el estante, la mesa o el cuarto físico. El departamento es a dónde caminar. |
| turno | de quién es la siguiente acción: nosotros, el cliente o el proveedor |
| opciones | las acciones legales aquí — y solo esas |
| respuestas | el mensaje o mensajes prefabricados que se disparan al entrar |
| procedimiento | el procedimiento escrito que se sigue en esta etapa |
| presupuesto de permanencia | cuánto es demasiado aquí (por departamento, no global) |
2.1 El flujo (códigos aproximados)
CI → DIAG → WFC → WFO → WFP → WFT → [DATA] → OS → SET → WFI → PU
| dpto | qué significa | turno | área | mensaje al entrar | barrera de salida |
|---|---|---|---|---|---|
| CI | recepción | cliente | estante de recepción | «recibido» más el enlace de pago de la cuota de revisión | cuota de revisión pagada |
| DIAG | diagnóstico | nosotros | mesa | «ya empezamos…» | diagnóstico terminado (producto: notas) |
| WFC | esperando al cliente | cliente | — | el presupuesto: piezas + mano de obra − anticipo | el cliente aprueba y paga la pieza |
| WFO | esperando el pedido | nosotros | — | (ninguno — esto es un pendiente) | pedido hecho |
| WFP | esperando la pieza | proveedor/paquetería | — | número de guía | llega la pieza |
| WFT | esperando al técnico | nosotros | — | «tu pieza ya llegó, pronto te atendemos» | el técnico empieza |
| DATA | recuperación de datos | nosotros | área de recuperación de datos | «empezamos» → después «tus datos están recuperados» | recuperación terminada |
| OS | instalación del sistema | nosotros | mesa | instalación empezada | instalación terminada |
| SET | configuración | nosotros | mesa | restaurando datos, programas, controladores | configuración terminada |
| WFI | esperando la factura | nosotros (administración) | — | (Kat factura, luego llama para avisar que está listo) | facturado + cliente llamado |
| PU | entrega | cliente | rack de entrega | (al recoger: gracias más recibo) | pagado + recogido |
Después: se marca como recogido en el sistema de tickets → se cierra → se reabre para seguimiento (pedir reseña / agendar una visita a domicilio).
2.2 La alternancia de turno es el proceso
nosotros → cliente → nosotros → cliente → **nosotros** → proveedor → nosotros → … → administración → cliente
El turno es un atributo de primera clase, no derivado. Determina tres cosas que ningún campo de estado puede:
- a quién perseguir cuando se atora
- si la demora es culpa nuestra
- qué escalamiento aplica
Consecuencia para el tablero: agrupar por turno, los nuestros hasta arriba. Todo lo que está en una columna de «nosotros» es una lista de pendientes; todo lo que está en una columna de «ellos» es una lista de seguimiento. No hace falta ninguna astucia de tablero.
2.3 «Atorado con nosotros» no es un solo cajón
- WFT está atorado por el tiempo del técnico.
- WFI está atorado por el tiempo de administración (otra persona, otra
habilidad, una llamada telefónica).
Una máquina envejeciendo en WFI no es un problema de técnicos por mucho que lleve ahí. El tablero necesita una lista de mesa y una lista de mostrador, no un solo montón de «nuestro turno».
2.4 WFO es el estado más condenatorio del sistema
El cliente ya pagó una pieza y nadie ha hecho el pedido. Envejecer en WFO no es esperar — es una pelota que se cayó con su dinero ya en la cuenta. Si un solo número va en rojo en una pantalla de pared, que sea el elemento más viejo en WFO.
2.5 Los dos estados de espera necesitan lógicas de vencimiento distintas
| atorado por | ¿tiene fecha estimada? | escalamiento | |
|---|---|---|---|
| WFC | el cliente | no — abierto | escalera de contacto ascendente; registrar cada intento |
| WFP | la paquetería | sí — la fecha de entrega prometida | medir contra la fecha estimada; perseguir al proveedor |
El mismo concepto de «atorado», dos mecánicas completamente distintas. Ninguna de las dos es un acuerdo de nivel de servicio (§4).
2.6 La ocupación de un departamento es una posición financiera
Una vez que el cliente pagó la pieza, WFO y WFP son un pasivo: dinero retenido contra una pieza que no llegó, por un trabajo que no se hizo. Sumar la ocupación por departamento da, gratis:
- Σ WFO + WFP = dinero de clientes retenido contra piezas no entregadas (ingreso
diferido)
- Σ WFC = trabajo presupuestado detenido a la espera de aprobación
Sin ningún reporte aparte — el mismo tablero que muestra el envejecimiento muestra la exposición.
---
3. Coherencia entre lo físico y lo digital
3.1 La ubicación ES el estado
Mover el bote a la mesa de DIAG es la transición a DIAG. Consecuencias:
- Se impone solo. Un bote está físicamente en exactamente un lugar, así que «un
objeto, un estado» no necesita ninguna restricción. (En contraste, domain-inventory::StockPlacement permite un mismo artículo activo en dos ubicaciones — correcto para mercancía fungible, equivocado aquí.)
- Auditar es caminar, no consultar. La base de datos es una afirmación sobre el
cuarto; acoplarlos hace que la afirmación se pueda comprobar de un vistazo. Desacóplalos y la base podrá afirmar «listo para entrega» sobre una máquina que está en la mesa de diagnóstico, y nunca nadie lo va a notar.
- DATA demuestra que esto es ruta crítica, no mera pulcritud: *«sabíamos que
estaba en el área de recuperación de datos o si no en la mesa.»* El departamento es el índice físico — a qué cuarto entrar.
3.2 Ser elegible no es transitar
Que el pago se libere no debe avanzar el estado. Si lo hiciera, la base afirmaría DIAG mientras el bote seguía en el estante de CI, destruyendo la §3.1.
- pago liberado → el artículo se vuelve elegible para avanzar
- alguien mueve físicamente el bote → el estado transita
El hueco entre esas dos cosas es una cola de trabajo — «pagado y esperando a que lo muevan» — y es una lista distinta de la del envejecimiento. Una dice «nadie ha tocado esto»; la otra dice «esto está listo y atorado con nosotros». Las dos van en el tablero.
3.3 El bote es la unidad de custodia, no la máquina
Un ticket = un bote = un conjunto de objetos físicos que tienen que quedarse juntos y salir juntos: la máquina, las piezas pedidas (añadidas en WFT), y los componentes desmontados y etiquetados con cinta azul de pintor. Perder un tornillo es una falla de custodia; la cinta era la imposición.
Nada en el marco modela «estos N objetos físicos pertenecen a un mismo trabajo y no deben separarse.» storage-locations tiene Container/Bin; inventory tiene artículo↔ubicación. Ninguno tiene el conjunto.
---
4. La permanencia no es un acuerdo de nivel de servicio
Un acuerdo de nivel de servicio es una medida de compromiso: una meta prometida, donde incumplir es un evento contractual, visible para el cliente, y puede llevar penalización. Tiempo de respuesta, tiempo de arreglo, pérdida de paquetes.
La permanencia es higiene operativa. Nadie le prometió al cliente que su máquina saldría del BIN-14 en diez días. La fecha en el bote existía para que nosotros lo notáramos.
Los conjuntos que cubren son casi opuestos:
- El acuerdo de nivel de servicio vigila lo que ya te comprometiste a hacer — así
que alguien ya está pensando en ello.
- La permanencia vigila aquello sobre lo que nadie prometió nada — que es
exactamente donde las cosas se pudren.
La máquina que se quedó ahí hasta que el disco se llenó no tenía acuerdo de nivel de servicio porque nadie la estaba siguiendo. Era invisible para el sistema de promesas precisamente porque no existía ninguna promesa.
Verificado: operations-sla no puede expresar la permanencia. Todos sus relojes son input.created_at + duración de la política; SlaInput no tiene campo de estado. Dos hitos están escritos a mano (primera respuesta, resolución). Además, su campo pause_on_waiting existe, viene en true por omisión, tiene constructor — y tracker.rs nunca lo lee. WFC es el estado para el que se inventó esa bandera, y no hace absolutamente nada en silencio.
El envejecimiento en sí es aritmética (ahora − entered_state_at), no una capacidad faltante. Lo que falta:
1. Un `entered_state_at` confiable. updated_at se mueve con cualquier escritura; toca una nota y el artículo se ve fresco. El workflow_transition_history.at de operations-workflow lo aporta correctamente — pero solo para entidades que usan el almacén CAS, y nada proyecta «cuándo se entró al estado actual». 2. Un presupuesto por estado. Tres días en WFC es normal; tres días en WFO es una pelota caída. 3. Ambiente. La fecha del bote funcionaba porque se veía desde el otro lado del cuarto sin preguntar. Los reportes son sistemas de jalar; la pared de botes era un sistema de empujar.
---
5. Identificadores
5.1 Número de ticket: 6 dígitos aleatorios — y lo aleatorio es ruta crítica
Requisitos, en orden de prioridad: perceptualmente distinto, memorable, decible, escribible sobre cinta. No «imposible de adivinar».
- Lo secuencial falla en el salto físico.
100234y100235en botes vecinos; un
dígito mal leído mete la pieza equivocada en la máquina equivocada. Lo aleatorio maximiza la distancia de edición práctica.
- Lo secuencial además le filtra el volumen del negocio a cada cliente.
- Impreso en dos filas de tres sobre la cinta — la cinta es angosta, así que dos
filas mantienen los dígitos lo bastante grandes como para leerse desde el otro lado del cuarto después de manosearlos; y agrupar de 3 en 3 reduce medible el error de transcripción (la ergonomía del número telefónico).
Es una referencia compartida en cuatro superficies — la cinta del bote, el correo del cliente, el buscador del personal, y dicho en voz alta por teléfono. Cuatro saltos, tres medios; el número tiene que sobrevivir a todos. Por eso «fácil de distinguir, fácil de recordar» era el requisito correcto.
Nunca fue una credencial. La autenticación era correo más contraseña, con sesiones y permisos de verdad. El número de ticket aparecía dentro de los correos como referencia y era la llave de búsqueda del personal.
5.2 Dos necesidades de identificador, asignadores opuestos
| forma | por qué | encaje en el marco | |
|---|---|---|---|
| BIN-NN | secuencial, sin huecos, nunca reutilizado | un conjunto físico fijo; un hueco significa un estante faltante | forge_allocate_counter (application-core/src/sql_invariants.rs:129) — atómico en la base, sin huecos, revertir no quema nada |
| Número de ticket | aleatorio, único, memorable, distinto | contra la mala lectura entre superficies físicas | ausente — todo asignador del marco es secuencial sin huecos; los dos generadores aleatorios de 6 caracteres (reservations, scheduling, copiados y pegados) no comprueban colisiones |
Nótese además que `foundation/sequence` tiene el cerebro partido: la get_next_sequence_value() en SQL sí es genuinamente sin huecos (SELECT … FOR UPDATE), pero los tipos Sequence/TemporalSequence en Rust son contadores en memoria con &mut self y cero `PgPool`. Usar la API de Rust para asignar el BIN-14 no da ni ausencia de huecos ni seguridad ante concurrencia.
La forma canónica de presentar el identificador pertenece a la pieza de biblioteca (123456 guardado, 123 / 456 en la cinta, dicho «uno veintitrés, cuatro cincuenta y seis»), o las superficies se van a separar y alguien va a escribir a mano una tirada de 6 que se acabará leyendo mal. SequenceFormat soporta plantillas de una sola línea y da por hecho una pantalla.
---
6. Por qué importaba el procedimiento por departamento
El estado te dice qué hacer. Un trabajador no necesita todo el proceso en la cabeza — solo lo que es legal desde donde está.
- En CI no puedes pedir piezas. En WFO no puedes moverlo al rack de entrega.
- Clases enteras de error se previenen no ofreciendo la acción equivocada.
Esto es lo que permitió que el taller corriera con chavos listos de 17 años a tres semanas de haber entrado: la ejecución correcta no dependía de la pericia. También es la propiedad protectora del diseño de recepción con otro disfraz — menos formas de cometer un error caro con la propiedad de alguien más.
El silencio se vuelve estructuralmente imposible. El mensaje va pegado al estado, no al criterio de una persona, así que un cliente no puede olvidarse entre etapas. Eso mata la llamada de «¿dónde está mi computadora?» — una línea de costo real, ya que cada una interrumpe a alguien que trae un desarmador en la mano. Importa más durante DATA, donde la espera es más larga y la ansiedad más alta: empezamos → recuperado → instalando → configurando, sin que nadie decida mandar ninguno de esos avisos.
La complejidad de la plantilla varía por departamento: CI es una cadena fija; WFC es un documento calculado (piezas + mano de obra − anticipo); WFP se arma desde el registro del pedido (número de guía).
6.1 La transferencia de turno va por eventos en AMBAS direcciones
- Mensaje saliente → el artículo pasa al turno del cliente (por ejemplo, WFC).
- Respuesta entrante del cliente → el sistema mueve el ticket a un estado de
revisión → de vuelta a nuestro turno, a la vista.
Nadie tiene que darse cuenta de que un cliente respondió; la respuesta misma lo mueve. Así que la comunicación entrante es una transición de estado, no meramente un añadido a un hilo de mensajes — que es como la tratan casi todos los sistemas de tickets, y por lo que sus tableros se desactualizan.
Esto es lo que hace sobrevivible a WFC. Los únicos elementos de WFC que se pudren son aquellos donde el cliente nunca responde nada — precisamente la rama de abandono (§9), y el único caso que este mecanismo no puede atrapar.
6.2 El correo es un puntero, no una carga
A los clientes se les avisa por correo que hay una actualización en el ticket 123456, con un enlace al portal — o simplemente entran a su cuenta. El correo lleva la referencia y el puntero; el contenido se queda detrás de la autenticación.
La razón principal es que se puede revisar, no la privacidad (según el operador — esta nota originalmente lo tenía al revés):
**Un correo es una publicación irrevocable. El portal es un documento revisable.**
El contenido que se manda por correo es permanente e incorregible. El contenido detrás de un enlace sigue siendo editable hasta el momento en que el cliente lo mira. Esa ventana se usaba constantemente y por tres razones distintas:
1. El análisis cambió. Más diagnóstico revisó el hallazgo. 2. El precio cambió. «Perdón, el precio cambió» — un presupuesto revisado, antes de que el viejo se volviera un compromiso que ya hubieran leído. 3. La razón humana. Algo escrito con enojo se podía echar para atrás. En palabras del operador: «alguien se encabronó (yo) y luego tuvo que decir: ah qué bueno, todavía no lo revisaron.»
Esa tercera es un requisito de diseño real, no un defecto del que avergonzarse. En un negocio donde rutinariamente le dices a la gente que su máquina está muerta y que costará 400 dólares, un sistema que te concede un respiro para reconsiderar protege al cliente de tu peor hora y te protege a ti de ti mismo. Casi todas las herramientas hacen que mandar algo irretractable no cueste ningún esfuerzo.
Esto vuelve el estado de vista parte del modelo, no telemetría. Si el cliente ya lo miró o no define la ventana de corrección:
- no visto → todavía editable; corrígelo en silencio
- visto → ya aterrizó; las correcciones ahora tienen que ser una corrección
explícita y visible
Una consecuencia de diseño: la pieza de biblioteca necesita un viewed_at sobre el documento entregado, y el editor tiene que mostrar el estado de la ventana — porque «¿todavía puedo arreglar esto?» es la pregunta que de verdad se está haciendo.
La privacidad es el beneficio secundario, y es real: el correo es inseguro en tránsito, se queda en una bandeja de entrada indefinidamente, se sincroniza a teléfonos (posiblemente el teléfono conectado a la máquina que se está reparando), y se reenvía. El presupuesto lleva precios; las notas de DIAG pueden describir cosas que el cliente no querría que se quedaran en una cuenta de correo por una década.
Así que la plantilla de un departamento no es una sola cosa — es una plantilla más una política de divulgación por canal. El mismo cambio de estado produce detalle graduado según qué tan confiable sea la superficie de entrega:
| canal | lleva |
|---|---|
| portal (sesión autenticada) | el documento completo — renglones del presupuesto, notas, guía |
| correo electrónico | referencia del ticket + «hay una actualización» + enlace |
| SMS (si alguna vez) | todavía menos |
Esta es la regla de medios seguros del marco (.claude/CLAUDE.md regla 10) en otro dominio: el contenido vive detrás de la ruta con control de acceso; lo que sale del edificio es un puntero, nunca la cosa.
Decisión de diseño, ya resuelta: «enlace seguro» significa un enlace a una página que exige iniciar sesión, no un enlace mágico que carga un token. Un enlace mágico es una credencial al portador sentada en una bandeja de entrada — y las bandejas se comprometen, se comparten y se quedan con la sesión abierta en aparatos viejos. Como ya existen sesiones y contraseñas de verdad, el enlace es una comodidad que apunta a la autenticación, nunca un sustituto de ella.
---
7. El hueco que causó el dd
La máquina se va en PU. La copia de los datos no.
Dos objetos de custodia, dos finales distintos:
| objeto | custodia liberada | ¿seguido? |
|---|---|---|
| la máquina | en PU — firmado, recibo emitido | sí, por el tablero de departamentos |
| la copia de trabajo de los datos | solo al borrarla — después de confirmar la satisfacción | sin departamento, sin estante, sin turno, no es trabajo de nadie |
La segunda obligación sobrevive a la primera y es invisible para el sistema que seguía a la primera. El ticket se siente terminado en cuanto el cliente se va con un recibo. Nada estaba vigilando, porque lo que había que vigilar ya había salido del edificio.
Así que el problema del envejecimiento nunca fue principalmente botes ahí parados demasiado tiempo. La obligación de custodia más longeva no tenía ninguna representación, y lo único que acabó por sacarla a la luz fue que el disco se llenó — momento en el cual el desecho ocurrió bajo presión de capacidad, sobre cualquier disco que alguien agarrara, para tickets que seguían abiertos.
7.1 El arreglo sale del mismo vocabulario
Un departamento para la copia de los datos — WFW, esperando el borrado — al que se entra en PU y del que solo se sale por una destrucción verificada, con el ticket incapaz de cerrarse hasta que esté vacío. Entonces «cerrar el ticket» y «destruir la copia» se vuelven un solo acto.
7.2 El evento de confirmación ya existía
La reapertura para seguimiento (pedir reseña / agendar visita a domicilio) es la puerta del desecho. Llamas para preguntar cómo va funcionando, dicen «excelente, ya está todo de vuelta» — esa frase es el el cliente confirma que quedó satisfecho que autoriza el borrado. El toque comercial y la liberación de la custodia siempre fueron una misma conversación; solo que no estaba formalizada.
7.3 Disparadores del desecho, en orden
1. Entrega confirmada — lo correcto. Datos devueltos, organizados, programas reinstalados, máquina configurada «como estaba o mejor», el cliente confirma. Entonces dd. Luego anotarlo en el ticket. Luego cerrar. 2. Contacto agotado y registrado — el respaldo correcto. Se intentó el seguimiento y se volvió a intentar, el cliente está ilocalizable. Lo dispara los intentos registrados, no los días transcurridos. 3. Presión de capacidad — lo que de verdad lo dispara. Inevitable con medios finitos.
Un temporizador fijo de retención es incorrecto, confirmado en la práctica: los tiempos de regreso de los clientes son irreduciblemente impredecibles, así que cualquier periodo fijo es o demasiado corto (destruye la red de seguridad que alguien todavía necesita) o tan largo que deja de significar algo. Y un reloj es igual de incorrecto como respaldo — eso reintroduce el mismo defecto un nivel más abajo.
Como la presión de capacidad no se puede legislar, el trabajo del sistema es garantizar que cuando se dispare, se dispare sobre copias elegibles: seguir la elegibilidad de forma continua, mostrar una lista de trabajo recuperable («N copias elegibles, X GB»), exigir una anulación registrada para destruir una no elegible, y tratar una cuenta creciente de tickets sin cerrar como el indicador adelantado.
---
8. Cerrado no es terminal
Reabrir para seguimiento es una ruta normal, no una excepción — cosa que la mayoría de las máquinas de estados se equivocan, ya que is_terminal() normalmente significa «nunca más».
Pero la reapertura hace doble trabajo: la reparación está terminada; lo que despierta es la relación con el cliente (la reseña, la visita a domicilio, el soporte pagado continuo). Estrictamente son objetos distintos — encounters para la visita, parties para la persona.
El contraargumento para dejarla pegada: reabrir preserva el contexto, y el contexto vale dinero. «¿Cómo va la laptop desde que te recuperamos las fotos?» convierte mucho mejor que «por favor califica tu experiencia». La historia del trabajo es la personalización.
El modelo probablemente correcto: un encuentro de seguimiento ligado al ticket de reparación, no una reapertura de este — el contexto se preserva, sin fingir que la reparación está sin terminar. La confirmación que produce libera la custodia de los datos y cierra el ticket de verdad.
---
9. Ramas
| rama | desde | nota |
|---|---|---|
| irreparable | DIAG | la ruta de «te recuperamos los datos y te ayudamos a comprar un reemplazo» — otro producto |
| rechazado | WFC | el cliente dice que no al presupuesto. Terminal, pero el objeto de todos modos tiene que salir del edificio — una ruta de devolución, posiblemente menos el anticipo |
| abandonado | de donde sea, casi siempre WFC | nadie regresa jamás. No existía ningún estado terminal limpio. Este es el bote de once meses |
Los estados terminales de CatalogItemStatus son Sold | Donated | Trashed | Invalidated — no hay `Returned`, así que «salió del edificio y sigue siendo de alguien más» no se puede representar y es indistinguible de una pérdida.
---
10. Destino de la migración
Intención: migrar el sistema, no meramente importar la historia. Casi toda la superficie de osTicket es ensamblaje:
| osTicket | el marco |
|---|---|
| tickets | domain-encounters |
| clientes / agentes | identity-parties + identity-auth + identity-rbac (sesiones, permisos) |
| departamentos | ← la pieza de biblioteca nueva |
| respuestas prefabricadas | plantillas de domain-notifications |
| entrada de correo | infrastructure-communication |
| notas | content-notes |
| adjuntos | content-assets + AttachmentService |
| búsqueda | infrastructure-search |
| auditoría | foundation-audit-log (inalterable) |
| procedimientos | operations-runbook (solo contenido — sin registro de ejecución, así que «el técnico de verdad hizo el paso 4» queda sin capturar) |
El hueco es el mismo alrededor del cual se improvisó. La migración tiene que volver de primera clase:
1. el departamento como un estado real con barreras 2. el departamento atado a un área física 3. el bote como unidad de custodia de varios objetos 4. la permanencia por departamento, ambiente 5. la obligación de custodia de datos que arrastra, WFW
Es la diferencia entre un sistema de tickets que un taller usa y un sistema de taller.
10.0 CUIDADO AL MIGRAR — este es un sistema evolucionado, no lo emparejes
El modelo no se diseñó de antemano. Se afinó durante años a base de prueba y error. Cada regla que tiene es probablemente una cicatriz: pagar antes de DIAG porque alguien diagnosticó una máquina y nunca le pagaron; cinta en los componentes porque se perdió un tornillo; números de ticket aleatorios porque una pieza acabó en el bote equivocado; WFO separado de WFP porque «esperando» escondía un pedido que nunca se hizo.
Ese conocimiento no se ve en el diseño — solo se ven sus consecuencias. Así que el mayor riesgo de la migración es simplificar:
- Trata cualquier estado que parezca redundante o quisquilloso como ruta crítica
hasta que se demuestre lo contrario (la cerca de Chesterton). Encuentra la falla que previene antes de quitarlo.
- El orden también está afinado. Las barreras están donde están porque ponerlas en
otro lado causó un problema específico. Ese orden no es obvio y es lo primero que un diseñador de fuera se equivocaría.
- Algunas cercas tienen razones que solo recuerda el operador; otras tienen razones que
ya nadie recuerda y el proceso sigue cargando correctamente.
Simplifica desde la evidencia, no desde la estética. Las cuentas históricas de transiciones (§10.1) mostrarán qué estados de verdad hicieron trabajo y cuáles eran vestigiales — esa es la única base sólida para podar.
10.1 Los datos históricos son la verdad de campo
Migrar los datos de osTicket (MySQL → Postgres) produce:
- presupuestos de permanencia medidos en vez de inventados — la distribución real
de cuánto tardaba DIAG de verdad, cómo se veía la cola larga de WFC, con qué frecuencia se atoraba WFO
- validación del vocabulario reconstruido de esta nota — donde los datos
discrepen, ganan los datos
data/import tiene la forma (mapeo de columnas, reglas de validación, estrategia de duplicados, CsvParser) pero es solo tipos, sin persistencia; el cargador está sin escribir.
Decidan la retención antes de cargar, no después. Esos tickets llevan datos personales de clientes de hace seis años, de un negocio que ya no opera. Lo que el diseño necesita son los tiempos históricos, y esos sobreviven intactos a la anonimización.
---
11. Qué tiene que originar el marco
Después de revisar las 256 piezas, todo lo de arriba es composición excepto:
1. El departamento como nodo de primera clase que posee área + turno + opciones + respuestas + procedimiento + presupuesto de permanencia. Nada ata esas seis cosas; storage_locations.default_workflow es una pista solitaria de que alguien alguna vez lo consideró, y no tiene usuarios. 2. La cerca del depósito — is_sellable() no toma ninguna entrada de propiedad; Disposition no tiene ReturnToOwner; CatalogItemStatus no tiene Returned; Consent está indexado por usuario y sin sujeto, así que «autorizo destruir este disco» no se puede representar — y un cliente de mostrador no tiene sesión con la que consentir. 3. La proyección de `entered_state_at` más presupuestos de permanencia por estado. 4. Un certificado de destrucción. compliance::DeletionRequest::complete() no registra método, ni testigo, ni certificado. 5. Un asignador de identificadores aleatorio, con unicidad comprobada y presentación legible para una persona (§5.2). 6. El conjunto de custodia de varios objetos (§3.3).
Todo lo demás existe — varias piezas disfrazadas: legal-evidence es un conjunto general de custodia de artefactos etiquetados; travel-compliance es un conjunto general de inspección certificada con vencimiento; legal-matter::LegalHold es un gravamen general sin vencimiento.