GEORGEBOT • Leyendo el código para contarte cómo está hecho
README_MD0%
Documentación del proyecto

Read Mecómo está hecho

Este sitio es un export estático de Next.js alimentado por seis APIs externas. Toda la data se refresca en cada build, con fallback a caché en JSON.

Descripción

El portafolio digital de Jorge Marquez Lander

Este es el portafolio digital de Jorge Marquez Lander: un solo sitio que reúne, con el mismo lenguaje visual, las dos carreras que definen su vida — la ingeniería civil y la actuación — en lugar de dos portafolios separados.

La idea nació de una constatación práctica: el trabajo de un ingeniero se mide en kilómetros de fibra, subestaciones y presupuesto; el de un actor, en personajes, escena y sets. Nada de eso encajaba en un portafolio convencional.

Aquí conviven ambas trayectorias sin renunciar a ninguna, y el sitio aprovecha para mostrar además lo que no cabe en un currículum: los viajes, los libros, la música, el cine y las redes.

Todo está construido sobre datos reales que se refrescan solos. No es una maqueta ni un demo: es el portafolio en producción, con su propia agenda de videollamadas, su asistente de IA y su formulario de contacto.

Ingeniero Civil

28+ años de trayectoria en infraestructura crítica, telecomunicaciones y gestión de proyectos en Latinoamérica: redes de fibra óptica y HFC, infraestructura energética y obra civil. Doce competencias técnicas que van desde la gerencia de proyectos y los sistemas eléctricos hasta el desarrollo web.

Experiencias
15
Formación académica
20
Competencias técnicas
12

Actor

Trayectoria en cine, teatro, televisión, comerciales y casting: cortometrajes, videoclips, workshops y campañas. Miembro de la Academia de Ciencias y Artes Cinematográficas de Venezuela.

Experiencias
68
Formación artística
25
Videos en videoteca
150
Estadísticas

El proyecto en números

23
Páginas estáticas
83
Componentes React
45
Componentes ui/
10
Scripts de datos
21
Rewrites en Firebase
6
APIs integradas
9
Servicios
5
Artículos de blog
512
Libros catalogados
150
Videos en videoteca
15 / 68
Experiencias (ing. / act.)
20 / 25
Formación (ing. / act.)
668 / 68
Trakt (historial / watchlist)
435
Scrobbles Last.fm
1.585
Posts de Instagram
457
Posts matcheados
83
Experiencias en Instagram
70
Posts de viaje en el atlas
Despliegue

Cómo se publica

El flujo

Un script de PowerShell encadena los cuatro syncs, el timestamp, el build estático y la subida a Firebase Hosting. Una variante estricta valida typecheck y lint antes de sincronizar.

El hosting

Plan
Firebase Spark
Raíz
public/out
URLs
cleanUrls + 21 rewrites
Producción
https://jorgemarquezlander.web.app

Ver el código

El repositorio es público. La documentación completa, con comandos y variables de entorno, vive en el README de GitHub.

GitHub
Interacciones

Las cuatro capas que hacen que el sitio responda

Además del contenido editorial, el sitio tiene cuatro integraciones que corren enteras en el navegador: un asistente de IA, la agenda de videollamadas, el canal de mensajes y el traductor. Ninguna pasa por un servidor propio.

GEORGEBOT

Asistente de IA personal, siempre accesible desde el botón flotante. Responde en primera persona, con mi voz, y conoce la trayectoria, los artículos, los viajes y el ADN musical del sitio.

  • →Arma su contexto en el cliente: perfil, historial y ratings de Trakt, watchlist y los tops de Last.fm.
  • →Consulta por streaming al proveedor configurado, con reintento entre modelos y respuesta sin streaming si la cuota choca.
  • →Enriquece lo que responde: embebe los videos de YouTube que menciona, convierte un enlace de agenda en botón y construye rutas internas del sitio.
Proveedor

Gemini por defecto, o cualquier endpoint compatible con OpenAI (BlueMinds, OpenRouter) cambiando una variable.

Calendly

La agenda real de 30 minutos, embebida en un modal con la estética del sitio. Aparece en el pie, en el botón flotante, en la página de contacto y dentro del propio chat.

  • →Loader con progreso que espera el evento postMessage real de Calendly, con red de seguridad a 10 segundos.
  • →CSS inyectado para forzar el fondo oscuro y evitar el destello blanco; en móvil el modal pasa a pantalla completa.
  • →El idioma de la agenda sigue al idioma activo del traductor, con 10 locales mapeados.
Enlacecalendly.com/jorgemarquezlander/30min

Telegram

El formulario de contacto entrega el mensaje directamente a la Bot API de Telegram. No hay buzón ni servidor de por medio: el envío se hace desde el navegador. Aparece en la página de contacto y en el panel flotante.

  • →Campos de nombre, email, teléfono opcional y mensaje, validados con zod.
  • →Multimedia: grabar audio, grabar video con cambio de cámara frontal/trasera, o adjuntar archivos. Cada adjunto viaja como mensaje aparte, numerado.
  • →Se incluye la IP del visitante para poder identificar el mensaje, y la interfaz lo dice de forma explícita.

Traductor

Todo el sitio es traducible a nueve idiomas desde el botón del globo en la cabecera. No es una traducido por ruta: se inyecta en el cliente y traduce la página completa en el sitio.

  • →Selector propio con español, inglés, francés, italiano, portugués, alemán, chino, árabe y japonés.
  • →La preferencia se guarda en cookie de Google Translate y sobrevive a la navegación; volver a español la limpia y recarga.
  • →Se ocultan los spinners y el banner del traductor, y se bloquea el desplazamiento que Google inyecta en el body.
Nota

El idioma es puramente cosmético: no cambia las rutas ni el contenido, que sigue siendo el del sitio original en español.

