Aquí abajo están mis cuatro apps contadas por dentro: qué había antes, qué decidí, qué descarté y qué se me rompió por el camino. No es el resumen bonito — es lo que hay detrás de cada una.
Todo sale de los documentos de decisión que voy dejando en cada proyecto y de su propio historial, así que puedo sostenerlo con fechas. Y va con la jerga puesta: es el único sitio de esta web donde no la traduzco, porque quien llega hasta aquí la está buscando.
Contexto
Una app para la compra, las recetas y saber en qué se te va el dinero del súper. Pensada para llevarla en una mano mientras empujas el carro con la otra.
Guardas el ticket al salir y la app aprende de él. Con el tiempo te dice dónde te conviene comprar, qué llevas en la lista y cuánto te va a costar.
De dónde salgo
Una app de listas y recetas la hace cualquiera. Lo que la hacía distinta era que aprendiera de lo que ya compras, y para eso necesitaba leer tickets.
Ahí estaba el problema: leer un ticket pide inteligencia artificial, y poner la mía significaba pagar por cada uso y quedarme con las fotos de la compra de la gente en un servidor mío. Dos cosas que no quería.
Qué decidí
La inteligencia artificial la pones tú, no la app. Nevera te prepara el texto, tú se lo llevas a la que uses —ChatGPT, Claude, la que sea— y pegas la respuesta de vuelta. Con eso desaparecen las tres cosas que me preocupaban: no pago por cada ticket, tus fotos no pasan por ningún servidor mío y la factura no crece cuando crece la app.
Lo que compras se guarda en filas, no en un bloque de texto. Las recetas guardan sus ingredientes de la otra forma y lo natural era repetirlo, pero aquí hice lo contrario: todo lo que quería hacer después —lo que más compras, cuánto gastas al mes, qué tienda te sale mejor— son cuentas, y las cuentas la base de datos las hace sola sobre filas.
El criterio no fue que una forma sea mejor: lo que se suma va en filas, lo que solo se lee entero puede ir junto. Las fotos del ticket, que nunca se suman, siguen guardadas del otro modo. Y los precios en céntimos enteros, nunca con decimales, para que las sumas cuadren al céntimo.
Qué se rompió
Una animación que nunca hizo lo que yo creía. La mancha del fondo de los iconos giraba con varias capas superpuestas. Fui a hacerla más orgánica y me encontré dos cosas que desde fuera no se veían.
La primera: todas las capas compartían un mismo sitio donde apuntar hacia dónde iban, y cada vez que una terminaba lo sorteaba de nuevo entero. O sea que cada capa que acababa les cambiaba el destino a las demás en pleno vuelo. Se sostenía sola, pero de milagro. La segunda: cada vuelta obligaba a repintar la cabecera, y esa cabecera está en casi todas las pantallas. Para siempre.
La reescribí con otra herramienta que dibuja sin molestar al resto de la app. Pero lo que más me costó no fue programarla: hice las tres versiones posibles, las puse a girar juntas en la misma pantalla para compararlas de verdad, y borré las dos que perdieron. Una de ellas no gastaba nada, y aun así la descarté: esa mancha moviéndose es parte del carácter de la app.
En qué quedó
De una app de listas salió un histórico de compras con gasto por meses, precios de cada producto y qué tienda te sale mejor. Sin pagar un céntimo por la parte de inteligencia artificial y sin guardar una sola foto de nadie.
Está en la App Store y en Google Play, y es la que mejor cubierta tengo con pruebas automáticas.
Cómo sigue
Fue creciendo por capas sobre lo mismo: el modo de una sola mano en el súper, traerte recetas desde un texto, una web o un vídeo, una copia de seguridad completa con las fotos dentro, un buscador que aguanta erratas y acentos, notas dictadas con la voz y un diario de novedades que se lee dentro de la app.
Contexto
Nació en mi casa. Estaba cansado de decirles que no a mis dos hijos adolescentes, así que convertí los noes en un juego: en lugar de «no», «casi casi».
Cada uno tiene un objetivo y va sumando hasta cien puntos. Yo sumo o resto, siempre con un motivo, y queda apuntado.
De dónde salgo
La empecé en julio de 2024 y la tuve parada más de un año. Cuando la retomé funcionaba, pero no era para enseñársela a nadie.
Y me apareció un problema nuevo: quería poder mandarles un reto por WhatsApp, y eso pedía un servidor. En una app que a propósito no tiene cuentas ni guarda nada fuera del móvil.
Qué decidí
Solo un sitio puede escribir en la base de datos. El tope de cien puntos, el máximo de cinco hijos, lo que se borra en cadena: todas esas reglas se cumplen ahí dentro, nunca en la pantalla. De ahí salió una decisión que parece un atajo: como solo hay un escritor, el que borra en cadena es él, y no le pedí a la base de datos que lo vigilara.
Lo que la hace defendible no es la decisión, es que dejé escrito cuándo deja de valer: el día que aparezca otra cosa que escriba —un widget, una sincronización, lo que sea— esto se cae y hay que hacerlo bien.
El aviso diario tuve que darle la vuelta. Solo debe sonar los días que nadie ha puntuado, pero un aviso programado no puede mirar nada cuando salta: si está puesto, suena. Así que programo treinta de golpe, uno por día, y los vuelvo a programar enteros cada vez que abres la app o puntúas.
Los retos no guardan quién eres. Cuando mandas uno, se crea una entrada que se borra sola pasado un tiempo. No hay usuarios ni cuentas: la propia dirección del enlace es la llave. Tu hijo lo abre en el navegador sin instalar nada ni registrarse en ningún sitio.
Qué se rompió
Una palabra que casi me cuesta la publicación. En español la app les llama «esclavo 😄» a los hijos, que es la broma de casa. Al traducirla no la pasé literal: en inglés esa palabra no hace gracia, quema, y me la habrían tumbado en la revisión.
No guardar quién eres tiene su precio. Si reinstalas la app, los retos no vuelven, y los enlaces se mueren solos al caducar. Lo acepté por coherencia: la app ya pierde todo lo demás si la reinstalas.
Y la tanda de avisos tiene un techo que algún día me morderá: iOS solo aguanta 64 notificaciones pendientes por app. Con treinta voy sobrado hoy, pero el día que programe otra cosa a la vez habrá que repartir ese presupuesto.
En qué quedó
Está en la App Store, rehecha entera: un anillo que enseña el progreso, la gráfica de cómo va evolucionando y un mando de puntos que vibra al pasar por cada tope.
Aunque en esta el resultado que me importa no sale en ninguna tienda, sino en si en mi casa sirvió para lo que la hice.
Cómo sigue
Seis decisiones documentadas en un mes. Luego llegaron los retos que se comparten por enlace y avisan al móvil cuando el crío los da por hechos, los ajustes de avisos en su propio sitio y la traducción entera al inglés, cuidando que la broma siguiera teniendo gracia en los dos idiomas.
Contexto
Una app para llevar la cuenta de lo que quieres ver. Guardas películas y series en tus listas y te enteras de lo que se estrena. Los datos de cine vienen de fuera; tus listas no salen del móvil.
De dónde salgo
El servidor de QVO no era suyo. Vivía en mi web, compartido con otras cuatro apps, así que no podía tocarlo sin pensar en las demás: la app iba al ritmo del repositorio más lento.
Encima arrastraba tres versiones de la API conviviendo a la vez, con comprobaciones tan flojas que ya no comprobaban nada, y dos direcciones distintas para pedir lo mismo.
Y había un problema de fondo con los datos: la fuente rápida y gratis no tiene todas las películas. Le faltan las raras, las antiguas y las que no son americanas. Yo las quería todas.
Qué decidí
Me llevé el servidor dentro de la app. Ahora los dos comparten el mismo código y los mismos tipos, sin nada en medio que mantener sincronizado. A cambio, el día que las otras apps se muden tendrán que repetir parte del trabajo. Lo acepté: prefiero eso a que una app espere por otra.
Los datos van a dos velocidades. Cuando abres una ficha, la app pregunta a la fuente rápida y guarda la respuesta. Por detrás, sin que nadie espere, un proceso nocturno va a buscar lo que esa fuente no tiene y rellena los huecos. Por separado no valía ninguna: la rápida no lo tiene todo, y la completa tarda demasiado para ponerla delante de alguien que está mirando la pantalla.
Cambié la API entera de golpe, sin mantener la vieja. La app estaba en pruebas y romper salía barato. Ir migrando poco a poco me costaba escribir tanto código de transición como rehacerlo limpio.
Dejé el login para más adelante. Lo que se pide al servidor son datos públicos de cine; lo tuyo está en tu móvil. Lo que había antes te identificaba solo por el correo, sin comprobar nada, así que preferí quitarlo a mudarlo roto.
Qué se rompió
Las listas contaban películas que no estaban. El contador subía y el hueco se quedaba vacío. Pasaba porque nada impedía guardar una película en una lista que no había llegado a crearse.
Lo interesante no fue arreglarlo, sino lo que decidí no arreglar. La revisión daba por hecho que había que atar también las fichas de las películas, y eso lo descarté: esa tabla no son datos tuyos, es una copia que la app puede volver a bajar cuando quiera. Tus listas tienen que sobrevivir aunque la copia se borre. Lo dejé escrito en el propio código para que nadie venga luego a «completar» lo que falta.
Y cambiar todo de golpe me dejó sin red: si algo salía mal, no tenía un interruptor para volver atrás. O publicaba otra versión y esperaba a que Apple la revisara, o parcheaba en caliente si el fallo estaba en la parte que se puede parchear.
En qué quedó
Publicada en iPhone y en Android. La apuesta de las dos velocidades salió bien: están todas las películas y la app no se hace de rogar, porque lo lento pasa cuando nadie está mirando.
Y el servidor dentro de la app hizo lo que buscaba: publico cuando quiero, sin esperar a que ninguna otra cosa esté lista.
Cómo sigue
Compartir una película fue un buen ejemplo de decidir por descarte. Lo evidente era hacer una captura bonita en el móvil y mandarla. La deseché por cuatro razones que se suman: una imagen no se puede tocar, ni copiar, ni te lleva a la app; WhatsApp la recomprime y destroza la tipografía fina; mandar imagen y texto a la vez se comporta distinto en cada sitio; y el día que quisiera lo mismo en la web tendría que dibujarlo dos veces.
Así que mando un enlace y la tarjeta la dibuja mi servidor. Lo que decidió el diseño no fue verlo en grande, sino verlo pequeño: en un chat esa vista previa se pinta a un dedo de ancha, y ahí solo sobreviven el cartel, el título y el año. Hasta mi firma perdió el nombre y se quedó en el logo.
Contexto
Una app de frases célebres en español. Se abre y aparece una cita tecleándose en pantalla, como si alguien la estuviera escribiendo. Funciona sin internet, sin cuenta y sin pagar.
De dónde salgo
De apps de frases hay cientos, casi todas una lista con publicidad. Por ahí no había forma de destacar.
Lo único que podía diferenciarla eran dos cosas: la calidad de las frases y lo bien que se buscaran. Ninguna de las dos se arregla con diseño. Eso me obligaba a reunir yo el archivo de citas y a que todo funcionara desde el primer segundo.
Qué decidí
Todas las frases van dentro de la app: 3.183 citas de 1.318 autores, unas 46.000 palabras. Se cargan la primera vez que la abres y ya no dependes de nada más.
El buscador me lo hice yo. No compara letras: pesa más las palabras raras que las comunes, y suma lo que sabe del autor y del tema. Vive aparte del resto de la app, sin nada de la pantalla ni de la base de datos dentro, que es lo que me permite probarlo de verdad.
Cada ventana tiene su propia dirección. Quité las hojas que suben desde abajo y convertí el menú, el buscador y las favoritas en pantallas con nombre propio. Así el móvil sabe volver atrás solo y yo dejé de mantener dos formas de navegar.
Qué se rompió
Apple me la rechazó por «no tener suficiente contenido». A una app con 3.183 frases dentro.
Lo primero fue tragarme el enfado y mirarlo bien. El motivo era falso, pero apuntaba a algo verdadero: toda la interfaz está escondida hasta que tocas la pantalla, y quien la revisó no debió pasar de ahí. No es que no hubiera contenido: es que no encontró por dónde entrar.
Decidí no tocar la app y responder. Mandé dos cosas: las cifras exactas de lo que hay dentro y un itinerario numerado, paso a paso, hasta cada función. La aprobaron al día siguiente, a la primera, sin grabar ningún vídeo y sin compilar una versión nueva.
Me llevé una lección que no va de trámites: una interfaz que se esconde por elegancia también se esconde para quien decide si te publica.
En qué quedó
Publicada en la App Store el 1 de agosto de 2026. El escrito que mandé lo guardé como receta, por si vuelve a pasar: es la respuesta que menos me costó y la que mejor salió.
Y hace lo que prometía: la abres en un avión, sin cuenta y sin pagar, y están las 3.183.
Cómo sigue
Después llegaron una nube de autores y temas que se toca para saltar a una cita, la frase del día que salta sin pasar por ningún servidor, un diario de novedades con comentarios y una pantalla para revisar lo que propone la gente.
Esto no es una app, pero es donde vive el trabajo de servidor de las cuatro: sus páginas, sus diarios de novedades y todo lo que le piden a internet. Es también mi repositorio más viejo.
De dónde salgo
Empezó siendo solo mi portfolio. Cuando las apps necesitaron un servidor, lo puse aquí porque ya estaba montado y pagado. La comodidad se cobró después: acabó siendo el sitio donde se juntaban cuatro apps que no salen a la vez ni van al mismo ritmo.
Qué decidí
Las peticiones responden todas igual, con la misma forma, y lo que ya se ha preguntado se guarda una temporada: quince días si el dato no cambia, siete si cambia.
Quién soy se declara una sola vez, en la portada, y el resto de páginas apuntan a esa. Repetir mi ficha en cada una no es lo mismo: para quien lee esos datos serían dos personas distintas que se llaman igual.
Los cuatro diarios comparten motor y cada uno lleva su ropa. Y una decisión de la que me volví atrás: puse el menú de la web también en los diarios y lo acabé quitando. Cada blog tiene su propia cara y mi barra de navegación no pintaba nada ahí.
Qué se rompió
Un fallo que salía y se iba sin tocar nada: el mismo código publicaba bien una vez y fallaba a la siguiente, siempre después de reaprovechar el trabajo de la compilación anterior. Lo arreglé obligándolo a empezar de cero cada vez.
Y otro que te manda a buscar donde no es. Una página nueva fallaba al compilar, pero fallaba al final del todo. Entonces la plataforma cancela y deja publicada la versión anterior. ¿Qué ves tú? Que tu página nueva da error 404. Y te pones a mirar si los ficheros subieron, si la dirección está bien, si es cosa del caché. Todo menos lo que era.
La regla me la apunté con todas las letras: si una página nueva da 404 justo después de publicarla, mira primero el registro de la compilación y luego el código.
En qué quedó
Las pruebas automáticas vigilan cosas que no son código. Por ejemplo, que la lista de tareas del proyecto cuadre con las que existen de verdad, o que ninguna página se salga del correo de contacto bueno. Si cambio el correo en una página y me olvido de las otras cinco, salta ahí y no en la cara de quien me escribe.
Cómo sigue
De portfolio pasó a plataforma: los diarios de las cuatro apps, el buzón de retos de CasiCasi con sus avisos, la ficha de una película que se puede compartir con su tarjeta dibujada al vuelo, y mis currículums exportados a PDF sin depender de ninguna web de terceros.
Y algo que no es código pero sostiene todo lo demás: las decisiones escritas que ves contadas arriba. Es lo que me permite contarlas con fechas y motivos, en vez de con lo que me parece recordar.
¿Hablamos?
Versiones, commits y demás cifras, a . Las saco de los repositorios cuando me acuerdo, así que si ves una fecha vieja, la cifra es de esa fecha.