Saltar al contenido
Oswaldo Rodríguez

← Todos los proyectos

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).