Mi amiga Priya gestiona los turnos de una planta médica de 34 camas y ha pasado dos años atendiendo solicitudes de intercambio de turnos por un chat grupal que nadie lee en orden. Quería algo que las enfermeras pudieran abrir en el móvil durante un descanso, publicar un turno que necesitaran cubrir y que alguien lo reclamara antes de que la enfermera jefe tuviera que reorganizar manualmente el cuadro. Lo construí en tres semanas de tardes-noches. Este es el registro del día en que salió realmente a producción —publicación, dominio personalizado, enfermeras reales, turnos reales— porque la brecha entre "funciona en pruebas" y "funciona a las 7 de la mañana cuando la planta va corta de dos personas" resultó ser una lección en sí misma.
6:58 — publicación
Había configurado el destino de despliegue en el propio dominio de Priya la noche anterior, así que esta parte fue anticlimática: pulsar publicar y ver cómo el registro de verificación del build pasaba sus comprobaciones:
- Rutas resolviendo correctamente
- El endpoint de reclamación de turnos devolviendo una respuesta real en lugar de un stub
- El gancho de notificaciones por SMS realmente configurado, en lugar de en modo de prueba
Todo en verde. Le envié el enlace a Priya por SMS a las 6:58 porque sabía que entraría a su turno justo entonces y quería que lo viera en vivo antes de empezar el día, no después.
7:15 — la primera usuaria real hace algo que no probé
Priya publicó un turno abierto para esa tarde a los veinte minutos, más rápido de lo que esperaba, lo que significó que no había terminado mi café antes de que existiera el primer dato real. Luego una enfermera llamada Denise lo reclamó, lo desreclamó cuatro minutos después y lo volvió a reclamar. No tengo ni idea de por qué; tal vez revisó su propio calendario a mitad de la reclamación y se dio cuenta de que tenía cita en el dentista. La aplicación lo gestionó bien. Lo que no había probado era que tres personas intentaran reclamar el mismo turno dentro de la misma ventana de diez segundos, porque en tres semanas de pruebas en solitario ese escenario nunca se me ocurrió. Tampoco se me ocurrió entonces. Se le ocurrió a la realidad unas cinco horas después.
9:40 — silencio, y el silencio me pone nervioso
No pasó nada durante dos horas y media. Ninguna reclamación, ninguna publicación, ningún error en los registros. Aun así revisé el panel cuatro veces, un hábito que probablemente debería romper: un build que no se está usando no está roto, simplemente aún no se está usando, y son problemas distintos con soluciones distintas. Me obligué a cerrar la pestaña e ir a hacer trabajo de verdad.
11:52 — el error
El endpoint de reclamación aceptó las tres, porque había escrito la lógica de "marcar como reclamado" como una simple comprobación de actualización si está abierto, sin bloqueo, y en pruebas normales con un solo usuario esa condición de carrera simplemente no tiene espacio para ocurrir. Con tres toques simultáneos desde tres teléfonos distintos, tiene todo el espacio del mundo. Las tres enfermeras recibieron un SMS de confirmación diciendo que habían cubierto el turno. Denise fue una de ellas, por segunda vez ese día, y esta vez estaba molesta.
Quiero ser honesto sobre cómo lo descubrí: no lo detecté por la monitorización. Priya me lo escribió, con un emoji de risa incluido, aunque no creo que lo dijera en broma, porque, de hecho, fue un problema para su tarde:
la app dice que 3 personas se quedaron con el mismo turno jaja
12:10 — al chat del build
Describí el error en lenguaje sencillo: varias personas pueden reclamar un turno si tocan al mismo tiempo, y solo una reclamación debería quedar registrada. No intenté escribir yo mismo la solución primero, en parte porque estaba con el móvil en un aparcamiento y en parte porque describir el fallo con precisión suele ser más rápido que diagnosticarlo con precisión. El agente lo rastreó hasta el bloqueo de fila que faltaba en la tabla de reclamaciones, y propuso cambiar a una actualización condicional atómica: la reclamación solo se completa si el estado del turno sigue siendo "abierto", y es la propia operación la que decide quién gana, en lugar de un comprobar-y-luego-escribir que permite que las tres solicitudes vean "abierto" al mismo tiempo. Ese es el error real en una frase, y es el tipo de cosa que resulta obvia en cuanto se dice e invisible hasta que algo la fuerza a la vista.
12:34 — sale la solución, y hago esperar a Priya
El parche era pequeño. Aun así, no lo empujé directamente al dominio en vivo durante un turno activo: primero lo ejecuté contra una versión de vista previa e hice que la colega enfermera jefe de Priya, que no estaba de turno, probara los mismos tres toques simultáneos desde tres pestañas del navegador. Se mantuvo firme. Una reclamación se completó, dos recibieron un mensaje de "este turno acaba de ser reclamado por otra persona" en lugar de una confirmación falsa. Lo publiqué a las 12:34, unos cuarenta y dos minutos después de que ocurriera el error, lo cual se sintió lento en el momento y rápido en retrospectiva.
De 14:00 a 18:00 — la parte aburrida y buena
- 11 turnos más publicados
- 9 reclamados sin problemas
- 2 expiraron sin reclamar y pasaron al cuadro que Priya todavía gestiona manualmente, lo cual está bien: la herramienta no necesita resolverlo todo el primer día, necesita resolver lo concreto que estaba roto
- 0 reclamaciones dobles más
Observé los números en lugar de imaginar resultados, una actividad distinta y mucho más tranquila.
Qué haría de otra manera
Dos cosas.
- Habría descrito el escenario de reclamación concurrente en el prompt de construcción original en lugar de descubrirlo en vivo: "varios usuarios, misma acción, mismo momento" es una frase, no una petición complicada, y simplemente no se me ocurrió incluirla porque mis propias pruebas son inherentemente secuenciales; solo hago clic en un botón a la vez.
- Invertí demasiado en el texto de las notificaciones por SMS durante la segunda semana —tres reescrituras distintas de un mensaje de confirmación de las que nadie se había quejado— y muy poco en exactamente el tipo de caso límite de concurrencia que una planta llena de enfermeras en su descanso, todas mirando el móvil en el mismo momento, siempre iba a golpear el primer día.
En el próximo lanzamiento, voy a dedicar menos tiempo a pulir textos que nadie va a criticar y más a preguntarme "qué pasa si cinco personas hacen esto a la vez", porque para cualquier cosa con más de un usuario real, tarde o temprano, alguien lo hará.



