8 min

Especificaciones de funciones de Claude Code desde el código: un flujo de trabajo simple

Aprende a crear especificaciones de funciones de Claude Code a partir del código extrayendo el comportamiento real de rutas y componentes, y generando una especificación viva y una lista de brechas.

Especificaciones de funciones de Claude Code desde el código: un flujo de trabajo simple

Por qué necesitas especificaciones que coincidan con el código

La gente discute sobre lo que hace una app porque recuerda distintas versiones. Soporte recuerda el último ticket enojado. Ventas recuerda la ruta de la demo. Ingenieros recuerdan lo que la funcionalidad debía hacer. Pregunta a tres personas y obtendrás tres respuestas seguras, y ninguna coincide con la versión actual.

Con el tiempo, el código se convierte en la única fuente que se mantiene actual. La documentación se desvía, los tickets se cierran y las correcciones rápidas se acumulan. Una ruta obtiene una nueva regla de validación. Un interruptor de UI cambia un valor por defecto. Un handler empieza a devolver errores distintos. Nadie actualiza la especificación porque parece opcional y cada cambio parece demasiado pequeño para documentarlo.

Eso crea problemas previsibles. Los equipos envían cambios que rompen casos límite que no conocían. QA prueba la ruta feliz y pierde reglas ocultas en los handlers. Los nuevos integrantes copian el comportamiento desde la UI sin entender las restricciones reales. Los interesados discuten opiniones en lugar de señalar un comportamiento acordado.

Un buen resultado no es un documento perfecto. Es claridad compartida. Todo el mundo debería poder responder: "¿Qué pasa si hago X?" y "¿Qué garantiza el sistema?" sin adivinar. Obtienes menos sorpresas, ciclos de revisión más cortos y menos momentos de “Espera, eso ya lo hace” porque el equipo mira la misma verdad.

Cuando una spec coincide con el código, es seguro planear cambios. Puedes ver qué es estable, qué es accidental y qué falta antes de hacer el release.

Qué son una especificación viva y una lista de brechas

Una especificación viva es una descripción corta y editable de lo que la app hace hoy. No es un documento único. Cambia cada vez que cambia el comportamiento, para que el equipo pueda confiar en ella.

Cuando la gente habla de especificaciones de funciones escritas desde el código (por ejemplo, usando Claude Code), el objetivo es simple: leer el comportamiento real desde rutas, handlers y pantallas, y luego escribirlo en lenguaje llano.

Una especificación viva útil se centra en lo que los usuarios ven y en lo que el sistema promete. Debe cubrir:

  • Comportamiento visible por el usuario (qué ocurre cuando alguien hace clic, envía un formulario, inicia sesión)
  • Reglas y restricciones (campos obligatorios, límites, cálculos)
  • Casos límite (estados vacíos, errores, reintentos, timeouts)
  • Permisos (quién puede ver, crear, editar, borrar)
  • Salidas importantes (correos enviados, registros creados, cambios de estado)

Lo que no debe cubrir es cómo está organizado el código. Si empiezas a nombrar archivos y planes de refactor, estás entrando en detalles de implementación. Evita:

  • Nombres de funciones y clases, árboles de componentes
  • Debates de arquitectura y planes de reescritura

La lista de brechas es algo aparte. Es una pequeña lista de desajustes e incógnitas que encuentras al redactar la spec.

  • Bug: el código viola el comportamiento actual o una regla acordada.
  • Solicitud de funcionalidad: quieres un comportamiento nuevo.
  • Brecha: no puedes decir cuál debería ser el comportamiento correcto, o el comportamiento es inconsistente entre pantallas/roles.

Ejemplo: una ruta rechaza archivos mayores de 10MB, pero la UI dice 25MB. Eso es una brecha hasta que el equipo decida qué regla es la real y actualice el código o la spec.

Elige un alcance y un formato de spec simple

Empieza pequeño. Si intentas documentar toda la app, acabarás con un montón de notas en las que nadie confía. Elige una porción que los usuarios puedan describir en una frase, como “invitar a un compañero”, “checkout” o “restablecer contraseña”. Buenos alcances son un área de funcionalidad, un módulo o un recorrido de usuario desde el punto de entrada hasta el resultado.

