2026Desarrollo completo — pipeline de datos, API y web
Bailoteca — Directorio de escuelas de baile
Un directorio de academias de baile en Santiago de Chile, alimentado por un pipeline de datos con aprobación humana.
- Python
- FastAPI
- Angular
- PostgreSQL
- Supabase
- Pydantic
- GitHub Actions
- Data Pipeline
Problema
Las academias de baile de Santiago están repartidas entre Google Maps, Instagram y el boca a boca. Quien busca «clases de salsa en Ñuñoa» recibe una mezcla de escuelas válidas, agregadores y entradas desactualizadas — no existe un lugar único y confiable.
Quería un directorio donde cada entrada publicada estuviera verificada, no adivinada por un scraper: dirección real, sitio real, estilos reales. Eso descarta de partida la publicación totalmente automática.
Enfoque
Publicación con aprobación humana
El pipeline termina en «proponer», nunca en «publicar». Una CLI pequeña (`bailoteca review` / `bailoteca approve <id>`) permite revisar cada propuesta y publicarla. Descarté la publicación totalmente automática: los datos scrape-ados son ruidosos, y una sola dirección equivocada erosiona más la confianza que una entrada faltante.
Las filas publicadas solo están expuestas al público mediante un rol Postgres de solo lectura con row-level security, por lo que la API no puede escribir por accidente.
Fuentes públicas, sin scraping de Instagram
El enriquecedor lee las partes públicas de la web: el sitio de la academia, datos estructurados JSON-LD, Google Maps y OpenStreetMap. Para presencia social lee únicamente la vista previa pública (Open Graph) — nunca inicia sesión ni recorre posts.
Descarté scrapear el feed de Instagram: rompe los Términos de Servicio, es frágil y las señales que aportaría no justifican el costo de mantenimiento.
Reglas primero, LLM como respaldo
La clasificación de estilos es un set determinista de reglas sobre palabras clave y datos estructurados; un LLM solo se usa para los casos que las reglas no resuelven. Esto mantiene el pipeline barato y auditable — cada decisión se puede explicar desde el input.
Descarté una llamada a LLM por candidato: multiplica el costo por corrida y hace imposible acotar las regresiones.
Un esquema, tres superficies
Un paquete compartido (`bailoteca-shared`: conexión, DTOs Pydantic, lecturas) es la única fuente de verdad consumida por el pipeline, la FastAPI de solo lectura y la SPA Angular. Si el esquema cambia, las tres partes fallan el chequeo de tipos juntas en vez de divergir.
FastAPI sirve los mismos DTOs que produce el pipeline; la app Angular consume la misma API que cualquier cliente externo.
Resultados
- En producción en bailoteca.vercel.app con el primer lote de academias reales (34 publicadas al momento de escribir) — el listado crece porque el pipeline propone y yo apruebo.
- Corre a $0/mes: solo tier gratuito de Supabase, GitHub Actions y fuentes de datos gratuitas.
- API de solo lectura en producción en bailoteca-api.vercel.app/docs (OpenAPI vía FastAPI).