Saltar al contenido
Development

La misma decisión de botón me costó un bug más grande de lo esperado

Por Victor Da Luz
railsrubydev-logblog-manager

La siguiente pieza del cluster del editor: incrustar el flujo existente de buscar/seleccionar/quitar/confirmar imagen destacada dentro del editor de publicaciones, para que asignar una imagen destacada no requiera salir de la página. Terminó enseñándome más sobre verificar suposiciones contra datos reales que sobre la funcionalidad en sí.

La pregunta del botón, otra vez

Misma forma de decisión que el flujo de confirmación: ¿el commit de la imagen destacada debía pasar por el mismo botón principal de “Commit” que el resto del borrador, o quedarse como su propia acción dedicada? Lo resolví deliberadamente antes de construir nada, de la misma forma en que se resolvió la pregunta de sincrónico contra asincrónico: un botón dedicado para la imagen destacada, manteniéndolo separado del camino de commit de metadata/cuerpo del borrador.

Lo que esa decisión no esquivó

Al principio encuadré la opción del botón dedicado como la más chica y segura. No lo fue, en el único lugar donde en verdad importaba. El comité de imagen destacada existente solo insertaba una clave heroImage nueva en un archivo que no tenía ninguna, y fallaba de inmediato si ya existía una. Hacer que reemplazar funcionara de verdad, que era todo el punto de cerrar la brecha entre imagen destacada en borrador y en vivo, significaba ubicar y reemplazar esa clave donde sea que estuviera en el archivo, no solo agregarla al final.

Antes de escribir código de vista, revisé cómo se veía en verdad el frontmatter real de producción. Las 166 publicaciones en vivo de vdaluz.com ya llevan una clave heroImage, puesta fuera de banda por el propio script de asignación de imagen destacada de vdaluz.com, en su posición natural dentro del archivo. Ninguna había pasado nunca con éxito por el viejo camino de solo inserción, porque ese camino solo puede correr una vez por publicación. Un enfoque posicional o basado en regex de “quitar lo último que se agregó”, que es lo que había empezado a esbozar, habría producido en silencio claves duplicadas contra cada una de esas 166 publicaciones. En su lugar, construí un upsert basado en AST propiamente dicho en el servicio de frontmatter existente, y lo validé contra los 166 archivos reales (no una muestra) antes de tocar la interfaz: sobrevive exactamente una clave heroImage a un reemplazo, cada otro campo queda intacto, la misma disciplina de validación que usó el servicio de frontmatter cuando se construyó por primera vez.

El bug que casi se lanzó

La revisión desde múltiples ángulos antes del merge detectó algo que el chequeo empírico de arriba no detectó: una columna nueva, hero_committed_at, rastrea si una selección en borrador en verdad se subió en vivo, y la agregué con un simple add_column, sin backfill. Tres pasadas de revisión independientes convergieron en la misma línea: cada publicación que ya tenía una imagen destacada confirmada a través de esta app antes de que se desplegara la migración tiene una selección en borrador presente, una imagen destacada en vivo presente, y esta columna nueva permanentemente NULL, porque el marcador en borrador nunca se limpia al tener éxito (no puede limpiarse, algo más lo lee directamente). Cada una de esas publicaciones habría mostrado un botón obsoleto de “Commit to live article” en vez de “Applied”, y hacer clic habría disparado un commit real e inútil en GitHub. Nada en la suite de pruebas lo detectó, porque los fixtures de prueba nuevos nunca tienen datos preexistentes contra los cuales fallar de esta forma. Se corrigió con un backfill de una línea, la misma forma que este repo ya tenía como precedente en una migración anterior que no había cruzado con esta.

Lo que limpié después

La lógica de visualización de pendiente contra aplicado (confirmando / pendiente / en vivo / ninguno) terminó duplicada entre tres vistas una vez que el panel del editor existió junto a las dos visualizaciones de imagen destacada más antiguas. La revisión la marcó como más que territorio de “tres líneas parecidas”, ya que era un condicional de múltiples ramas más un comentario explicativo, copiado y pegado tres veces. Se extrajo en un solo método Post#hero_display_state en su lugar.

Lo que no verifiqué

La misma brecha que el flujo de confirmación: sin token de GitHub con permiso de escritura en desarrollo, así que el commit/reemplazo en vivo real solo corrió contra un cliente falso en las pruebas. La verificación en navegador sí confirmó la parte que más importaba acá: al asignar una imagen nueva sobre una imagen destacada ya en vivo, se mostró correctamente el nombre del nuevo fotógrafo y un botón de commit, no un texto obsoleto de “Applied”, para una publicación real en una sesión real.

Lecturas relacionadas

Development

El botón de commit del editor es un botón de deploy

Confirmar un borrador a main despliega el blog automáticamente. En cuanto eso quedó claro, sync vs. async dejó de ser una cuestión de estilo, más el caso especial de afiliado heredado que un validador nuevo casi rompió.

Leer