Elige tu punto de entrada según dónde viva la verdad:

  • Si necesitas las reglas reales, empieza por rutas y handlers.
  • Si necesitas la experiencia real, empieza por los puntos de entrada de la UI.
  • Si la funcionalidad está enredada, empieza por la página/controlador de mayor nivel y trabaja hacia afuera.

Antes de leer código, recopila algunas entradas para que los desajustes sobresalgan rápido: cualquier doc de API existente, notas antiguas de producto, tickets de soporte y los “puntos de dolor conocidos” que la gente menciona. Estos no anulan el código, pero te ayudan a notar estados faltantes como errores, casos límite y permisos.

Mantén el formato de la spec aburrido y consistente. Los equipos se alinean más rápido cuando cada spec se lee igual.

Plantilla de spec (repetir para cada flujo visible al usuario)

  • Propósito: lo que el usuario intenta lograr
  • Puntos de entrada: dónde comienza el flujo (URL, menú, botón)
  • Precondiciones: auth, roles, datos requeridos
  • Flujo principal: 5–10 pasos en lenguaje claro
  • Datos y efectos secundarios: registros creados/actualizados, correos, logs
  • Errores y casos límite: qué pasa cuando algo falla
  • Preguntas abiertas: comportamientos poco claros que necesitas confirmar

Usa esta estructura repetidamente y tus especificaciones serán legibles, comparables y fáciles de actualizar.

Extraer comportamiento desde rutas y handlers

Empieza por puntos de entrada del servidor. Rutas y handlers muestran “qué hace la app” en términos concretos: quién puede llamarla, qué deben enviar, qué reciben y qué cambia en el sistema.

Lista las rutas en alcance y mapea cada una a una intención de usuario. No escribas “POST /api/orders.” Escribe “Realizar un pedido” o “Guardar un borrador.” Si no puedes nombrar la intención en palabras simples, eso ya es una brecha en la spec.

Mientras lees cada handler, captura inputs y reglas de validación como requisitos visibles para el usuario. Incluye campos obligatorios, formatos permitidos y las reglas que generan errores reales. Por ejemplo: “El email debe ser válido”, “La cantidad debe ser al menos 1”, “La fecha de inicio no puede ser en el pasado.”

Escribe las comprobaciones de auth y roles de la misma forma. En lugar de “middleware: requireAdmin”, documenta: “Solo los administradores pueden cancelar cualquier pedido. Los usuarios regulares solo pueden cancelar su propio pedido dentro de 10 minutos.” Si el código comprueba propiedad, feature flags o límites por tenant, inclúyelos también.

Luego anota salidas y resultados. ¿Qué devuelve el éxito (un ID creado, un objeto actualizado)? ¿Cómo lucen los fallos comunes (401 no autenticado, 403 no permitido, 404 no encontrado, 409 conflicto, 422 error de validación)?

Finalmente, registra los efectos secundarios porque son parte del comportamiento: registros creados o actualizados, emails o notificaciones enviados, eventos publicados, jobs en background encolados y cualquier cosa que desencadene otros flujos. Estos detalles evitan sorpresas cuando los equipos confían en la spec más adelante.

Extraer comportamiento desde componentes y flujos de UI

Las rutas te dicen qué puede hacer la app. Los componentes te dicen lo que los usuarios realmente experimentan. Trata la UI como parte del contrato: qué aparece, qué se bloquea y qué pasa cuando algo falla.

Empieza por encontrar las pantallas de entrada para la funcionalidad. Busca el componente de página, el layout y algunos componentes de “decisión” que controlan fetch, permisos y navegación. Ahí suele estar el comportamiento real.

Al leer componentes, captura reglas que los usuarios pueden percibir: cuándo las acciones están deshabilitadas, pasos requeridos, campos condicionales, estados de carga y cómo aparecen los errores (errores inline bajo el campo vs toast, reintento automático, botones de “intentar de nuevo”). También anota comportamiento de estado y caché como datos obsoletos mostrando primero, actualizaciones optimistas o timestamps de “último guardado”.

Fíjate en flujos ocultos que cambian silenciosamente lo que los usuarios ven. Busca feature flags, buckets de experimentos y puertas solo para admins. Anota redirecciones silenciosas también, como enviar usuarios desconectados al inicio de sesión o enviar usuarios sin acceso a una pantalla de upgrade.