El contexto del bot

El build genera además un archivo de contexto agregado con las cifras del sitio (posts, experiencias, títulos vistos, rutas). Conviene saber que hoy ese archivo no lo consume el chat: GEORGEBOT arma su contexto en el navegador a partir de los JSON individuales. El archivo se conserva como respaldo y como resumen para otras automatizaciones.

Sistema de categorización

Cómo se clasifican 1.585 posts

El Hub Social clasifica cada post en cuatro capas, por orden de prioridad. Es first-match-wins: gana la primera capa que coincide.

  1. 1

    Travel Atlas

    Posts de viaje curados a mano por país. No se auto-clasifican: el clasificador de captions confundía «nyc» con un @handle y «francia» con una plaza de Caracas.

  2. 2

    Matching a experiencias

    instagram-matches.json cruza captions, @handles, hashtags, postIds y dateRange contra 83 experiencias.

  3. 3

    Keywords de caption

    Reglas por palabras sobre el texto del caption, en el client.

  4. 4

    postIdOverrides

    Asignación manual por ID de post. Tiene máxima prioridad sobre todo lo demás.

Orden de resolución

El orden importa más de lo que parece: Running y Viajes van segundo y tercero, muy al principio, no al final.

OverridesEventosRunningViajesIngenieríaComercialesTalleresCortometrajeVideoclipsTelevisiónCastingPersonalBienestarOtros

13 categorías resultantes

ViajesComercialesCortometrajeTalleresTeatroVideoclipsCineBienestarTelevisiónEventosRunningCastingPersonal

Resultado verificado: 457 posts matcheados a 83 experiencias y 1.128 sin match, que caen por keywords al resto de categorías.

Stack

Stack tecnológico

CapaTecnologíaVersiónUso en el proyecto
FrameworkNext.js (App Router)15.2.8Render estático + metadata por ruta
UIReact18.3.1Componentes cliente (*-client-page.tsx)
LenguajeTypeScript5.xstrict, tsc --noEmit
EstilosTailwind CSS3.4.145 componentes ui/ estilo shadcn/ui
PrimitivasRadix UIvariosDialog, Sheet, Tabs, Accordion, Tooltip
CarruselesEmbla Carousel8.1.3Videos, libros, posts, servicios
Temanext-themes0.3.0Modo oscuro forzado
i18nnext-intl4.8.2messages/es.json, locale único 'es'
Analítica@next/third-parties16.1.6Google Analytics
Validaciónzod3.24.2Esquemas de datos y formularios
GráficosRecharts · three2.15 · 0.185Visualizaciones y escena 3D
Audiowav1.0.2Reproductor de la Audioteca
ScrapingPuppeteer25.4.0Solo scripts de sync (Trakt)
HostingFirebase HostingSparkSirve public/out con cleanUrls

@next/third-parties y eslint-config-next van por delante del next fijado en 15.2.8. El build funciona, pero conviene alinearlas en una pasada de mantenimiento.

Arquitectura

Cómo está estructurado

Patrón de páginas

app/<seccion>/page.tsx
  # servidor: metadata, canonical, JSON-LD
app/<seccion>/<seccion>-client-page.tsx
  # cliente: UI, hooks, interacciones

Las rutas dinámicas usan generateStaticParams para que output: 'export' emita un HTML por slug. Resultado: 23 páginas estáticas, sin servidor en producción.

Doble carpeta public/

jorgemarquezlander/public/   # proyecto Next.js
└── public/                  # assets que Next sirve

El doble public/ es intencional: es la ruta estática que Next.js sirve. Los JSON de caché se copian también a public/public/data/ para poder hacer fetch estático desde el cliente.

Datos: estático + live

  • →Los hooks cliente (use-trakt-data, use-music-data, use-blog-data, use-books-data) consultan las APIs externas en vivo y caen al JSON cacheado cuando la API falla o no hay red.
  • →El build refresca los JSON, de modo que el sitio nunca queda vacío aunque las APIs cambien o fallen.
Mapa de rutas

Qué hay y dónde

/

Hero con video, sobre mí, servicios, blog, feed social, atlas

/ingenieria

Trayectoria de ingeniería: tabs, modales, certificados

/actuacion

Trayectoria actoral, ficha técnica, galería, lightbox

/servicios

9 servicios profesionales y su detalle

/social

Hub Social: grilla de 1.585 posts categorizados, lightbox, stats

/bitacora

Ecosistema: bento de libros, Trakt, IG, música, mapa, atlas

/videoteca

150 videos de YouTube en 9 categorías + reproductor

/cinemateca

Historial y watchlist de Trakt con pósters

/audioteca

Historial de Last.fm con filtros y reproducción

/biblioteca

512 libros con estantes, búsqueda y modal

/blog

Artículos con HTML rico, share y metadatos

/atlas

Atlas de viajes: mapa, carruseles por país, grilla por tag

/contacto

Datos de contacto y formulario

/readme

Esta documentación del proyecto

Pipeline de datos

Seis APIs, un solo build

Trakt.tv + TMDB

Historial y watchlist con Puppeteer, metadatos en español de TMDB

Generatrakt_history.json, trakt_watchlist.json

YouTube Data v3

Videos del canal con thumbnails, categorización por keywords

Generavideoteca-data.ts, profile-data-es.ts

Instagram Graph API

Pipeline fetch → diff → match → merge → imágenes

Generainstagram-*.json, travel-atlas.json

Last.fm

Historial, recent, top tracks/artists + enriquecimiento

Generalastfm_*.json (4 archivos)

Google Books

Portadas, descripciones en español e ISBN

Generabooks-data.ts

Google Analytics

Analítica del sitio vía @next/third-parties

Genera—