whoami

Juan Rodríguez — Desarrollo full-stack

Cada proyecto aquí nació de un reto que no sabía resolver. La excusa para aprenderlo a fondo es construirlo: de la API al servidor. Uso la IA para acelerar mi investigación, pero el diseño, la arquitectura y el despliegue son míos de principio a fin.

cat habilidades.txt

frontend/
React TypeScript Astro Vite HTML/CSS Accesibilidad
backend/
Python FastAPI SQLAlchemy PostgreSQL Alembic REST
infra/
Docker Docker Compose Caddy nginx Linux Cloudflare
seguridad/
OAuth/JWT Argon2id CSRF CSP UFW / fail2ban

ls ./proyectos

Ver proyectos Escribirme

grep --tag

memories

2026

Aplicación privada de recuerdos compartidos, con galería de +500 fotos.

Una SPA privada donde se organizan fotos y momentos por secciones. No tiene registro público: las altas se hacen por CLI, una decisión deliberada para no exponer endpoints de escritura innecesarios. La galería está pensada para volumen: monta las fotos por lotes según baja el scroll y resuelve mezclas de verticales y horizontales sin recortar nada que importe.

  • Sesión solo en cookies HttpOnly, con CSRF de doble envío y rotación de refresh token: reusar uno revocado cierra todas las sesiones.
  • Contraseñas con Argon2id, rate limiting y respuesta idéntica ante email inexistente o contraseña incorrecta, para no permitir enumerar usuarios.
  • Galería incremental con IntersectionObserver, y un sistema de temas cuyo test reconstruye el fondo animado para verificar contraste WCAG AA.
  • Backend asíncrono de punta a punta con SQLAlchemy 2.0 y asyncpg, migraciones con Alembic.
  • Modelo de roles (admin/guest/love) guardado como VARCHAR + CHECK, no ENUM nativo de Postgres: añadir o quitar un rol es una migración normal, no un ALTER TYPE.
  • React
  • TypeScript
  • Vite
  • GSAP
  • FastAPI
  • PostgreSQL
  • Docker
  • S3

infra-rdgzlabs

2026

La plataforma self-hosted sobre la que corren estos proyectos.

Un solo VPS que aloja varias aplicaciones full-stack bajo un mismo dominio, con costo marginal cero por proyecto nuevo. El servidor se levanta desde cero con scripts idempotentes, así que el estado no depende de pasos manuales ni de memoria. Caddy enruta por subdominio sirviendo el certificado de origen de Cloudflare, y todo el origen queda detrás de su proxy para que nadie llegue saltándoselo.

  • Provisioning reproducible con Bash idempotente: SSH solo por clave, UFW, fail2ban y actualizaciones automáticas aplicadas desde el primer arranque.
  • Reverse proxy Caddy con TLS resuelto por el certificado de origen de Cloudflare (válido 15 años, modo Full strict) que enruta por subdominio, sobre un único PostgreSQL compartido con aislamiento real por proyecto: un rol de login y una base de datos propios para cada uno, sin permisos PUBLIC.
  • Origen blindado tras Cloudflare en dos capas —firewall UFW restringido a sus rangos IP y reglas DOCKER-USER de iptables, porque Docker puede saltarse UFW por su cuenta— y cabeceras HSTS/CSP centralizadas para toda la plataforma.
  • IP real del visitante verificada de extremo a extremo (Cloudflare → Caddy → backend): detecté y cerré un vector de suplantación en el X-Forwarded-For que habría permitido evadir el rate limiting de cada proyecto.
  • Backups automatizados por cron con pg_dumpall a object storage, con retención configurable.
  • Docker
  • Caddy
  • Cloudflare
  • PostgreSQL
  • Linux
  • Bash

portfolio

2026

Landing estática en Astro con cero hidratación de framework y una CSP que bloquea cualquier script inline.

La landing de este dominio, pensada para mostrar el trabajo de forma clara: tarjetas de proyecto con capturas, stack y logros verificables, más un filtro por tecnología. El frontend es Astro estático con cero hidratación de framework, toda la interactividad es TypeScript vanilla y se lee entero sin JavaScript. Detrás, un backend FastAPI mínimo que solo recibe los mensajes del formulario de contacto, sobre la misma infraestructura self-hosted que el resto de proyectos.

  • Content Security Policy estricta sin scripts inline, verificada en build por un script que falla el despliegue si aparece un <script> con cuerpo.
  • Contenido y diseño en una sola fuente de verdad (datos dirigidos por datos + design tokens): añadir un proyecto o cambiar la paleta no toca componentes y conserva el contraste WCAG AA.
  • Accesibilidad de base: modal y lightbox en <dialog> nativo con foco atrapado, anuncios por aria-live y respeto de prefers-reduced-motion.
  • Endpoint de captación de leads que siempre responde 201 (incluso si el honeypot detecta un bot), con rate limiting por IP agrupado por /64 en IPv6 y aviso por email vía Resend que nunca puede tumbar la petición.
  • Cadena de suministro del frontend auditada antes de construir: ignore-scripts bloquea cualquier postinstall de npm, y el lockfile se resuelve y audita con cuarentena por fecha antes de que el build ejecute código de terceros.
  • Astro
  • TypeScript
  • GSAP
  • FastAPI
  • PostgreSQL
  • Docker
  • Caddy
  • Nginx

cat contacto.txt

contacto

exit

Hecho con Astro y servido desde un VPS propio con Docker, Caddy y nginx. © 2026 Juan Rodríguez Aviso de privacidad

Escríbeme

Cuéntame quién eres y en qué puedo ayudarte. Suelo responder en menos de 24 horas.