Un ejemplo concreto: en una pantalla de “Cambiar email”, documenta que Guardar permanece deshabilitado hasta que el email sea válido, aparece un spinner durante la petición, el éxito muestra un banner de confirmación y los errores de validación del backend se renderizan bajo el input. Si el código muestra una flag como newEmailFlow, anota ambas variantes y qué difiere.

Escribe cada flujo de UI como pasos cortos (qué hace el usuario, qué hace la UI a cambio) y mantiene condiciones y errores junto al paso que afectan. Eso mantiene la spec legible y hace que las brechas sean más fáciles de detectar.

Convertir hallazgos en especificaciones legibles

Planifica cambios de forma segura
Usa el modo de planificación para bosquejar cambios antes de tocar el código.

Las notas crudas de rutas y componentes son útiles, pero difíciles de discutir. Reescribe lo que observaste en una spec que un PM, diseñador, QA e ingeniero puedan leer y acordar.

Un patrón práctico es una historia de usuario por ruta o pantalla. Manténlo pequeño y específico. Por ejemplo: “Como usuario autenticado, puedo restablecer mi contraseña para recuperar el acceso.” Si el código muestra comportamiento distinto por rol (admin vs usuario), sepáralo en historias distintas en lugar de esconderlo en notas al pie.

Luego escribe criterios de aceptación que reflejen rutas reales del código, no el producto ideal. Si el handler devuelve 401 cuando falta el token, ese es un criterio. Si la UI deshabilita enviar hasta que un campo sea válido, ese es un criterio.

Incluye reglas de datos en lenguaje claro, especialmente las que causan sorpresas: límites, ordenamientos, unicidad, campos obligatorios. “Los nombres de usuario deben ser únicos (comprobado al guardar)” es más claro que “índice único.”

Los casos límite suelen ser la diferencia entre un buen documento y uno útil. Señala estados vacíos, valores nulos, reintentos, timeouts y qué ven los usuarios cuando una llamada a la API falla.

Cuando topes con incógnitas, márcalas en lugar de adivinar:

  • Desconocido: ¿qué mensaje debe aparecer cuando el email no se encuentra?
  • Desconocido: ¿permitimos 0 artículos o forzamos al menos 1?
  • Desconocido: ¿este error debe mostrarse al usuario o solo registrarse?

Esos marcadores se convierten en preguntas rápidas para el equipo en lugar de suposiciones silenciosas.

Crear una lista de brechas sin convertirla en backlog

Una lista de brechas no es un segundo Jira. Es un registro corto y basado en evidencia de dónde el código y el comportamiento previsto no coinciden, o dónde nadie puede explicar claramente qué es “correcto”. Bien hecha, se convierte en una herramienta de acuerdo, no en una pelea de planificación.

Sé estricto sobre lo que cuenta como brecha:

  • Comportamiento poco claro: la app hace algo pero la regla no está escrita en ninguna parte.
  • Inconsistencia: dos lugares se comportan distinto para el mismo caso.
  • Regla faltante: existe un caso límite pero no hay decisión visible en código o docs.

Cuando registres una brecha, incluye tres partes para que se mantenga fundamentada:

  • Tipo: bug (el código parece incorrecto) o decisión faltante (intención poco clara)
  • Impacto: confusión del usuario, riesgo de seguridad, pérdida de datos, o menor
  • Evidencia: dónde lo viste y qué observaste (ruta/handler/componente)

La evidencia es lo que evita que la lista se convierta en opiniones. Por ejemplo: “POST /checkout/apply-coupon acepta cupones expirados, pero CouponBanner.tsx los bloquea en la UI. Impacto: ingresos y confusión del usuario. Tipo: bug o decisión faltante (confirmar regla real).”

Manténla corta. Pon un límite, como 10 ítems en la primera pasada. Si encuentras 40 problemas, agrúpalos en patrones (inconsistencias de validación, comprobaciones de permisos, estados vacíos) y conserva solo los ejemplos más representativos.

Evita fechas y programación dentro de la lista de brechas. Si necesitas propiedad, mantenlo ligero: anota quién debe tomar la decisión (producto) o quién puede verificar el comportamiento (ingeniería) y traslada la planificación real a tu backlog.

