👩🏻💻 Estefanía Turín
2024-08-15
📌 [ FastAPI | TypeScript | Gemini AI ]
"Un gestor de enlaces inteligente que transforma URLs en una base de conocimiento personal mediante IA, combinado con una estética retro y acogedora."
A continuación puedes ver un recorrido rápido por la interfaz retro, observando cómo la IA procesa, resume y añade etiquetas a las URLs guardadas en tiempo real:
💻 Backend (API)
Elegí FastAPI por su excelente rendimiento nativo asíncrono y la generación automática de documentación. Para la capa de persistencia, implementé SQLAlchemy Core, lo que me permitió escribir consultas seguras, eficientes y explícitas, previniendo vulnerabilidades de inyección SQL.
🎨 Frontend
El uso de TypeScript fue fundamental para asegurar la robustez de la aplicación mediante el mantenimiento estricto de los contratos de datos entre cliente y servidor. Integré TanStack Query para resolver la gestión del estado del servidor de forma profesional, abstrayendo mecanismos de cacheo y estados de carga de manera eficiente.
▹
Resúmenes Automáticos: Al guardar un enlace, el pipeline lee el contenido del sitio web objetivo y utiliza la IA para generar un resumen conciso.
▹
Sugerencias de Tags: El modelo analiza semánticamente el texto extraído y clasifica automáticamente el conocimiento dentro de categorías lógicas.
📌 Decisión clave de performance: Procesar las peticiones de extracción y análisis de Gemini como tareas en segundo plano (Background Tasks). Esto permite ofrecer una respuesta instantánea en la interfaz de usuario mientras la IA computa de forma asíncrona.
❌ Problema: Errores de CORS en Producción
Las peticiones HTTP del frontend (hosteado en Vercel) hacia la API del backend (en Google Cloud Platform) eran bloqueadas por las políticas del navegador.
🛠️ Solución:
Implementé una configuración de CORS robusta en FastAPI utilizando allow_origin_regex para validar y autorizar de forma segura las URLs dinámicas de despliegue generadas por Vercel.
❌ Problema: Conflicto en el Pool de Conexiones
Aparición del error DuplicatePreparedStatementError debido a una incompatibilidad en el manejo de consultas preparadas entre el pooler PgBouncer (en modo transacción) y los drivers asíncronos de Python.
🛠️ Solución:
Investigué la infraestructura de la base de datos y configuré explícitamente el driver de conexión con statement_cache_size=0, solucionando la colisión y estabilizando el entorno.