Skip to content
Proyecto propio · Full-stack

Fantomio

Un amigo secreto donde ni quien organiza puede ver quién le regala a quién. El sorteo corre dentro de la base de datos y cada cuenta lee solo su propia asignación.

Row Level SecurityPostgresSupabaseCloudflare WorkersSorteo a ciegasPruebas en CI
El proyecto

Fantomio, antes GhostSwap, organiza el amigo secreto de una familia, una oficina o un grupo de amigos. Se arma el grupo con un link, cada persona anota su lista de deseos y el sorteo se hace en Postgres, con reglas de acceso por fila que dejan a cada cuenta leer solo a quién le regala y la lista de esa persona. Tiene mensajes anónimos con tu amigo secreto, un modo a ciegas donde ni el chat delata nombres, ediciones para repetir el grupo al año siguiente sin repetir parejas, y una cuenta completa con foto, cambio de correo, Google, unión de cuentas, descarga de datos y borrado. Es gratis y no rastrea a nadie.

Por qué existe

Las apps de amigo secreto que había pedían cuentas en sitios dudosos y casi siempre dejaban que quien organiza viera todo. Quise una que funcionara bien y donde el secreto no fuera una promesa de la pantalla.

Cómo lo construí

Moví toda la lógica sensible a la base. El sorteo es una función de Postgres que respeta exclusiones, evita repetir las parejas del año anterior y avisa cuando no hay sorteo posible. Las políticas RLS hacen que ni el organizador lea asignaciones ajenas, y una lista de deseos solo la ven su dueña y quien le regala. Para el modo a ciegas, la base tapa los nombres en cada mensaje antes de guardarlo, distinguiendo a una Rosa del color rosa. Después le sumé pruebas automáticas contra un Supabase desechable, registro de migraciones y alertas, para dejar de probar en producción.

Stack y decisiones técnicas

Next.js 16 exportado como sitio estático en Cloudflare Workers, sin servidor propio. Supabase con Postgres, Auth y RLS en todas las tablas. El sorteo, los archivos, las revelaciones programadas y los correos corren en la base con funciones, pg_cron y pg_net hacia Brevo. Cada deploy espera a que GitHub Actions levante un Supabase desechable, aplique las migraciones y pase las pruebas de privacidad. Errores reportados a Sentry sin datos personales.

Reflexión

La mayoría de estas apps tiene un problema de confianza que nadie nombra. Si quien organiza puede ver todo, la privacidad es solo una promesa, y convertirla en una garantía técnica cambió la arquitectura entera.