Ejemplo: documentando una función real desde el código

Encuentra brechas antes de enviar
Compara el comportamiento de UI y API en conversación y lista las discrepancias con evidencia.

Elige un alcance pequeño y de alto tráfico: checkout con códigos promocionales y opciones de envío. El objetivo no es reescribir todo el producto, sino capturar lo que la app hace hoy.

Empieza por las rutas del backend. Ahí suelen aparecer las reglas primero. Podrías encontrar rutas como POST /checkout/apply-promo, GET /checkout/shipping-options y POST /checkout/confirm.

Desde esos handlers, redacta el comportamiento en palabras claras:

  • Los códigos promocionales se validan en el servidor (expirados, límite de uso, elegibilidad del cliente).
  • Los totales se recalculan tras aplicar el promo, pero solo después de re-verificar inventario.
  • Las opciones de envío dependen del destino, peso y si algún artículo está marcado como “restricted”.
  • Confirmar falla si el stock de una línea cambió desde que se cargó el carrito.
  • El impuesto se calcula después de elegir el envío (no cuando se aplica el promo).

Luego verifica componentes de UI. Un PromoCodeInput puede mostrar que los totales solo se actualizan tras una respuesta exitosa y que los errores se muestran inline bajo el input. Un componente ShippingOptions puede seleccionar automáticamente la opción más barata al cargar y desencadenar una actualización completa del desglose de precios cuando el usuario la cambia.

Ahora tienes una spec legible y una pequeña lista de brechas. Por ejemplo: los mensajes de error difieren entre la ruta de promo y la UI (“Invalid code” vs “Not eligible”), y nadie puede señalar una regla clara de redondeo de impuestos (por línea vs total del pedido).

En la planificación, el equipo acuerda la realidad primero y luego decide qué cambiar. En lugar de debatir opiniones, revisas comportamientos documentados, eliges una inconsistencia a arreglar y dejas el resto como “comportamiento actual conocido” hasta que valga la pena revisarlo.

Validar la spec con el equipo y mantenerla actual

Una spec solo ayuda si el equipo acuerda que coincide con la realidad. Haz una lectura corta con un ingeniero y una persona de producto. Manténla estrecha: 20–30 minutos centrados en lo que los usuarios pueden hacer y qué hace el sistema en respuesta.

Durante la revisión, convierte afirmaciones en preguntas de sí/no. “Cuando un usuario llama a esta ruta, ¿siempre devolvemos 403 sin sesión?” “¿Este estado vacío es intencional?” Esto separa el comportamiento intencional del accidental que se coló con el tiempo.

Alineen el vocabulario antes de editar. Usa las palabras que ven los usuarios en la UI (etiquetas de botones, títulos de página, mensajes). Añade nombres internos solo cuando ayuden a los ingenieros a encontrar el código (nombres de rutas, nombres de componentes). Esto evita desajustes como que producto diga “Workspace” mientras la spec dice “Org”.

Para mantenerla actual, haz explícita la propiedad y la cadencia:

  • Responsable de la spec: una persona que fusione cambios (suele ser el owner de la función o tech lead)
  • Disparador de actualización: en el merge del PR para cambios de comportamiento, o en cada release
  • Revisión rápida: añade una casilla “spec actualizada?” en la plantilla del PR
  • Almacenamiento: mantenla cerca del código para que cambie con el código

Si usas una herramienta como Koder.ai, los snapshots y rollback pueden ayudarte a comparar “antes” y “después” del comportamiento cuando actualizas una spec, especialmente tras un refactor grande.

Errores comunes y trampas

La forma más rápida de perder la confianza en una spec es describir el producto que quieres, no el producto que tienes. Mantén una regla dura: cada afirmación debe respaldarse con algo que puedas señalar en el código o en una pantalla real.

Otra trampa común es copiar la forma del código en el documento. Una spec que lee “Controller -> Service -> Repository” no es una spec, es un mapa de carpetas. Escribe en términos visibles para el usuario: qué desencadena la acción, qué ve el usuario, qué se guarda y cómo lucen los errores.

Los permisos y roles a menudo se ignoran hasta el final y entonces todo falla. Añade reglas de acceso temprano, incluso si son desordenadas. Señala qué roles pueden ver, crear, editar, borrar, exportar o aprobar, y dónde se aplica la regla (solo UI, solo API o ambos).

