Discusión

Flujo de trabajo de sincronización de especificaciones OpenAPI con informe de diferencias y comando /api-sync

De Wikiprompt, la enciclopedia libre de prompts

Nurullah Sevinçtekin

17 sept 2026

Flujo de trabajo de sincronización de especificaciones OpenAPI con informe de diferencias y comando /api-sync Un flujo de trabajo completo para configurar un script de sincronización de especificaciones OpenAPI, un comando de barra para planificación e integración en un proyecto. Incluye instrucciones detalladas para encontrar la especificación, comparar, generar informes y clasificar.

Contenido del PromptGuardar

🌐
# Configurar un flujo de trabajo de sincronización de especificaciones OpenAPI en este proyecto Quiero el mismo flujo de trabajo de especificación de backend que uso en otro repositorio: un script que compara la especificación OpenAPI en vivo contra una instantánea local y escribe un informe de cambios **orientado al frontend**, más un comando de barra `/api-sync` que convierte ese informe en un plan por fases. Completa estos datos desde el repositorio antes de comenzar (pregúntame solo si no puedes resolverlo): - **Fuente de la especificación**: encuéntrala tú mismo - ver Parte 0. No me preguntes por la URL hasta que hayas buscado. Lo que encuentres se convierte en el valor predeterminado del script, anulable mediante una variable de entorno `OPENAPI_URL`. - **Ruta de la instantánea**: `api-spec/openapi.yaml` · **Ruta del informe**: `api-spec/CHANGES.md` - **Raíz de origen para referencias cruzadas**: `src/` (ajusta al diseño de este repositorio) - **Biblioteca de validación de respuestas**: zod (ajusta si este repositorio usa otra cosa) - **¿Instantánea en git?** Mantén el yaml **ignorado por git** (demasiado grande/ruidoso para el historial) pero **confirma `CHANGES.md`** - el informe generado es el registro duradero de qué cambió y cuándo. También ignora `api-spec/openapi-*.yaml` y `api-spec/CHANGES-*.md` (archivos manuales con fecha). Lee este repositorio primero (gestor de paquetes, convenciones de scripts, cómo se escriben las llamadas API y los esquemas de respuesta) y adapta su estilo. No inventes rutas - busca las reales con grep. --- ## Parte 0 - encuentra la especificación antes de escribir nada Haz esto primero y dime lo que encontraste. No adivines una URL, y no me preguntes hasta que esto salga vacío. **1. Los documentos - el lugar más barato, y normalmente correcto.** `README.md`, `CLAUDE.md`, `AGENTS.md`, `CONTRIBUTING.md`, cualquier cosa en `docs/`, `.github/`, `.cursor/rules/`, un archivo de prueba `*.http`/`*.rest`, o un checkout del wiki. La URL suele estar en prosa ("API docs: …/swagger"), en un paso de configuración, o junto al enlace del repositorio backend: ```bash grep -rniE 'swagger|openapi|api-?docs|redoc|\/v3\/api-docs' --include='*.md' --include='*.mdx' --include='*.txt' --include='*.http' --include='*.rest' . | grep -v node_modules ``` Dos trampas: un **enlace de Swagger UI** (`…/swagger-ui/index.html`, `…/docs`, `…/redoc`) es una página HTML, no la especificación - deriva la URL de máquina a partir de ella (`/swagger-ui/index.html` → `/v3/api-docs`, `/docs` → `/openapi.json`, `/redoc` → el `spec-url` en su HTML) y verifica con curl. Y una URL de documentos puede estar **desactualizada** - confirma que responde antes de adoptarla, y dime si el README apunta a algo muerto. **2. Un archivo de especificación ya en o cerca del repositorio** - alguien suele dejar uno: ```bash find . -path ./node_modules -prune -o -iregex '.*\(swagger\|openapi\|api-docs\).*\.\(ya?ml\|json\)' -print git ls-files | grep -iE 'swagger|openapi|api-docs' ``` También revisa `node_modules/.cache/`, `.next/cache/`, `dist/`, `build/`, `coverage/` y cualquier carpeta ignorada por git `api/`, `api-spec/`, `docs/`, `schemas/` - una ejecución anterior de generación de código suele dejar una copia allí. Una copia en caché desactualizada sigue siendo útil: es una **línea base para sembrar la instantánea**, para que la primera diferencia real sea significativa en lugar de "todo es nuevo". Si encuentras una, di qué tan antigua es (`git log -1` / mtime del archivo) antes de decidir confiar en ella. **3. Una configuración de generador que ya nombre la fuente** - este es el hallazgo de mayor señal, porque apunta a la URL o ruta que el equipo realmente usa: ```bash grep -rniE 'openapi|swagger|api-docs' --include='*.json' --include='*.ts' --include='*.js' --include='*.mjs' --include='*.yaml' --include='*.yml' --include='.env*' --include='Makefile' --include='*.sh' -l . | grep -v node_modules ``` Busca específicamente: configuración de `openapi-typescript` / `orval.config.*` / `kubb.config.*` / `swagger-typescript-api` / `@hey-api/openapi-ts`, un script npm tipo `openapi` en package.json, una URL base de API en `.env*`, URLs de servicio en `docker-compose.yml`, pasos de flujo de trabajo de CI, o un cliente generado confirmado cuyo comentario de cabecera cite su especificación fuente. **4. Derívala de la URL base de la API.** Si solo encuentras una URL base, prueba las rutas convencionales para el framework de ese backend antes de preguntarme - FastAPI `/openapi.json`, Spring/springdoc `/v3/api-docs` (+ `.yaml`), ASP.NET `/swagger/v1/swagger.json`, NestJS `/api-json`, Rails/rswag `/api-docs/v1/swagger.yaml`, más `/openapi.yaml` y `/swagger.json` simples: ```bash curl -sS -o /dev/null -w '%{http_code} %{content_type} %{url_effective}\n' <BASE>/openapi.json ``` Informa cuáles respondieron. Si todas requieren autenticación, dilo - no incorpores un token en el script. **5. ¿Nada funciona?** Entonces pregúntame, y dime qué descartaste. ### Si la especificación no es accesible por HTTP No fuerces el diseño de descarga. Haz que la fuente sea un único `SPEC_SOURCE` que puede ser **una URL, una ruta local, o un comando de shell** (por ejemplo, el propio `make openapi` del repositorio backend, o un archivo generado de un checkout hermano), resuelto en ese orden: flag `--to <archivo>` → variable de entorno `OPENAPI_URL` → el valor predeterminado que descubriste. Todo lo posterior - diferencia, informe, instantánea - no cambia. Di en `CLAUDE.md` cuál usa este repositorio y cómo actualizarlo. ## Parte 1 - `scripts/sync-api.mjs` Un script Node ESM único con pocas dependencias (`js-yaml` es la única dependencia nueva; usa el gestor de paquetes del repositorio). Flags: ``` node scripts/sync-api.mjs descargar remoto → comparar vs instantánea → escribir informe + sobrescribir instantánea node scripts/sync-api.mjs --check solo comparar, instantánea intacta, salir con 1 si hay desviación (compatible con CI) node scripts/sync-api.mjs --from <archivo> comparar contra <archivo> en lugar de la instantánea node scripts/sync-api.mjs --to <archivo> tratar <archivo> como "remoto" en lugar de descargar (sin conexión) node scripts/sync-api.mjs --json también imprimir la diferencia cruda como JSON en stdout ``` Añade `"sync:api": "node scripts/sync-api.mjs"` a package.json. **Si aún no existe una instantánea**: escribe la especificación descargada como instantánea, imprime "sembrada - vuelve a ejecutar después de que el backend publique para ver una diferencia", sal con 0. Nunca informes toda la API como "nueva". Excepción: si la Parte 0 encontró una especificación en caché/vendida más antigua, siembra la instantánea desde **esa** en su lugar y ejecuta una diferencia real contra la especificación en vivo en la primera ejecución - dime la fecha de la copia en caché para que sepa qué significa la línea base. ### Qué debe comparar Aplana `paths` en un mapa de operaciones `"GET /a/b"` → operación y compara operaciones *y* `components.schemas` por separado: **Operaciones** - añadidas / eliminadas / cambiadas - parámetros: nuevos (marca `required`), cambios requerido↔opcional, valores de enum añadidos/eliminados - identifica un parámetro por `in:name` (o `ref:Name` para parámetros `$ref`), no por índice de array - esquema del cuerpo de solicitud y de respuesta exitosa: si el nombre del `$ref` cambió, informa el renombrado; si la forma es **en línea** (sin `$ref`), compara sus propiedades aquí - un esquema sin nombre se compara aquí o en ningún lugar. Resuelve envoltorios `allOf: [$ref]` al nombre subyacente, y renderiza uniones `oneOf`/`anyOf` como `A | B` (ganar/perder un miembro de unión es un cambio de comportamiento real). - códigos de estado no-2xx nuevos/eliminados - cambios en requisitos de seguridad, recién `deprecated` **Esquemas** - propiedades añadidas (marca requeridas) / eliminadas / con tipo cambiado - valores de enum añadidos o eliminados (en el esquema y en cada propiedad, incluyendo `items.enum`) - cambios requerido↔opcional ### Las dos cosas que hacen que este informe valga la pena 1. **Extracción de `error_code` de la prosa de respuesta.** Los códigos de error de máquina suelen estar documentados en ningún lugar excepto en el texto `description` de cada respuesta no-2xx ("… ya es un miembro activo (already_member)"), así que una nueva rama que necesitamos manejar parece *nada cambió* para una diferencia a nivel de esquema. Parsee por **contexto, no vocabulario**: tokens dentro de `(...)`, tokens después de prosa tipo `error_code`, y cualquier token en snake_case que aparezca en el enum literal `error_code` de algún esquema. **No** filtres tokens que colisionen con nombres de campos o valores de enum - esas colisiones son exactamente los códigos que más importan. Descarta tokens introducidos por la frase "campo X" (esos son nombres de campos, no códigos). Informa códigos añadidos, y para un código que dejó de documentarse, busca en el código fuente `"ese_codigo"` y di **qué archivo ramifica sobre él** - esa es una rama muerta. 2. **Referencia cruzada de cada cambio contra el código real.** Carga cada archivo fuente una vez mediante `git ls-files --cached --others --exclude-standard <raíz src>` (incluye no rastreados para que un sitio de llamada añadido en esta sesión cuente; omite archivos listados pero eliminados del árbol de trabajo), luego: - **Sitios de llamada** para una ruta: convierte parámetros de ruta en comodines de un solo segmento y exige que la coincidencia termine en una comilla/backtick/`?` para que `/orgs/{id}` no coincida con `/orgs/${id}/archive`. Cada operación eliminada/cambiada lista sus sitios de llamada, o "⛔ sin sitio de llamada". - **Espejos de esquema**: encuentra el archivo que contiene nuestro espejo de validación de respuesta de un esquema de especificación - coincide con `fooBarSchema` en cualquier lugar, más el nombre PascalCase simple **solo dentro de un `schemas.ts`** (en otros lugares colisiona con identificadores TS no relacionados). Adapta la convención de nombres a lo que este repositorio realmente usa - busca con grep primero. - Una nueva operación cuya ruta ya está referenciada en `src/` recibe una nota "⚠️ ruta ya referenciada - verifica el método". ### Formato del informe (`api-spec/CHANGES.md`) Encabezado con fecha de generación, etiqueta de línea base, `info.version` de la especificación, y conteos de operaciones y esquemas antes→después; luego una pequeña tabla de añadidos/eliminados/cambiados; luego secciones, en este orden: - `## 🔴 Operaciones eliminadas - rompe si las llamamos` (con sitios de llamada) - `## 🟡 Operaciones cambiadas` (viñetas anidadas por cambio + sitios de llamada) - `## 🟢 Operaciones nuevas`, agrupadas por área de ruta (primer segmento, con casos especiales sensatos para los prefijos de esta API) - resumen, esquema de respuesta, esquema del cuerpo de solicitud - `## 🔴 Esquemas eliminados` (con archivos espejo) - `## 🟡 Esquemas cambiados` - **los espejados primero ordenados y en negrita con el archivo espejo**, ya que esos son los que pueden romper el parseo hoy; el resto son informativos - `## 🟢 Esquemas nuevos` (una línea separada por comas) Si nada cambió, el cuerpo es exactamente "Sin cambios desde la última instantánea." Pon al inicio del archivo "no editar a mano". Mantén el script comentado donde una decisión no sea obvia (la heurística de error_code, el ancla final del comparador de rutas, por qué se incluyen archivos no rastreados) - el yo futuro lee esos comentarios. ## Parte 2 - `.claude/commands/api-sync.md` Un comando de barra (`/api-sync [alcance]`, alcance opcional, también acepta `implement`) que ejecuta el flujo de trabajo. Frontmatter: `description` + `argument-hint`. Pasos: 1. **Comparar** - ejecuta `npm run sync:api`, lee `api-spec/CHANGES.md`. Señala las dos decisiones de juicio que el informe puede marcar pero no decidir: un **cuerpo de solicitud** cambiado en un sitio de llamada en vivo es accionable incluso sin espejo de esquema (construimos cuerpos a mano), y un **`error_code`** nuevo es una rama que aún no tenemos - si es un error de campo debe renderizarse en línea en el campo, no solo como un toast. Si el informe dice que no hay cambios, dilo y detente - no inventes trabajo. 2. **Clasifica cada elemento** en: Rompe (P0) · Silenciosamente incorrecto - un esquema espejado ganó un campo requerido o un enum creció con valores que nuestro validador rechaza (P0) · Ahora-incompleto - un cuerpo de solicitud construido a mano ganó un campo, o un nuevo `error_code` en el que no ramificamos (P1) · Des-mockea una pantalla (P1) · Extiende una pantalla (P2) · Característica completamente nueva (P3) · Solo-backend (descartar). Nunca omitas un elemento; si no encaja en ningún lugar, lístalo como una pregunta abierta. Verifica cada clasificación contra el código en lugar de asumir - abrie el archivo espejo nombrado, busca con grep el fixture mock, confirma que la pantalla existe. 3. **Escribe el plan** - una sección con fecha en `ROADMAP.md` (o el equivalente de este repositorio; crea uno si no hay), ordenada por esas prioridades y por fases para que cada fase se publique de forma independiente. Por elemento: los endpoints y archivos que cambian, qué puede hacer el usuario después que no puede hoy (el punto del trabajo - no "conectar endpoint X"), y si está bloqueado y por quién. Una línea por elemento. Luego actualiza cualquier documento de cobertura/seguimiento que este repositorio mantenga. 4. **Informa de vuelta en el chat** - qué publicó el backend en un párrafo en lenguaje simple, cualquier cosa rota ahora mismo con el archivo a corregir, las fases una línea cada una, y preguntas genuinas para el dev del backend solamente. Detente ahí; solo si el argumento contiene `implement`, construye **solo la Fase 1**, luego ejecuta el typecheck + lint de este repositorio e informa antes de continuar. ## Parte 3 - conéctalo - Añade las entradas de gitignore. - Añade una sección corta **Flujo de trabajo de cambios de backend** a `CLAUDE.md` (críala si falta): la instantánea es local y está ignorada por git, `CHANGES.md` es el registro confirmado, `CHANGES.md` se genera así que nunca lo edites a mano, `/api-sync` cuando el dev del backend diga que algo se publicó, `npm run sync:api -- --check` para detectar desviación, y el hábito de archivar un `api-spec/openapi-YYYY-MM-DD.yaml` con fecha antes de un gran cambio de backend como punto de referencia confirmado. - Siembra la instantánea ejecutando el script una vez, y muéstrame el primer informe - más una nota de una línea sobre de dónde vino la especificación y, si sembraste desde una copia en caché, qué tan desactualizada estaba.

Iniciá sesión para ver el prompt completo

Continuar con:

Al iniciar sesión, aceptás nuestros Términos de uso y Política de privacidad

Uso

Este prompt está diseñado para usarse con coding. Copiá el contenido de arriba y pegalo en tu herramienta de IA preferida.

Para mejores resultados, personalizá los marcadores (indicados con corchetes o mayúsculas) con tus requisitos específicos.

Referencias

Categorías:coding| prompts.chat| openapi| api-sync

Discusión