Crea tu propio YNAB con IA para gestionar tus finanzas
Una aplicación de presupuesto parece la hoja de cálculo más aburrida del mundo. Tienes dinero, lo repartes en categorías, apuntas lo que gastas.
Tres frases. ¿Qué puede salir mal?
Pues resulta que dentro de esas tres frases viven la aritmética de céntimos, un invariante contable que no puede romperse jamás, un saldo que rueda de un mes al siguiente con reglas distintas para el efectivo y el crédito, una conciliación contra la realidad del banco y una tarjeta de crédito que hace descarrilar a casi todas las réplicas caseras.
Por eso un YNAB propio es el proyecto perfecto para el fin de semana. No porque sea fácil, sino porque parece fácil y no lo es, y esa distancia es justo donde se aprende.
Este post no repite el método. La receta general —cómo eliges qué reconstruir, el prompt cero, los criterios de aceptación, los prompts de rescate— la tienes en cómo crear tu propio X con IA. Y si vienes de crear tu propio Calendly con IA o de crear tu propia status page con IA, reconocerás la estructura. Aquí vamos a lo concreto de un presupuesto:
- Un prompt único para arrancar ahora mismo, si no quieres leer más
- Qué entra y qué no entra en un YNAB propio que se termina
- Las seis piezas donde se juega el partido, con el prompt de cada una
- El agujero de correctitud que tu agente no va a detectar solo
- Qué hacer con las transacciones programadas, el trozo que todo el mundo olvida
- Dónde mirar cuando te atasques, con Actual como referencia viva
- Cómo generar el checklist que te dice si esto está de verdad terminado
Vamos al lío.
El prompt único, si quieres empezar ahora mismo ¶
Hay gente que ha llegado hasta aquí con el portátil abierto y el agente esperando. Para ti va esto.
Copia este prompt, pégalo y dale al enter.
Vas a construir "Sobre", una alternativa pequeña a propósito, a
YNAB, para una sola persona que quiere repartir su dinero con el
método de los sobres (presupuesto de base cero). Quiero una
aplicación completa que funcione de verdad, no una maqueta ni una
colección de componentes sueltos.
Usa el stack que veas en el repositorio; si está vacío, propón uno
habitual y pregúntame antes de instalar nada exótico.
ANTES DE ESCRIBIR CÓDIGO
Devuélveme un plan corto con las rutas, los endpoints, las tablas y
las decisiones que estés tomando. Espera a que yo lo apruebe.
MODELO DE DATOS
Account (tipo activo o pasivo, saldo), CategoryGroup y Category,
BudgetMonth (categoría, mes, importe asignado), Transaction (cuenta,
fecha, importe en céntimos enteros, categoría, beneficiario, estado
sin confirmar / confirmada / conciliada) y las líneas de una división
cuando una transacción se reparte entre varias categorías. Nada más.
LAS TRES COSAS QUE NO PUEDES HACER MAL
1. El dinero se guarda siempre como entero de céntimos, jamás como
decimal flotante. Toda división debe cuadrar con el total del
padre al céntimo, sin perder ni ganar nada al redondear.
2. El "por asignar" es dinero en cuentas de efectivo menos dinero ya
asignado a categorías. No es ingresos menos gastos. Cuando gastas,
ese número no cambia: baja el disponible de la categoría, no el que
tienes por repartir.
3. El disponible de una categoría es un total acumulado mes a mes:
arrastre anterior más asignado menos gastado. El saldo positivo
pasa entero al mes siguiente; el sobregasto en efectivo se resta
del "por asignar" del mes que viene y la categoría arranca en cero.
PANTALLAS
Presupuesto del mes (grupos, categorías con asignado, gastado y
disponible, y el número "por asignar" bien visible arriba), registro
de una cuenta con sus transacciones y estados, editor de transacción
con soporte para división, y vista general de cuentas con sus saldos.
Cada pantalla declara su acción principal, su estado de carga, su
estado vacío y su error recuperable.
FUERA DE ALCANCE
Multidivisa, sincronización bancaria automática, informes avanzados,
objetivos complejos, varios usuarios y apps móviles nativas. Si crees
que hace falta algo de esto, pregúntame en vez de construirlo.
TESTS
Unitarios del motor de presupuesto con estos casos: una categoría con
saldo positivo que arrastra al mes siguiente, un mes con sobregasto en
efectivo, un gasto con tarjeta que mueve dinero a la categoría de pago
de esa tarjeta, y una división que debe sumar al céntimo. Y un test
del invariante: la suma de los disponibles de todas las categorías más
el "por asignar" es igual, en todo momento, al dinero real que hay en
las cuentas de efectivo.
ENTREGA
Migraciones, datos de ejemplo, .env.example comentado y un README que
me permita levantar esto desde cero dentro de seis meses.
Cuando termines, dime qué has dejado a medias y qué decisiones tomaste
sin preguntarme.
Con eso tienes una primera versión que se abre en el navegador y ya reparte dinero en categorías.
Ahora la parte honesta: eso es una primera versión, no un producto.
No importa transacciones del banco, no las concilia, no entiende de transferencias entre cuentas y trata a una tarjeta de crédito como si fuera una cuenta corriente cualquiera. El prompt cubre tres de las seis piezas difíciles. Las otras tres son las que más tiempo te van a comer.
Así que vuelve por aquí cuando lo tengas ejecutándose. El resto del post es justo eso.
El nivel de vibe coding al que apunta este post ¶
Conviene situar esto antes de empezar, porque hay tres formas de construir esta aplicación y solo una encaja aquí.
La primera es el vibe coding básico: le pides “hazme un YNAB”, aceptas lo que salga y lo despliegas. Funciona para enseñárselo a un amigo. No funciona para llevar tu propio dinero durante un año. Si estás en ese punto y quieres el método de tres tiempos para salir de él, empieza por cómo programar con IA tu primer proyecto.
La tercera es la metodología completa: especificación, artefactos versionados, criterios de aceptación formales. Es lo que te conviene en un proyecto que va a durar, y lo tienes desarrollado en la guía de Spec Driven Development. Para un proyecto de fin de semana es matar moscas a cañonazos.
Este post vive en la segunda: vibe coding con criterio. Sigues conversando con el agente, sigues sin escribir specs formales, pero sabes de antemano cuáles son las seis piezas donde el modelo se va a equivocar y llegas a ellas con el prompt preparado. Si quieres el marco de cuánta garantía pedir según lo que te juegas, lo desarrollo en cómo hacer bien vibe coding.
🔑 La diferencia entre el vibe coding que funciona y el que no funciona rara vez está en el prompt. Está en saber de antemano dónde se va a equivocar el modelo, y llegar a ese punto con la pregunta correcta preparada.
Sobre la herramienta, da bastante igual: cualquier agente de terminal con acceso a ficheros te sirve. Claude Code, Codex, OpenCode o el que prefieras. Si todavía no has elegido, tienes la comparativa de agentes de IA en terminal. Los prompts que vienen funcionan igual en todos.
El tercer nivel, para el día que el presupuesto deje de ser un juguete
Recorre el ciclo completo de Spec Driven Development con OpenSpec en modo asistido sobre un proyecto pequeño. Lo ves funcionar entero antes de decidir si el tuyo necesita esa marcha.
Abrir el curso gratis →Qué entra y qué no entra en tu YNAB ¶
El alcance es la decisión más importante de todo el proyecto, y se toma antes del primer prompt.
Un YNAB propio que se termina cubre esto:
- Cuentas de efectivo y de tarjeta, con su saldo y su registro de movimientos.
- Categorías agrupadas, con lo asignado, lo gastado y lo disponible en cada una.
- El reparto de base cero: cada euro que entra se asigna a una categoría hasta que el “por asignar” queda en cero.
- Transacciones con beneficiario, categoría, estado, divisiones entre categorías y transferencias entre cuentas.
- El arrastre mensual del saldo de cada categoría, con sus reglas de sobregasto.
Y deja fuera esto, a propósito:
- Multidivisa
- Sincronización bancaria automática con el banco real
- Informes de tendencias y edad del dinero
- Objetivos y metas por categoría con fechas
- Varios usuarios sobre el mismo presupuesto
Esa lista de exclusiones no es pereza. Es la parte del producto que convierte un fin de semana en un trimestre. Escríbela en tu fichero de contexto antes de empezar y el agente dejará de proponerte cosas que no vas a construir.
Las seis piezas donde se juega el partido ¶
Aquí está el mapa. Cada una de estas piezas tiene una trampa concreta, y ninguna se resuelve sola por muy bien que escribas el prompt inicial.
| Pieza | Por qué es difícil | Cómo sabes que está bien |
|---|---|---|
| El “por asignar” | No es ingresos menos gastos, es caja menos reparto | El número nunca miente sobre lo que puedes repartir |
| El dinero en céntimos | Los decimales flotantes pierden céntimos | Una división de tres partes suma al total exacto |
| El arrastre mensual | El sobregasto en efectivo y en crédito no ruedan igual | El saldo positivo pasa, el rojo en efectivo se cobra aparte |
| Divisiones y transferencias | Son contabilidad de doble entrada disfrazada | Borrar un lado de una transferencia borra el otro |
| La conciliación | Tu número y el del banco divergen en silencio | Reimportar el mismo extracto no duplica nada |
| La tarjeta de crédito | Es una cuenta de pasivo, no de efectivo | Gastar a crédito reserva el dinero para pagarla |
Las tres primeras son de lógica pura. Las tres siguientes son de contabilidad y de integración. Y las de contabilidad son las que más tiempo te van a comer, aunque parezcan las accesorias.
Un mapa de trampas como el de esta tabla se construye mirando proyectos ajenos. Cada domingo reunimos 12 recursos sobre programar con IA y lo que va aprendiendo la comunidad de +6.700 developers.
Suscríbete gratis →Pieza 1: cada euro tiene un trabajo (y el número que lo vigila) ¶
Esta es la idea que sostiene todo YNAB, y también el error de cálculo más común cuando la reconstruyes.
El número que corona la pantalla —el “por asignar”, que YNAB llama ready to assign— no es ingresos menos gastos. Es el dinero que tienes en tus cuentas de efectivo menos el dinero que ya has repartido en categorías. Cuando gastas, ese número no se inmuta: lo que baja es el disponible de la categoría, porque ese euro ya tenía un trabajo asignado.
Implementa el cálculo del "por asignar" y del disponible de cada
categoría como un módulo de dominio puro, sin acceso a base de datos y
sin consultar el reloj por dentro: el mes que se está mirando entra
como parámetro.
El "por asignar" es el dinero en cuentas de efectivo menos la suma de
todo lo asignado a categorías. No lo calcules como ingresos menos
gastos bajo ningún concepto.
Está terminado cuando se cumple este invariante después de cualquier
operación (asignar, gastar, mover dinero entre categorías): la suma
de los disponibles de todas las categorías más el "por asignar" es
igual al dinero real que hay en las cuentas de efectivo. Escribe un
test que lo compruebe tras una secuencia larga de operaciones.
Ese invariante es tu red de seguridad. En un presupuesto sin tarjetas se cumple siempre: lo que tienes por repartir más lo que ya has repartido es igual al dinero que hay en tus cuentas. Es la identidad contable del sistema, el equivalente a que en una balanza los dos platos pesen lo mismo.
Si en algún momento deja de cuadrar, no tienes un presupuesto: tienes una hoja de cálculo que miente. Y las tarjetas de crédito son justo lo que complica esa identidad, por eso tienen su propia pieza más abajo.
Pieza 2: el dinero es aritmética de céntimos, no de decimales ¶
Prueba esto en la consola de tu navegador: 0.1 + 0.2. Te devuelve 0.30000000000000004.
Ahí está tu presupuesto sangrando por dentro.
Los números decimales del ordenador no representan el dinero con exactitud, y esos errores diminutos se acumulan hasta que un día tu “por asignar” marca un céntimo de más que sale de la nada. La solución la conoce cualquiera que haya tocado software de finanzas: el dinero se guarda como entero de céntimos. Diez euros con cincuenta son 1050, no 10.5.
// Dinero siempre en céntimos enteros: nada de decimales flotantes
type Cents = number; // entero: 1050 son 10,50 €
// Reparte un importe entre N partes sin perder ni ganar un céntimo.
// Las primeras partes se quedan el céntimo sobrante del redondeo.
function splitEvenly(total: Cents, parts: number): Cents[] {
const base = Math.floor(total / parts); // parte entera para todos
const remainder = total - base * parts; // céntimos que sobran
return Array.from({ length: parts }, (_, i) =>
i < remainder ? base + 1 : base
);
}
// splitEvenly(1000, 3) -> [334, 333, 333], suma exacta 1000
Ese detalle del reparto parece una tontería hasta que divides una cena de 10 € entre tres y tu aplicación te dice que has gastado 9,99 € o 10,01 €. En un presupuesto, un céntimo que no cuadra es una grieta que te hace desconfiar de todo lo demás.
⚠️ Guarda cada importe como entero de céntimos y haz todas las operaciones con enteros. Convierte a decimal solo al pintar en pantalla, nunca antes. Es la diferencia entre unas cuentas que cuadran al céntimo y un bug silencioso que descubres tres meses tarde.
Dale esta regla al agente por escrito y de paso pídele que la meta en el fichero de contexto del proyecto. Si no, tarde o temprano te colará un float para “simplificar” y volverás a sangrar céntimos.
Pieza 3: el saldo de una categoría rueda al mes siguiente ¶
Aquí está lo que separa a YNAB de una hoja de gastos normal. El disponible de una categoría no se reinicia cada mes: rueda.
Si en enero apartas 100 € para “Regalos” y solo gastas 60 €, en febrero esa categoría empieza con 40 € ya dentro. El saldo positivo se arrastra entero. Hasta aquí, fácil.
La trampa está en el sobregasto, y en que el efectivo y el crédito no se comportan igual.
// El disponible de una categoría es un total acumulado mes a mes.
interface MonthActivity {
assigned: Cents; // asignado este mes
spent: Cents; // gastado este mes (número negativo)
}
function available(carryover: Cents, month: MonthActivity): Cents {
// arrastre anterior + lo asignado + lo gastado (que ya es negativo)
return carryover + month.assigned + month.spent;
}
// Al cerrar el mes, el sobregasto en efectivo NO se arrastra en rojo:
// la categoría vuelve a cero y ese hueco se descuenta del "por asignar".
function nextCarryover(current: Cents): Cents {
return current < 0 ? 0 : current; // el saldo positivo sí pasa entero
}
¿Qué pasa cuando gastas más de lo que tenías en una categoría pagando con dinero de una cuenta de efectivo? El disponible se pone en rojo ese mes. Pero al llegar el mes siguiente, ese número rojo no se arrastra: la categoría vuelve a cero y el importe sobregastado se resta del “por asignar” del mes nuevo. Traducción práctica: te pasaste con la comida, así que tienes menos dinero fresco para repartir en el mes que empieza. El sistema te obliga a mirar de frente lo que hiciste.
El sobregasto a crédito es otra historia, y por eso lo dejo para la pieza de las tarjetas. Ahí un gasto de más no reduce tu dinero para repartir: aumenta lo que debes.
Añade tests del arrastre mensual al motor de presupuesto. Todos deben
fallar antes de que toques la implementación.
Casos obligatorios:
- Una categoría con saldo positivo que pasa entero al mes siguiente.
- Una categoría con sobregasto en efectivo: al cambiar de mes vuelve a
cero y el importe sobregastado se descuenta del "por asignar" nuevo.
- Mover dinero de una categoría a otra dentro del mismo mes sin tocar
el "por asignar".
- Editar la asignación de un mes pasado y comprobar que todos los
meses posteriores recalculan su arrastre.
Dime cuáles fallan y por qué antes de arreglar nada.
Ese último caso —editar el pasado— es la semilla del agujero del que hablo más abajo. Guárdalo en la cabeza.
Que los tests fallen primero no es un capricho. Un agente que escribe implementación y tests en el mismo turno tiende a escribir tests que pasan con la implementación que acaba de escribir, aunque las dos estén mal.
Pieza 4: divisiones y transferencias son contabilidad de doble entrada disfrazada ¶
Dos gestos que parecen triviales esconden la parte más contable de la aplicación.
Una división es una transacción repartida entre varias categorías: 80 € en el súper, de los cuales 60 € son comida y 20 € productos de limpieza. La regla de oro la heredas de la pieza 2: las líneas de la división tienen que sumar al total, al céntimo. Si no cuadran, la transacción no se guarda.
Una transferencia es más peligrosa, porque es un solo hecho económico con dos caras. Mueves 200 € de la cuenta corriente al ahorro: eso son dos apuntes que tienen que vivir y morir juntos.
- Si borras uno, se borran los dos.
- Si cambias el importe en un lado, cambia en el otro.
- Una transferencia entre dos cuentas de efectivo no lleva categoría: el dinero no sale de tu presupuesto, solo cambia de cuenta.
Implementa divisiones y transferencias con estas reglas explícitas:
DIVISIONES
- Una transacción dividida tiene varias líneas, cada una con su
categoría y su importe en céntimos.
- La suma de las líneas es igual al total de la transacción, siempre.
Rechaza guardar si no cuadra, no lo ajustes por tu cuenta.
TRANSFERENCIAS
- Una transferencia entre dos cuentas es un único hecho con dos
apuntes enlazados. Crear, editar o borrar uno afecta al otro dentro
de la misma transacción de base de datos.
- Una transferencia entre cuentas de efectivo no lleva categoría ni
toca el "por asignar": el dinero sigue dentro del presupuesto.
- Una transferencia hacia una tarjeta de crédito es un pago, y ese
caso lo trataremos aparte.
Propóneme antes cómo vas a enlazar los dos apuntes de una
transferencia, con sus contras.
Ese “propóneme antes cómo vas a enlazar los dos apuntes” es un patrón que uso mucho: pedir alternativas antes que soluciones. Probablemente te ofrezca un par de apuntes que se referencian entre sí por un identificador de transferencia compartido, o un único registro con dos cuentas. Elige tú. Esa elección es tu trabajo, no el suyo.
El fallo típico del código generado sin estas reglas es tratar la transferencia como dos transacciones independientes. Funciona el primer día. Al mes, editas una y la otra se queda como estaba, y tus dos cuentas dejan de cuadrar sin que sepas por qué.
Pieza 5: lo que tú dices y lo que dice el banco ¶
Hasta ahora todo el dinero lo has metido tú a mano. En el mundo real vas a importar movimientos de un fichero del banco, y ahí empieza la parte de integración.
El fichero llega en formatos con solera: CSV cuando hay suerte, y si no, QIF u OFX, dos formatos con décadas encima. El QIF es de los más traicioneros: no dice en qué orden vienen el día y el mes, ni con qué codificación está escrito. Un extracto español importado como si fuera estadounidense te coloca los gastos del 3 de abril el 4 de marzo.
Pero el problema gordo no es el formato. Es que importar dos veces el mismo extracto no puede duplicar tus movimientos, y un movimiento que ya apuntaste a mano tiene que reconocerse cuando llega del banco, no clonarse.
Implementa la importación de movimientos desde CSV con estas
garantías:
- Importación idempotente: reimportar el mismo fichero no crea
duplicados. Cada movimiento importado lleva un identificador estable
derivado de sus datos, y uno que ya existe se ignora.
- Emparejamiento: un movimiento importado que coincide en fecha e
importe con uno que ya apunté a mano se ofrece como pareja para
confirmar, no se añade como nuevo.
- Estados de una transacción: sin confirmar, confirmada y conciliada.
Solo yo marco una cuenta como conciliada contra el saldo real del
banco en una fecha.
- Al conciliar, si mi saldo y el del banco no coinciden, dímelo con la
diferencia exacta y ofréceme crear un ajuste, nunca lo cuadres a
escondidas.
Está terminado cuando importar el mismo fichero tres veces deja la
cuenta igual que importarlo una vez.
Ese último criterio vuelve a ser la idempotencia, la misma idea que persigue medio post. La conciliación es la que te salva de la peor sensación de todas: descubrir en marzo que tu aplicación y tu banco llevan divergiendo desde enero y ya no sabes cuál de los dos tiene razón.
Cuando el dinero es de verdad
La vez que una integración mal entendida duplicó suscripciones en producción
Te llevas el flujo real de una webapp construida entera con agentes y el error que pagué en Stripe cuando la IA entendió mal lo que le pedía: cobros duplicados, en producción, con dinero de clientes.
Ver el caso real →Audio premium · Web Reactiva Premium
Pieza 6: la tarjeta de crédito es un tipo de cuenta traicionero ¶
Si hay una pieza donde las réplicas caseras de YNAB se rompen, es esta. Y no por casualidad: la tarjeta de crédito es lo que más confunde incluso a la gente que usa YNAB de verdad.
Una tarjeta de crédito no es una cuenta de efectivo. Es una cuenta de pasivo: su saldo representa lo que debes, no lo que tienes. Cuando gastas 50 € en el súper pagando con la tarjeta, no sale dinero de tu bolsillo todavía, pero contraes una deuda de 50 €.
Aquí viene la parte elegante de YNAB, la que tienes que reproducir. Cuando gastas esos 50 € desde una categoría que tenía dinero asignado —“Comida”, pongamos— el sistema mueve 50 € de “Comida” a una categoría especial de pago de esa tarjeta. Ese dinero ya lo tienes en tu cuenta de efectivo, y ahora queda reservado para pagar la tarjeta cuando llegue el recibo. Así, el día que pagues, está esperando.
- La cuenta de la tarjeta baja a −50 €: debes 50 €.
- La categoría “Comida” baja 50 €: ese euro ya tenía trabajo.
- La categoría de pago de la tarjeta sube 50 €: ahí está el dinero reservado.
- Cuando pagas el recibo, es una transferencia de la cuenta de efectivo a la tarjeta que reduce esa categoría de pago.
Esa categoría de pago es el puente que mantiene la contabilidad honesta. La deuda de la tarjeta queda espejada por dinero reservado en efectivo, así que siempre tienes con qué pagar lo que cargaste. Es lo que hace que el invariante de la pieza 1 siga cuadrando aunque metas tarjetas por medio.
Implementa la tarjeta de crédito como cuenta de pasivo, no de
efectivo, con este comportamiento:
- Al gastar desde una categoría con dinero disponible usando la
tarjeta, mueve ese importe desde la categoría de gasto a la
categoría de pago de esa tarjeta concreta.
- El saldo de la tarjeta refleja la deuda (número negativo). La
categoría de pago refleja el dinero reservado para pagarla.
- Pagar la tarjeta es una transferencia desde una cuenta de efectivo
hacia la tarjeta, que reduce la categoría de pago.
- Excluye las cuentas de tarjeta de la suma de "efectivo" del
invariante del "por asignar": son pasivo, no caja.
- El sobregasto a crédito (gastar desde una categoría sin dinero
suficiente) aumenta la deuda; no lo trates como el sobregasto en
efectivo. Explícame en un comentario cómo lo distingues.
Y dime qué pasa cuando arranco una tarjeta que ya tiene deuda previa:
esa deuda no es dinero presupuestable.
Queda el caso de empezar con una tarjeta que ya arrastra deuda. La deuda vieja no es dinero que puedas repartir, y meterla como si lo fuera te descuadra el “por asignar” desde el minuto uno.
Las trampas contables como la de la tarjeta se descubren tarde y salen caras. En la newsletter de los domingos contamos lo que vamos aprendiendo con la IA en proyectos reales, y los +6.700 que la recibimos aportamos lo nuestro. Gratis, desde 2018.
Suscríbete gratis →El agujero que no verás hasta dentro de tres meses ¶
Esta es la pieza que más me gusta de todo el proyecto.
En un presupuesto, el pasado no es de solo lectura.
El disponible de cada categoría y el “por asignar” de cada mes son totales acumulados: dependen de todo lo que pasó antes. El saldo de “Regalos” en julio es la suma de lo que asignaste y gastaste en enero, febrero, marzo y todos los meses intermedios. Es una cadena.
Ahora imagina que en julio corriges una transacción de abril: pusiste 40 € donde eran 60 €. Ese cambio no afecta solo a abril. Tiene que recalcular el arrastre de mayo, de junio y de julio, uno detrás de otro.
Si tu aplicación calculó esos saldos una vez y los guardó en caché sin recalcularlos hacia delante, acabas de corromper en silencio cinco meses de cuentas. Y no te vas a enterar, porque la pantalla del mes actual sigue enseñando un número con toda la seguridad del mundo.
Revisa cómo se recalcula el presupuesto cuando cambia algo del pasado:
1. Si edito o borro una transacción de un mes anterior, ¿se recalculan
el arrastre y el disponible de TODOS los meses posteriores?
2. Si cambio lo asignado en un mes pasado, ¿se propaga el efecto hasta
el mes actual?
3. ¿Hay algún saldo cacheado que pueda quedar desincronizado con los
datos reales tras una edición del pasado?
4. ¿Puedo comprobar el invariante del "por asignar" en un mes cualquiera
del pasado, no solo en el actual?
Propón cómo garantizar que cualquier número mostrado es coherente con
todo el historial. No implementes nada todavía, solo el diagnóstico.
Y ese prompt merece una sesión nueva, con el contexto limpio. Un agente que acaba de escribir el motor de presupuesto lleva encima todas las razones por las que le pareció buena idea cachear ese saldo. No es un revisor: es el autor defendiendo su obra.
La solución razonable para un proyecto propio suele ser no cachear casi nada y recalcular desde el arrastre cada vez que se pinta un mes, o guardar solo saldos que se invaliden en cadena a partir del mes editado. Lo caro es descubrir que necesitabas esto cuando ya llevas medio año de datos encima.
El trozo que todo el mundo olvida: las transacciones programadas ¶
Tienes la aplicación funcionando. Llevas dos semanas apuntando movimientos a mano. Y un día se te olvida meter el recibo del alquiler y tu presupuesto te miente durante una semana.
Las transacciones programadas son la parte menos glamurosa de un presupuesto y una de las que más valor aporta en el día a día. El alquiler, la nómina, las suscripciones: cosas que se repiten y que no deberías teclear cada mes. También son la primera vez en el proyecto que necesitas trabajo en segundo plano, así que conviene tratarlas con cariño.
Añade transacciones programadas y recurrentes.
Requisitos:
- Una plantilla define cuenta, categoría, importe y una regla de
repetición (cada mes el día 1, cada viernes, etc.).
- Un trabajo programado revisa qué transacciones tocan y las materializa
como movimientos reales, en estado sin confirmar.
- Marca de materialización por plantilla y fecha, para que ejecutar el
trabajo dos veces no cree dos veces el mismo movimiento.
- Editar o borrar una plantilla no toca los movimientos ya
materializados del pasado.
Está terminado cuando ejecutar el trabajo tres veces seguidas crea
los mismos movimientos que ejecutarlo una vez.
💡 “Ejecutar el trabajo tres veces seguidas crea los mismos movimientos que ejecutarlo una vez.” Esa frase es la definición práctica de idempotencia, y vale para cualquier trabajo en segundo plano que escribas en tu vida: importaciones, recordatorios, recálculos. Guárdatela.
Cuando esto funcione, el paso natural son los objetivos: decirle a una categoría “necesito 1.200 € para el seguro en diciembre” y que ella te diga cuánto apartar cada mes. Es lo que convierte el presupuesto en algo que mira hacia delante en vez de solo registrar lo que ya pasó. Pero eso ya es otra tanda de decisiones; déjalo para cuando lo básico esté sólido.
Dónde mirar cuando te atasques (y por qué Actual es tu mejor referencia) ¶
Cuando quieras ver cómo resuelve todo esto alguien que lleva años haciéndolo, tienes una referencia excelente y con las puertas abiertas: Actual Budget, la alternativa de código abierto a YNAB.
No es un proyecto cualquiera. Nació como producto comercial de James Long y se liberó como open source en 2022. Hoy ronda las 27.200 estrellas y 2.600 forks en GitHub, con licencia MIT y escrito casi por completo en TypeScript, según su propio repositorio consultado en agosto de 2026. Va por la versión 26.6.0, publicada en junio de 2026.
Lo que a ti te importa: el motor de presupuesto que estás construyendo es justo lo que Actual tiene público y con licencia permisiva. Reparto de base cero, arrastre mensual, tarjetas de crédito, conciliación. Todo el partido que se juega en las seis piezas, resuelto por gente que se ha comido las trampas antes que tú.
Actual tiene además una decisión de arquitectura que merece la pena mirar aunque no la copies: es local-first. Los datos viven en tu dispositivo y la sincronización entre aparatos usa un mecanismo de fusión de cambios que no depende de un servidor central mandando. El núcleo, que ellos llaman loot-core, está separado de la interfaz para poder ejecutarse en cualquier plataforma. Ese corte entre el motor y la pantalla es justo el que te recomiendo para tu propia versión.
🛡️ Mirar el código de un proyecto maduro cuando te atascas no es hacer trampa. Es lo contrario de copiar el prompt gigante: tú ya has intentado resolver la pieza, tienes el problema en la cabeza y por eso entiendes por qué ellos lo resolvieron así. El código ajeno enseña cuando llegas a él con una pregunta, no cuando lo lees para evitarte pensar.
Si decides levantarlo en local para curiosear, tienes varias vías: una imagen de Docker, apps de escritorio descargables para Windows, Mac y Linux, o despliegues de bajo coste. La documentación de la comunidad cubre la instalación y el modelo de presupuesto de sobres con bastante detalle. Úsalo como referencia de comportamiento: fíjate en cómo pinta el “por asignar”, cómo trata una categoría en rojo y qué hace al gastar con una tarjeta.
Cómo se genera el checklist de “esto está terminado” ¶
Has llegado hasta aquí siguiendo el post. Tienes seis piezas construidas y, repartidos entre ellas, seis criterios de “está terminado cuando…”. El problema es que están sueltos, en seis conversaciones distintas que ya has cerrado.
Toca juntarlos en un solo sitio. Y hay una forma buena de hacerlo y una mala.
La mala es pedirle al agente “dime si el proyecto está terminado”. Te va a decir que sí. Siempre dice que sí.
Los tres tipos de comprobación ¶
Antes de generar nada, el reparto. Cualquier checklist útil de este proyecto tiene tres cajones, y confundirlos es lo que hace que la gente acabe con listas de treinta puntos que nadie repasa.
Lo que se comprueba solo. Los tests. El motor de presupuesto, el arrastre, las divisiones que suman al céntimo, la importación idempotente, el invariante del “por asignar”. Se ejecutan con un comando y devuelven verde o rojo. Aquí no hay opinión.
Lo que se comprueba a mano en diez minutos. Importar un extracto de ejemplo dos veces y ver que no se duplica, gastar con una tarjeta y comprobar que el dinero se reserva en su categoría de pago, editar una transacción del mes pasado y mirar que el mes actual reacciona. Cosas que automatizar cuesta más de lo que valen en un proyecto personal.
Lo que solo se contesta con criterio. ¿El sobregasto en efectivo se descuenta del mes siguiente como tú decidiste? ¿La deuda previa de una tarjeta se trata como querías? Aquí el agente no puede ayudarte, porque son decisiones de producto y las tomaste tú.
El prompt que lo genera ¶
Con ese reparto claro, el prompt tiene sentido. Fíjate en que no le pido una lista: le pido un fichero verificable.
Recorre el repositorio y genera un fichero VERIFY.md con el checklist
de verificación de este proyecto antes de darlo por terminado.
Reglas para construirlo:
- Cada punto describe CÓMO se comprueba, no solo qué se comprueba.
"El arrastre funciona" no vale. "Ejecutar el test X y ver que pasa"
sí vale.
- Agrupa los puntos en tres secciones: automático (un comando),
manual (menos de diez minutos) y decisión de producto (una pregunta
que solo puedo responder yo).
- Los puntos automáticos citan el fichero y el nombre del test que ya
existe. Si un criterio no tiene test que lo respalde, NO te lo
inventes: márcalo como hueco y ponlo en una lista aparte al final.
- Los puntos manuales incluyen el dato de prueba concreto: qué fichero
importar, qué cuenta usar, qué importe gastar.
- Las decisiones de producto van formuladas como pregunta cerrada, con
el valor implementado ahora mismo entre paréntesis.
Al final, una sección de huecos: criterios que aparecen en el código o
en los comentarios pero que nadie está comprobando.
No arregles nada. Solo el fichero.
Las dos líneas que hacen todo el trabajo son la del “cómo se comprueba” y la de “si no hay test, márcalo como hueco”. Sin la primera, te devuelve una lista de deseos. Sin la segunda, te inventa tests que no existen y los da por pasados.
Lo que debería devolverte ¶
Si el proyecto está donde debe, el fichero se parece a esto.
En el cajón automático: el test del invariante del “por asignar” tras una secuencia larga de operaciones, los tests de arrastre con el mes sobregastado, la división que suma al céntimo y la importación que no duplica al repetirse.
En el manual: gastar con tarjeta y ver el dinero moverse a la categoría de pago, importar el mismo extracto dos veces, editar una transacción de un mes anterior y comprobar que el mes actual recalcula.
Y en el de decisiones: si el sobregasto en efectivo se descuenta del mes siguiente (ahora mismo, sí), cómo se trata la deuda previa de una tarjeta, y si las cuentas de tarjeta se excluyen del cálculo del efectivo.
Ese tercer cajón es el que da valor al ejercicio, porque son cosas que decidiste hace tres días y ya no recuerdas.
La regla que impide que el checklist mienta ¶
Un checklist se corrompe siempre por el mismo sitio: alguien marca una casilla sin comprobarla.
Con un agente de por medio pasa a los dos minutos. Le pides que repase el fichero y te devuelve todo marcado, porque marcar es lo más parecido a completar la tarea que le has pedido.
La regla es sencilla: cada punto se cierra con una evidencia pegada al lado. La salida del comando, el nombre del extracto que importaste, la fecha en que lo probaste. Sin evidencia, la casilla sigue vacía aunque el agente jure que funciona.
Repasa VERIFY.md y ejecuta solo los puntos de la sección automática.
Para cada uno, pega debajo la salida real del comando: la de verdad,
no un resumen tuyo.
Los puntos manuales y las decisiones de producto los dejas sin tocar:
esos los cierro yo.
Si un punto falla, no lo arregles. Anótalo y sigue con el siguiente.
Ese “no lo arregles, anótalo y sigue” evita el problema clásico: el agente se atasca arreglando el primer fallo, se le va el contexto y nunca llegas a saber si los otros diez puntos pasaban.
Las tres señales de que puedes cerrar el portátil ¶
Con el fichero cerrado, quedan tres preguntas que ningún checklist responde.
La primera: tú lo usas. Llevas dos semanas metiendo tu dinero de verdad, cuadras con el banco y no has vuelto a abrir la hoja de cálculo vieja.
La segunda: la sección de huecos está vacía. No quedan criterios sueltos que aparezcan en el código y que nadie esté comprobando.
La tercera, y es la que más cuesta: la siguiente funcionalidad que se te ocurre está en la lista de exclusiones. Cuando te sorprendas pensando “sería fácil añadir los objetivos con fecha”, ese es el momento de cerrar el portátil.
Guarda el VERIFY.md en el repositorio y repásalo antes de cada despliegue. Es lo único de todo el proyecto que te va a seguir sirviendo dentro de seis meses, cuando vuelvas a tocarlo y no recuerdes ni por dónde empezaba.
Si en algún momento crece más allá de eso —porque le has cogido gusto o porque quieres que lo use tu pareja— ahí sí toca cambiar de marcha y meter una metodología con especificación de por medio. Pero esa es otra conversación, y ese día ya no estarás haciendo vibe coding.
Preguntas frecuentes ¶
¿Cuánto se tarda en montar un YNAB propio con IA?
Una versión mínima con cuentas, categorías, reparto de base cero y arrastre mensual cabe en unas seis horas de trabajo real. Añadir la importación de movimientos, las transferencias bien resueltas y las tarjetas de crédito se va a un par de días. Igualar el producto completo son meses, y es justo la parte que conviene no construir.
¿Cuál es la parte más difícil de construir un YNAB?
Las tarjetas de crédito combinadas con el arrastre mensual. Una tarjeta es una cuenta de pasivo que mueve dinero a una categoría de pago cada vez que gastas, y ese mecanismo tiene que encajar con el arrastre de saldos y con el invariante del dinero disponible sin descuadrar nada.
¿Por qué hay que guardar el dinero en céntimos y no en decimales?
Porque los números decimales del ordenador no representan importes con exactitud y acumulan errores diminutos. Guardar cada importe como entero de céntimos y convertir a decimal solo al mostrarlo evita que tu presupuesto sangre céntimos que salen de la nada.
¿Qué es el “por asignar” o ready to assign en YNAB?
Es el dinero que tienes en tus cuentas de efectivo y que aún no has repartido en categorías. Se calcula como caja menos lo asignado, no como ingresos menos gastos. Cuando gastas, ese número no cambia: baja el disponible de la categoría, porque ese euro ya tenía un trabajo.
¿Cómo se comporta el sobregasto en una categoría?
Depende de cómo pagues. Si sobregastas con dinero de una cuenta de efectivo, la categoría queda en rojo ese mes, vuelve a cero al mes siguiente y el importe de más se descuenta de tu dinero por asignar. Si sobregastas a crédito, en cambio, aumenta la deuda de la tarjeta.
¿Cómo se modela una tarjeta de crédito en un presupuesto de sobres?
Como una cuenta de pasivo cuyo saldo es la deuda. Al gastar con ella desde una categoría con dinero, ese importe se mueve a una categoría de pago de la tarjeta, donde queda reservado el efectivo para pagar el recibo. Pagar la tarjeta es una transferencia que reduce esa categoría de pago.
¿Cómo evito duplicar movimientos al importar del banco?
Con una importación idempotente: cada movimiento importado lleva un identificador estable derivado de sus datos, y uno que ya existe se ignora al reimportar. Además, un movimiento que coincide con uno apuntado a mano se ofrece para emparejar en vez de añadirse como nuevo.
¿Qué pasa si edito una transacción de un mes pasado?
Que todos los meses posteriores tienen que recalcular su arrastre, porque el saldo de cada categoría es un total acumulado. Si la aplicación guardó saldos en caché sin recalcularlos hacia delante, esa edición corrompe en silencio las cuentas de los meses siguientes.
¿Merece la pena si ya existe Actual Budget?
Depende del objetivo. Si necesitas una herramienta para llevar tu dinero de verdad, instala Actual, que es libre y está muy pulido. Si lo que quieres es aprender, reconstruir un producto cuyo comportamiento ya conoces te convierte en el mejor tester posible de tu propio código.
¿Hace falta escribir specs formales para este proyecto?
Para un proyecto de fin de semana que reconstruyes para aprender, no. Basta con conocer de antemano las piezas difíciles y llegar a ellas con el prompt preparado. La metodología formal empieza a compensar cuando el proyecto va a durar o lo va a tocar más gente.
Fuentes ¶
- Actual Budget, repositorio oficial en GitHub. Licencia MIT, stack, versión, estrellas y estructura del proyecto.
- Actual Budget, documentación de la comunidad. Instalación, modelo de presupuesto de sobres y guías de uso.
- Wikipedia, “YNAB (You Need a Budget)”. Origen, historia y las cuatro reglas del método.
- MDN, “Number.prototype.toFixed y aritmética de punto flotante”. Por qué los decimales flotantes no representan el dinero con exactitud.
🧨 Última oprtunidad para recibir la dinamita que mereces sobre programación con IA el próximo domingo: Suscríbete gratis a Web Reactiva en https://webreactiva.com/newsletter
12 recursos para developers cada domingo en tu bandeja de entrada
Además de una skill práctica bien explicada, trucos para mejorar tu futuro profesional y una pizquita de humor útil para el resto de la semana. Gratis.