No omitas los caminos no felices. El comportamiento real se esconde en reintentos, fallos parciales y reglas basadas en tiempo como expiraciones, cooldowns, jobs programados o límites “solo una vez al día”. Trata estos casos como comportamientos de primera clase.

Una forma rápida de sacar brechas es comprobar:

  • Fallos de validación y los mensajes exactos que ve el usuario
  • Manejo de envíos duplicados (idempotencia)
  • Trabajo en background (colas, cron) y qué pasa si falla
  • Problemas de concurrencia (dos usuarios cambiando el mismo registro)
  • Comportamientos basados en tiempo (timeouts, expiraciones, límites de tasa)

Finalmente, mantén tu lista de brechas en movimiento. Cada brecha debe etiquetarse como: “desconocido, necesita decisión”, “bug, arreglar” o “feature faltante, planificar”. Si nada se etiqueta, la lista se atora y la spec deja de ser “viva”.

Lista rápida antes de compartir una spec

Envía con código exportado
Genera apps por chat y exporta el código fuente completo cuando lo necesites.

Haz una pasada rápida por claridad, cobertura y accionabilidad. Alguien que no la escribió debe entender qué hace la función hoy y qué sigue sin estar claro.

Claridad y entendimiento compartido

Lee la spec como un nuevo compañero en su primer día. Si puede resumir la función en un minuto, estás cerca. Si sigue preguntando “¿dónde empieza esto?” o “¿cuál es la ruta feliz?”, ajusta la apertura.

Comprueba:

  • Prueba de una página: la apertura indica el objetivo del usuario, dónde inicia el flujo y dónde termina.
  • Roles y acceso: roles clave y qué puede o no hacer cada uno.
  • Resultados: qué parece el éxito y qué ve el usuario cuando falla (mensajes, redirecciones, reintentos).
  • Bordes y límites: límites de tamaño, límites de tasa, timeouts, reglas de validación y qué pasa cuando faltan datos.
  • Lenguaje: usa términos visibles para el usuario primero; define la jerga inevitable una vez.

Brechas que ayudan, no ruido

Cada brecha debe ser específica y comprobable. En lugar de “Manejo de errores poco claro”, escribe: “Si el proveedor de pagos devuelve 402, la UI muestra un toast genérico; confirmar mensaje deseado y comportamiento de reintento.” Añade una única acción siguiente (preguntar a producto, añadir un test, inspeccionar logs) y anota quién debe responder.

Próximos pasos para comenzar esta semana

Elige una área funcional y ponle un límite de tiempo de 60 minutos. Escoge algo pequeño pero real (login, checkout, búsqueda, una pantalla de admin). Escribe una oración de alcance: qué incluye y qué queda fuera.

Ejecuta el flujo una vez de extremo a extremo: revisa por encima rutas/handlers clave, traza el flujo UI principal y anota comportamientos observables (inputs, outputs, validación, estados de error). Si te quedas atascado, registra la pregunta como brecha y sigue adelante.

Cuando termines, comparte la spec donde el equipo pueda comentar y establece una regla: cualquier cambio de comportamiento enviado debe actualizar la spec en la misma ventana de entrega, aunque sean cinco líneas.

Mantén las brechas separadas del backlog. Agrúpalas en “comportamiento desconocido”, “comportamiento inconsistente” y “tests faltantes”, y repásalas brevemente cada semana para decidir qué importa ahora.

Si redactar e iterar se siente lento, un generador en chat como Koder.ai puede ayudarte a conseguir una primera versión rápidamente. Describe la función, pega fragmentos clave o nombres de rutas, refina el texto en conversación y exporta la fuente cuando la necesites. La idea es velocidad y claridad compartida, no un proceso mayor.

Preguntas frecuentes

¿Por dónde empiezo si quiero escribir una especificación de función a partir del código?

Comienza con una porción pequeña y visible para el usuario (por ejemplo, “restablecer contraseña” o “invitar a un compañero”). Lee las rutas/handlers para captar reglas y resultados, luego revisa el flujo de UI para registrar lo que los usuarios realmente ven (estados deshabilitados, errores, redirecciones). Redáctalo usando una plantilla consistente y registra las incógnitas en una lista de brechas separada.

