IA 31 may 2026 May 31, 2026 4 min de lectura 4 min read

Cómo monté un dashboard ejecutivo con IA en un fin de semana How I built an executive dashboard with AI in a weekend

Pasé de una página estática en GitHub Pages a un sitio propio con HTTPS, datos que se archivan solos cada noche y una gráfica semanal. Lo difícil no fue el código — fue dónde me tropecé. I went from a static page on GitHub Pages to my own site with HTTPS, data that archives itself every night, and a weekly chart. The hard part wasn't the code — it was where I tripped.

Tenía un dashboard ejecutivo —correos, llamadas, agenda del día— viviendo como una página estática en GitHub Pages. Cumplía. El problema no era el dashboard: era todo lo de alrededor. La URL era un subdominio impronunciable, los datos vivían en un repo público, y no había forma de ver la semana, solo el día de hoy.

Así que me di un fin de semana para arreglarlo. Este es el registro honesto. Esto hice, esto aprendí, esto falló — y falló en sitios tontos.

El punto de partida y la decisión

GitHub Pages es genial hasta que quieres tres cosas a la vez: dominio propio, control del servidor y datos privados. Las tres apuntaban al mismo sitio: un VPS. Tenía uno en Hostinger casi sin usar, así que el plan cabía en una línea: servir el dashboard desde mi propio servidor, con mi dominio y HTTPS.

No escribí casi nada de eso a mano. Le pasé el objetivo a un agente y fui revisando cada paso: instalar nginx, apuntar el dominio, sacar el certificado. Mi trabajo no fue teclear — fue decidir y verificar.

Lo que quedó montado

El stack final es deliberadamente aburrido, que es justo lo que quieres en algo que debe estar siempre arriba:

Pieza Antes Ahora
Hosting GitHub Pages VPS propio (nginx)
URL subdominio largo mi dominio + HTTPS
Certificado Let’s Encrypt, renovación automática
Datos solo “hoy” “hoy” + acumulado semanal

nginx sirviendo archivos estáticos, Let’s Encrypt para el SSL con renovación sola, y redirección de HTTP a HTTPS. Nada exótico.

La parte que me gusta: datos que se archivan solos

El dashboard seguía leyendo su resumen.json del día. Lo que le faltaba era memoria. Así que añadí un pequeño proceso nocturno: cada noche baja el resumen del día, lo guarda con la fecha, y un script en Python agrega la semana en curso (lunes a domingo, en hora de México) en un solo archivo que el dashboard lee para pintar una gráfica.

El cron parece trivial. No lo fue:

# Instalar el cron sin que se borre solo.
# Con `set -e`, un grep sin coincidencias devuelve 1 y ABORTA el script,
# dejando el crontab vacío. La red de seguridad: un tmpfile y `|| true`.
tmp=$(mktemp)
crontab -l 2>/dev/null > "$tmp" || true
grep -q 'snapshot.sh' "$tmp" || \
  echo '50 5 * * * /var/www/midominio/snapshot.sh' >> "$tmp"
crontab "$tmp"
rm -f "$tmp"bash

Dónde me tropecé (tres veces)

Ninguno de los tres errores fue de IA ni de arquitectura. Fueron detalles de sistema, de esos que no salen en ningún tutorial.

  1. Un salto de línea casi me deja fuera del servidor. Al añadir mi llave SSH al authorized_keys, la llave que ya tenía Hostinger no terminaba en \n. Mi llave se pegó a la suya en la misma línea y sshd las ignoró las dos. Diez minutos de “¿por qué no entro?” por un carácter invisible.
  2. Windows metió \r por todas partes. Edité los scripts en mi PC; al subirlos, los finales de línea de Windows (CRLF) rompían el shell del servidor. Un sed para normalizar a LF y listo — pero hasta encontrarlo, errores incomprensibles.
  3. El crontab que se borraba solo. El de arriba. set -e + un grep sin coincidencia = script abortado a media instalación.

Ninguno de los tres fallos fue “la IA se equivocó”. Fueron fricciones de toda la vida: un newline, un CRLF, un código de salida. La IA acelera el camino feliz; los baches siguen siendo tuyos.

