Un skill de Claude Code que toma un cambio de esquema descrito y te devuelve una migración forward revisada, un rollback probado y un informe de riesgo de locks y pérdida de datos, para que dejes de correr ALTERs destructivos contra producción a las 11 de la noche.

En resumen
- Genera tres artefactos, no uno: la migración forward, el rollback y un informe de riesgo que clasifica cada sentencia.
- Se dispara por la intención, 'agrega una columna', 'cambia este tipo', 'pon esto NOT NULL', e inspecciona el esquema en vivo antes de escribir una sola línea.
- Cada sentencia queda etiquetada como segura en línea, riesgosa o destructiva. Las riesgosas van con el patrón de dos pasos (backfill y después restringir) en vez de un ALTER de un solo golpe.
- Genera el SQL; no lo aplica. Tú lo lees, lo corres en una rama o en el stack local, y solo entonces lo promueves.
- Una migración sin bajada probada es un riesgo, no una mejora: el skill se niega a entregarte una sin su rollback.
Los cambios de esquema son donde hasta el ingeniero más tranquilo entra en pánico. El ALTER que se veía inofensivo en una base de prueba toma un lock exclusivo sobre una tabla de 40 millones de filas en producción, la app empieza a dar timeout, y de repente estás leyendo la documentación de locks de Postgres mientras el celular no para de vibrar. Un skill de migración existe para llevar ese análisis a antes de que escribas el comando, no después. Al terminar esto vas a tener un skill de Claude Code empaquetado que inspecciona el esquema en vivo, escribe una migración forward y su rollback, y te entrega un informe de riesgo que dice exactamente cuáles sentencias bloquean la tabla o borran datos, para que la parte fea sea una revisión y no una sorpresa.
Esto no es magia. Es un checklist con dientes, conectado a las herramientas para que el modelo lea tu esquema real en vez de adivinarlo. Todo el valor está en que lo peligroso se clasifica al principio, en lenguaje claro, donde tú puedes vetarlo.
01 · Qué hace el skill en realidad
Un skill de migración toma un cambio de esquema descrito, "agrega una columna bio nullable a profiles", "cambia amount de integer a numeric", "pon email NOT NULL", y produce tres artefactos:
- La migración forward: el SQL que aplica el cambio.
- El rollback: la migración de bajada que lo revierte, escrita en el momento, no prometida para después.
- El informe de riesgo: cada sentencia clasificada por radio de impacto, con su comportamiento de lock y cualquier pérdida de datos resumidos en una línea cada uno.
Lo que importa es el tercer artefacto. Un ALTER TABLE … ADD COLUMN lo escribe cualquiera. El skill se gana el sueldo cuando te avisa, antes de que corras nada, que esta sentencia en particular reescribe la tabla entera y mantiene un lock todo ese rato. Es la diferencia entre una migración que puedes leer y una puerta de un solo sentido que cruzas a ciegas.
Nota
Esto es un generador, no un operador. El skill escribe el SQL y se detiene. Nunca recurre a «apply_migration» contra un proyecto remoto por su cuenta. El humano lo corre, en una rama, en un stack local, y solo entonces lo promueve. Si mantienes esa frontera, el skill te multiplica la fuerza; si la difuminas, es un arma cargada apuntando a producción.
02 · Cuándo debe dispararse
El skill se dispara por la intención de cambiar una tabla, no por la palabra "migración". Su descripción debe hacer que Claude lo agarre cada vez que la conversación se mete a alterar esquema. Una buena redacción de disparo, puesta en la descripción del skill para que se active sin que tú lo nombres:
---
name: db-migration
description: >-
Úsalo cuando el usuario quiera cambiar un esquema de Postgres/Supabase:
agregar o eliminar una columna, cambiar el tipo de una columna, agregar
una constraint o NOT NULL, renombrar, agregar un índice o alterar una
tabla. Genera una migración forward revisada, un rollback y un informe
de riesgo de locks y pérdida de datos. Se dispara con "agrega una
columna", "cambia este tipo", "pon esto NOT NULL", "agrega un índice",
"elimina", "renombra columna".
---
Las frases de la descripción pesan más que la prosa que las rodea. "Cambia este tipo", "pon esto NOT NULL", "elimina una columna" son justo lo que dice un dev segundos antes de provocar un incidente, así que esas son las frases que deben activar el skill.
No debe dispararse con un SELECT puro, una query de solo lectura ni una pregunta sobre los datos. Eso son tareas de reporte, no cambios de esquema, y un skill de migración activándose ahí solo agrega fricción. Acótalo bien a DDL.
Consejo
Mete los verbos peligrosos en la descripción, no solo los seguros. Un skill que únicamente menciona "agrega una columna" se va a quedar callado mientras alguien escribe sin pensarlo un cambio de tipo de columna, que es justo el que duele. Nombra los casos destructivos más fuerte que el resto.
03 · Cómo funciona por dentro
El skill corre una secuencia fija. El orden es el mecanismo de seguridad: inspecciona, luego escribe, luego clasifica, y al final se niega a saltarse el rollback.
1. Inspecciona el esquema en vivo primero
Antes de escribir una sola línea, el skill lee el estado actual. Con Supabase eso significa «list_tables» (y «list_migrations» para ver qué ya está aplicado), así escribe contra la realidad y no contra un esquema imaginado. Una migración generada contra un tipo de columna adivinado es peor que no tener migración.
2. Escribe la migración forward
Produce el SQL de subida, acotado exactamente al cambio descrito. Nada de ediciones de paso, nada de "ya que estoy aquí" limpiando otra cosa: un solo cambio lógico, para que el rollback quede simple y la revisión quede honesta.
3. Clasifica cada sentencia
Este es el núcleo. Cada sentencia recibe una etiqueta:
- Segura en línea, agregar una columna nullable, crear un índice con CONCURRENTLY, eliminar un índice con concurrently. No toman un lock pesado ni reescriben filas.
- Riesgosa, cambiar el tipo de una columna, agregar NOT NULL sin default, agregar una foreign key sin NOT VALID primero. Pueden reescribir la tabla y bloquear escrituras.
- Destructiva, eliminar una columna, eliminar una tabla, truncar. Pierden datos, y el rollback puede restaurar la estructura pero no las filas.
4. Escribe el rollback al mismo tiempo
La migración de bajada se escribe en la misma pasada, no se deja para después. Si el cambio es destructivo y un rollback de verdad es imposible (no puedes "des-eliminar" los datos), el skill lo dice de frente en vez de fingir que un CREATE TABLE trae las filas de vuelta.
Para los cambios riesgosos propone el patrón de dos pasos en vez de un ALTER de un solo golpe:
-- Subida (paso 1 de 2): agregar nullable, backfill por lotes, luego restringir.
-- Agregar NOT NULL directo escanea + bloquea la tabla entera de una vez.
alter table profiles add column status text;
update profiles set status = 'active' where status is null; -- por lotes en la app
alter table profiles
add constraint profiles_status_not_null
check (status is not null) not valid; -- NOT VALID se salta el scan completo
alter table profiles validate constraint profiles_status_not_null;
Todo el truco está en separar NOT VALID del VALIDATE: la constraint empieza a aplicar a las filas nuevas de inmediato bajo un lock liviano, y el costoso scan de toda la tabla queda para el VALIDATE, que toma un lock mucho más débil y no bloquea las escrituras.
04 · Una invocación concreta
Así se ve usarlo de punta a punta. Tú describes el cambio en lenguaje natural; el skill hace la inspección y produce los tres artefactos.
Tú: "Pon profiles.email único y obligatorio."
El skill, después de correr «list_tables»:
INFORME DE RIESGO: profiles.email → UNIQUE + NOT NULL
1. CREATE UNIQUE INDEX CONCURRENTLY ... (email) [SEGURO EN LINEA]
No reescribe la tabla. Se construye sin bloquear escrituras.
AVISO: falla si ya existen emails duplicados; revisa primero.
2. ADD NOT NULL [RIESGOSO]
El NOT NULL directo escanea + bloquea la tabla. En su lugar uso
el patron de dos pasos check NOT VALID + VALIDATE (ver migracion).
PRECONDICION: se encontraron 3 emails duplicados. La migracion va a
fallar en el paso 1 hasta que se resuelvan. Query de de-dupe abajo.
Después emite la migración de subida, la de bajada y la query de de-dupe, y se detiene. No las corre. Tú lees el informe, arreglas los duplicados, corres el SQL en una rama de Supabase, confirmas que ambas direcciones funcionan, y solo entonces haces merge al proyecto que toca producción.
Importante
El chequeo de precondición, "se encontraron 3 emails duplicados", es la parte que te salva la noche. Que el índice único falle a la mitad es mucho mejor desenlace que que corra contra una tabla que diste por limpia. Exige que el skill saque las precondiciones antes del SQL, siempre.
05 · Configuración y ajuste
Un par de settings cambian qué tan cauteloso es el skill. Mételos en sus instrucciones para que el comportamiento sea consistente de una corrida a otra:
- Entorno destino, stack local vs. una rama de Supabase vs. (nunca) remoto. Por defecto déjalo en "solo generar", y que aplicar en remoto sea un paso aparte y deliberado que toma un humano.
- Umbral de lote, para los backfills, el número de filas a partir del cual cambia de un solo UPDATE a un loop por lotes. En una tabla grande, un solo update es por sí mismo un problema de lock.
- Tolerancia a locks, si un lock breve ACCESS EXCLUSIVE es aceptable (una tabla pequeña con poco tráfico) o hay que evitarlo del todo (una tabla con mucho tráfico). Esto decide si recurre al patrón de dos pasos o acepta el de un solo golpe, más simple.
- Operaciones prohibidas, operaciones que el skill debe negarse a generar sin una autorización explícita, por ejemplo DROP TABLE o TRUNCATE en una migración pensada para producción.
La configuración existe para que el skill calce con tu tolerancia al riesgo. Una tabla de un proyecto personal con 200 filas y una tabla multi-tenant con 40 millones no merecen la misma cautela, y forzar el patrón de dos pasos en la pequeña es puro trámite.
06 · Trampas
Los modos de falla aquí son específicos, y casi todos vienen de confiar de más.
- Nunca dejes que lo aplique directo a un proyecto remoto. Esta es la regla de oro. Genera el SQL, léelo, córrelo primero en una rama o en local. Un skill con «apply_migration» conectado a producción está a un solo error de confianza de provocar un outage.
- Exige el plan de backfill en el mismo PR. Cualquier cambio que toque filas existentes necesita su plan de migración de datos revisado junto al cambio de esquema, no agregado después, cuando la columna ya quedó a medio llenar.
- Un rollback que no restaura datos no es un rollback. Para los cambios destructivos, el skill debe decir con claridad que la migración de bajada restaura la estructura, no las filas. No dejes que insinúe que puedes deshacer un DROP COLUMN sin perder nada, no puedes.
- «CREATE INDEX CONCURRENTLY» no corre dentro de una transacción. Si tu runner de migraciones envuelve todo en una transacción por defecto, la construcción del índice concurrente va a fallar. El skill debe avisar cuándo una sentencia tiene que correr fuera del bloque de transacción.
- Va a estar seguro de sí mismo y equivocado sobre tu esquema si se salta la inspección. Obliga el paso de «list_tables» primero. Una migración escrita contra un tipo de columna adivinado es la salida más peligrosa que puede producir, justamente porque se ve correcta.
Un skill de migración no va a volver los cambios de esquema libres de riesgo, nada lo logra. Lo que te da es que el riesgo quede visible antes de actuar: clasificado, con el comportamiento de lock nombrado, el rollback escrito y las precondiciones revisadas. Genera, lee, prueba en una rama, promueve. Hazlo así y el ALTER de las 11 de la noche en producción deja de ser algo que te pasa a ti.
Puntos clave
- Exige tres artefactos, no uno: migración forward, rollback y un informe de riesgo que clasifique cada sentencia antes de correr cualquier SQL.
- Haz que inspeccione el esquema en vivo con «list_tables» primero, una migración escrita contra un tipo de columna adivinado se ve correcta y es la salida más peligrosa que puede producir.
- Clasifica por radio de impacto: lo seguro en línea corre libre, lo riesgoso lleva el patrón de dos pasos NOT VALID + VALIDATE, y lo destructivo lleva el aviso más fuerte y un honesto 'el rollback restaura estructura, no datos'.
- Genera, nunca apliques. Lee el SQL, córrelo en una rama o stack local, confirma ambas direcciones, y solo entonces promueve a cualquier cosa que toque producción.
- Ajusta la cautela según la tabla, el setting de tolerancia a locks evita que una tabla de 200 filas pague el mismo trámite que una de 40 millones.
Preguntas frecuentes
¿En qué se diferencia de solo pedirle a Claude que escriba el SQL?
Un simple 'escríbeme una migración' te da el SQL de subida y nada más, sin rollback, sin inspección del esquema en vivo, sin aviso de que la sentencia bloquea la tabla. El skill empaqueta la disciplina: corre «list_tables» primero para escribir contra la realidad, clasifica cada sentencia por radio de impacto, escribe la bajada en la misma pasada y saca las precondiciones antes del SQL. El valor está en que la estructura sea la misma cada vez, no en el SQL en sí.
¿Puede el skill aplicar la migración por mí para ahorrarme un paso?
Técnicamente puede, las herramientas de Supabase exponen «apply_migration», pero no deberías conectarlo a un proyecto remoto. Toda la historia de seguridad se cae en el momento en que el modelo puede correr DDL destructivo contra producción sin que un humano lo lea primero. Genera, lee, corre en una rama o stack local, confirma ambas direcciones, y solo entonces promueve. Ese 'paso que te ahorras' es justo el paso que evita el outage de las 11 de la noche.
¿Por qué dar la vuelta con NOT VALID y luego VALIDATE en vez de solo agregar NOT NULL?
Agregar NOT NULL directo obliga a Postgres a escanear la tabla entera bajo un lock que bloquea las escrituras todo ese rato, sin problema en una tabla chica, un outage en una grande. En cambio, agregar una constraint CHECK como NOT VALID la aplica a las filas nuevas de inmediato bajo un lock liviano; el scan completo y costoso queda para el VALIDATE, que toma un lock mucho más débil y deja que las escrituras sigan. En una tabla grande y caliente, ese patrón de dos pasos es la diferencia entre un parpadeo y un atasco.
¿Y los cambios destructivos, el rollback de verdad puede deshacer una columna eliminada?
No, y el skill debe decirlo de frente. Una migración de bajada puede recrear la estructura de la columna, pero los datos que tenía se van en el instante en que haces DROP. El rollback honesto restaura la forma, no las filas. Por eso los cambios destructivos llevan la etiqueta más fuerte y por eso deberías correrlos primero en una rama con un snapshot. No dejes que el skill insinúe un deshacer limpio que no puede cumplir.
¿De verdad cada cambio necesita el tratamiento pesado del patrón de dos pasos?
No, para eso está la configuración de tolerancia a locks. Una tabla de proyecto personal con 200 filas y poco tráfico puede aguantar un lock breve ACCESS EXCLUSIVE sin que nadie lo note, así que ahí el ALTER de un solo golpe, más simple, está bien. El patrón de dos pasos justifica su complejidad en tablas grandes y calientes, donde un lock de toda la tabla significa downtime. Forzar ese trámite en una tabla pequeña es solo ruido; deja que el skill ajuste su cautela según la tabla.
¿Va a detectar un problema que mete mi runner de migraciones, como envolver todo en una transacción?
Solo si se lo dices. CREATE INDEX CONCURRENTLY no puede correr dentro de una transacción, y muchos runners envuelven cada migración en una por defecto, así que una construcción de índice 'segura en línea' falla en silencio. El skill debe marcar cualquier sentencia que tenga que correr fuera del bloque de transacción, pero no puede saber cómo se comporta tu runner si eso no está en su configuración. Dile cómo se ejecutan tus migraciones y te avisará; déjalo a ciegas y va a generar SQL correcto que tu runner termina rechazando.
¿Prefieres que lo hagamos por ti?
Esto mismo lo construimos para negocios como el tuyo. La primera conversación es gratis y sin compromiso.
Escríbenos por WhatsAppPrimera conversación gratis. Te responde el fundador.
Recursos relacionados

El skill que escribe políticas RLS: políticas de Postgres que niegan por defecto y se prueban con casos de permitir y denegar
Un skill de Claude Code que convierte 'esta tabla guarda datos por usuario' en políticas de Row-Level Security que niegan por defecto, se escriben en la misma migración que activa RLS y solo se entregan con tests de permitir y denegar que prueban que de verdad funcionan.

MCP de Supabase para migraciones seguras por rama
Dejar que un modelo escriba tu migración de esquema no tiene nada de malo; dejar que la aplique directo a producción es la forma perfecta de arruinarte un sábado. El servidor MCP de Supabase le da a Claude una rama de base de datos donde trabajar (diseña, aplica, revisa los advisors y después haces merge) para que una respuesta tan equivocada como segura de sí misma le caiga a una copia desechable y no a tus tablas en producción.

Arma un índice RAG en Supabase con pgvector
RAG es búsqueda por vecino más cercano sobre texto que convertiste en embeddings, más un modelo que lee los resultados. Esta guía monta todo sobre Postgres pelado (schema, chunking, un índice HNSW, una función de búsqueda detrás de RLS y la llamada de retrieval a Claude) y te dice sin rodeos dónde pgvector se queda corto.