¿La especificación debe describir lo que el producto debería hacer o lo que hace el código hoy?

Por defecto: trata el comportamiento actual del código como la fuente de la verdad y documéntalo.

Si el comportamiento parece accidental o inconsistente, no lo “arregles” en la especificación: márcalo como una brecha con evidencia (dónde lo viste y qué hace) y pide una decisión para actualizar el código o la especificación.

¿Cuál es un formato simple de especificación que se mantiene legible a medida que la app crece?

Mantenla aburrida y repetible. Una plantilla práctica es:

  • Propósito
  • Puntos de entrada
  • Precondiciones (auth/roles/datos)
  • Flujo principal (5–10 pasos)
  • Datos y efectos secundarios
  • Errores y casos límite
  • Preguntas abiertas

Esto mantiene las especificaciones legibles y facilita detectar desajustes.

¿Cómo transformo la validación del handler y las comprobaciones de auth en requisitos en lenguaje natural?

Escribe las reglas como requisitos visibles para el usuario, no como notas de código.

Ejemplos:

  • “El email debe ser válido”
  • “La cantidad debe ser al menos 1”
  • “Solo los admins pueden cancelar cualquier pedido; los usuarios normales pueden cancelar sus propios pedidos dentro de 10 minutos”

Incluye qué desencadena un error y qué experimenta el usuario cuando ocurre.

¿Qué salidas y efectos secundarios debe incluir una especificación?

Céntrate en lo observable:

  • Resultado exitoso (qué cambia, qué ve el usuario)
  • Tipos comunes de fallo (no autenticado, no permitido, no encontrado, error de validación)
  • Efectos secundarios (registros actualizados, correos/notificaciones enviados, jobs en background encolados)

Los efectos secundarios importan porque afectan a otras funciones y a las expectativas de soporte/ops.

¿Qué hago si la UI y el backend no coinciden (por ejemplo, distintos límites de tamaño de archivo)?

Si la UI bloquea algo que la API permite (o al revés), regístralo como una brecha hasta que se tome una decisión.

Anota:

  • Qué dice/hace la UI
  • Qué fuerza el backend
  • El impacto (confusión, seguridad, problemas de datos)

Luego acuerden una regla y actualicen tanto el código como la especificación para que coincidan.

¿Cómo escribo una lista de brechas sin convertirla en una pelea de planificación?

Mantén la lista de brechas pequeña y basada en evidencia. Cada ítem debe incluir:

  • Tipo: bug vs decisión pendiente
  • Impacto: menor vs serio (confusión, seguridad, pérdida de datos)
  • Evidencia: dónde lo observaste (ruta/handler/componente) y el comportamiento exacto

Evita programar o convertirla en una segunda lista de tareas.

¿Qué casos límite son los más importantes de capturar en una especificación viva?

Documenta explícitamente en lugar de esconderlos.

Incluye:

  • Estados vacíos (sin resultados, sin permisos)
  • Reintentos/timeouts y qué puede hacer el usuario después
  • Envios duplicados (doble clic, refrescar)
  • Concurrencia (dos personas editando el mismo registro)
  • Reglas basadas en tiempo (expiraciones, límites diarios)

Ahí suelen aparecer sorpresas y bugs.

¿Cómo valido la especificación con el equipo para que la gente confíe en ella?

Hazlo corto: una lectura de 20–30 minutos con un ingeniero y una persona de producto.

Convierte las afirmaciones en comprobaciones de sí/no (por ejemplo, “¿Siempre devolvemos 403 si no hay sesión?”). Alineen el vocabulario usando las palabras que aparecen en la UI (etiquetas y mensajes) para que todos signifiquen lo mismo.

¿Cómo mantengo la especificación “viva” en lugar de dejar que se desvanezca otra vez?

Acerca la especificación al código y haz que las actualizaciones sean parte del envío.

Defaults prácticos:

  • Un responsable claro que fusione cambios en la spec
  • Disparador de actualización: cualquier cambio de comportamiento fusionado o cada release
  • Añadir al PR checklist: “¿Spec actualizada?”
  • Mantener las brechas separadas y revisarlas con regularidad

La meta son ediciones pequeñas y frecuentes, no una gran reescritura.

Related posts