El rediseño

Con la infraestructura en pie, le di una capa de producto: tarjetas con KPIs, una paleta coherente y una gráfica semanal de verdad. La librería de la gráfica la alojé en el propio servidor en vez de tirar de un CDN — una dependencia externa menos que pueda caerse o cambiar bajo mis pies.

En una línea: la IA me ahorró el 80% del tecleo, pero el 100% de los errores que me costaron tiempo fueron detalles de sistema invisibles. Vale la pena ir revisando paso a paso, no aceptando a ciegas.

¿Lo volvería a hacer en un fin de semana? Sí. Pero ahora sé exactamente dónde mirar primero cuando algo no arranca: el newline, el CRLF y el código de salida.

I had an executive dashboard —emails, calls, the day’s agenda— living as a static page on GitHub Pages. It did the job. The problem wasn’t the dashboard: it was everything around it. The URL was an unpronounceable subdomain, the data lived in a public repo, and there was no way to see the week — only today.

So I gave myself a weekend to fix it. This is the honest log. What I built, what I learned, what broke — and it broke in silly places.

The starting point and the decision

GitHub Pages is great until you want three things at once: your own domain, control of the server, and private data. All three pointed to the same place: a VPS. I had one at Hostinger sitting almost unused, so the plan fit on one line: serve the dashboard from my own server, on my own domain, over HTTPS.

I barely wrote any of it by hand. I handed the goal to an agent and reviewed every step: install nginx, point the domain, issue the certificate. My job wasn’t typing — it was deciding and verifying.

What ended up running

The final stack is deliberately boring, which is exactly what you want in something that has to stay up:

Piece Before Now
Hosting GitHub Pages My own VPS (nginx)
URL long subdomain my domain + HTTPS
Certificate Let’s Encrypt, auto-renew
Data only “today” “today” + weekly rollup

nginx serving static files, Let’s Encrypt for SSL with automatic renewal, and an HTTP-to-HTTPS redirect. Nothing exotic.

The part I like: data that archives itself

The dashboard still read its resumen.json for the day. What it lacked was memory. So I added a small nightly process: every night it pulls the day’s summary, stores it under its date, and a Python script aggregates the current week (Monday to Sunday, in Mexico time) into a single file the dashboard reads to draw a chart.

The cron looks trivial. It wasn’t:

# Install the cron without it wiping itself.
# With `set -e`, a grep with no match returns 1 and ABORTS the script,
# leaving the crontab empty. The safety net: a tmpfile and `|| true`.
tmp=$(mktemp)
crontab -l 2>/dev/null > "$tmp" || true
grep -q 'snapshot.sh' "$tmp" || \
  echo '50 5 * * * /var/www/mydomain/snapshot.sh' >> "$tmp"
crontab "$tmp"
rm -f "$tmp"bash

Where I tripped (three times)

None of the three mistakes were about AI or architecture. They were systems details — the kind that show up in no tutorial.

  1. A line break nearly locked me out of the server. When adding my SSH key to authorized_keys, the key Hostinger already had didn’t end in \n. Mine got glued onto its line and sshd ignored both. Ten minutes of “why won’t it let me in?” over an invisible character.
  2. Windows put \r everywhere. I edited the scripts on my PC; on upload, Windows line endings (CRLF) broke the server’s shell. One sed to normalize to LF and done — but until I found it, baffling errors.
  3. The crontab that erased itself. The one above. set -e + a grep with no match = a script aborted mid-install.

None of the three failures was “the AI got it wrong.” They were plain old friction: a newline, a CRLF, an exit code. AI speeds up the happy path; the potholes are still yours.

The redesign

With the infrastructure standing, I gave it a product layer: KPI cards, a coherent palette, and a real weekly chart. I self-hosted the chart library on the server rather than pulling from a CDN — one fewer external dependency that can go down or shift under my feet.

In one line: AI saved me 80% of the typing, but 100% of the errors that cost me time were invisible systems details. It pays to review step by step, not accept blindly.

Would I do it again in a weekend? Yes. But now I know exactly where to look first when something won’t start: the newline, the CRLF, and the exit code.