Plataforma IoT que monitorea y automatiza cultivos hidropónicos, organizada en 11 repositorios y construida por un equipo de cinco en el que soy el desarrollador líder.
Firmware para ESP32 en MicroPython que publica las lecturas de los sensores por MQTT sobre TLS, y un simulador que alimenta la demo con clima real sin hardware.
API en Spring Boot 4 con Java 21, MongoDB, Redis, JWT y OpenAPI, con más de 130 pruebas JUnit, que verifica la propiedad de cada cultivo y de cada dispositivo.
Asistente en FastAPI y scikit-learn que diagnostica cada cultivo con un sistema experto, lógica difusa y modelos que pronostican cuándo una variable va a salir de su rango.
PWA en React 19 y TypeScript, construida con Vite 8 y Tailwind 4, que muestra cada lectura frente a su rango ideal y deja actuar al asistente.
Este sitio es un portafolio bilingüe en React y TypeScript con páginas prerenderizadas, una vista por rol, una página para cada proyecto y un asistente que responde en el navegador.
Prerenderizado estático de cada vista y cada proyecto, con SEO por ruta, datos estructurados, sitemap e imágenes de Open Graph.
Cada sección carga su código y su texto por separado, con presupuestos que CI verifica para el JavaScript de arranque, el peso de cada chunk y lo que necesita el primer pintado.
Seis vistas por rol que reescriben el texto, reordenan las secciones y resaltan lo que importa a cada perfil.
Las cifras de GitHub salen, en cada build de CI, de las estadísticas que mi repositorio de perfil genera a diario.
Lo que construí en las empresas donde trabajo y trabajé. El código es privado y los clientes quedan en el anonimato; cada página cuenta la arquitectura.
Más de 20 servicios en FastAPI que mantienen Zoho CRM sincronizado con los sistemas académicos de más de 15 instituciones de Latinoamérica y España.
Un servicio por institución sobre un estándar común, con routers sin lógica, controladores que normalizan los datos y una sola capa de acceso por cada sistema externo.
Conecta PeopleSoft Campus Solutions por SOAP con WS-Security, bases SQL Server detrás de una VPN, archivos CSV por FTP, APIs REST y webhooks.
Las sincronizaciones largas responden 202 Accepted, corren en segundo plano y dejan en el CRM un registro de cada corrida con su resultado y su duración.
Los servicios recientes usan claves de idempotencia, reintentos escalonados cuando Zoho responde 429, trabajos persistidos en PostgreSQL y secretos cifrados con AES-256-GCM.
El stack que vigila los servicios de integración y los servidores donde corren, con métricas, logs, trazas, sondas y alertas en un mismo lugar.
Prometheus recoge 26 jobs entre los servicios en FastAPI instrumentados, los contenedores con cAdvisor, las máquinas con Node Exporter y Nginx con su exportador.
18 sondas de Blackbox Exporter revisan desde afuera que cada servicio y cada dominio respondan, y que sus certificados TLS no estén por vencer.
Promtail lleva los logs de los contenedores a Loki a través de un proxy de solo lectura del socket de Docker, y Tempo recibe las trazas de OpenTelemetry de los servicios.
Grafana reúne 4 tableros (Docker, FastAPI, máquina y Nginx) y 12 reglas de alerta, entre ellas errores 500 en las integraciones, contenedores que reinician en bucle, disco y CPU, que llegan a Telegram.
Cinco widgets que viven dentro de Zoho CRM para cotizar, matricular, capturar prospectos, agendar citas y cambiar de programa sin salir del registro.
Un cotizador que simula el plan de pagos en el navegador, aplica los descuentos con su tope, genera el PDF del plan de inversión y solo escribe en el CRM al confirmar.
Un asistente de matrícula en React que ejecuta en orden las cinco funciones en Deluge que hablan con PeopleSoft Campus Solutions, valida los datos antes de cada paso y traduce los errores del sistema académico.
La captura de prospectos desde una campaña, uno por uno o en carga masiva con plantilla, mapeo de columnas y revisión antes de importar.
La gestión de citas sobre los eventos del CRM para crear, reagendar, cancelar y registrar el resultado, con permisos de negocio que bloquean la acción cuando no pueden confirmar un rol.
Formularios que las instituciones publican en sus sitios para que un aspirante se registre, complete su solicitud y suba sus documentos, conectados al CRM por los servicios de integración.
Un flujo en varias páginas que va del registro del prospecto a la solicitud completa que actualiza la oportunidad, la carga de documentos y una página de agradecimiento.
Selects en cascada que cargan la oferta de cada institución (unidad, nivel, modalidad, periodicidad, ciclo y programa) desde la API de jerarquía académica.
Un script común para los formularios web del CRM que guarda los parámetros UTM en campos ocultos y preselecciona el programa desde la URL.
Versiones para pregrado, posgrado y educación continua, y formularios de becas y de relaciones familiares para los procesos que los piden.
Un generador de firmas para las cinco marcas del grupo que se ve igual en Outlook, Gmail y Apple Mail.
Un servicio en FastAPI y Jinja2 con un formulario, un catálogo por marca y tema, la descarga de un .htm para Outlook y un modo por lotes que convierte un CSV en un ZIP con una firma por persona.
Cada logotipo sale dos veces, como imagen alojada para los clientes modernos y como el nombre de la marca en texto para Outlook de escritorio, que renderiza con Word.
El nombre de respaldo se mide con una tabla de anchos de Arial Bold y baja de a un píxel hasta caber en su columna.
Una auditoría renderiza cada combinación de marca, tema e insignia y falla ante cualquier cosa que un cliente de correo rompería.
Más de 90 landing pages de admisiones para cinco instituciones de educación superior que envían cada lead a Zoho CRM con la campaña que lo trajo.
Landing pages en React, TypeScript y Vite que capturan los parámetros UTM, bloquean el doble envío, publican en Zoho Forms y envían el evento de conversión a Google Tag Manager.
WhatsApp, Meta Ads y Google Ads conectados al CRM por webhooks y REST, con funciones en Deluge y apps en Zoho Creator para los equipos comerciales.
Contacto de leads con agentes de IA en Dapta.
En los posgrados, el formulario pregunta el nivel de estudios del aspirante y la respuesta llega al CRM con el lead.
La infraestructura que publica, vigila y mantiene más de 100 landing pages de varios clientes en un solo VPS, sin reiniciar nada en cada despliegue.
Cada landing llama a un workflow reutilizable de GitHub Actions que instala, compila, verifica la ruta base, comprime los archivos con gzip, genera WebP de las imágenes y sube el resultado por rsync en dos fases.
El despliegue entra con un usuario sin shell, encerrado con rrsync y con la huella del servidor fijada, y el Nginx de cada cliente monta sus landings en solo lectura.
Un solo bloque de Nginx sirve cualquier landing registrada, con assets inmutables por un año, HTML sin caché, WebP por negociación y las etiquetas de Google Tag Manager inyectadas en el servidor.
Scripts que aplican un mismo cambio a los 106 repositorios (workflow de despliegue, política de Dependabot, archivos de entorno) y generan la configuración de Nginx de cada cliente.
Los resultados de cada noche para dos marcas de lotería y correos de bienvenida y cumpleaños, cada uno con el nombre y el segmento de quien lo recibe.
Un script en Python consulta la API de resultados, llena una plantilla Jinja2 que solo tiene variables y escribe el HTML listo para la plantilla de Amazon SES.
Correos que dispara un evento del suscriptor, como la bienvenida y el saludo de cumpleaños.
Los destinatarios salen de una vista de Zoho Analytics por su API de exportación masiva; cada correo lleva el nombre y el segmento de la persona, y una columna del archivo puede asignarle otra plantilla.
Si un sorteo todavía no se publica, el script sale con un código propio y el pipeline reintenta cada 10 minutos, hasta 9 veces, antes de enviar lo publicado.
Scripts y notebooks en Python que mueven grandes volúmenes de registros en el Zoho CRM de cada cliente, entre cargas, vínculos, etiquetas, borrados y sincronizaciones.
Parte los CSV, los sube como ZIP a la Bulk Write API, crea los trabajos, consulta su estado y los retoma si algo se corta.
Vincula, etiqueta y borra registros en masa desde un CSV, y prepara las importaciones en notebooks de Jupyter.
Sincroniza los clientes de la base Oracle de un cliente con su CRM.
Asigna códigos y prepara los envíos de SMS de una campaña, y analiza los segmentos antes de cada envío.
El sitio de captación de una inmobiliaria, que muestra los inmuebles que la empresa ya tiene en Wasi, sincronizados cada madrugada, y recibe solicitudes de asesoría, contacto y visita.
Cada madrugada, un workflow de GitHub Actions descarga el inventario de la API de Wasi, publica solo los inmuebles disponibles y, si algo cambió, hace commit y lanza el despliegue.
El listado y sus filtros leen un índice columnar de 25 campos por inmueble; el registro completo de cada uno queda en su propio archivo y se pide al abrir el detalle.
Cuando un inmueble sale de Wasi, la siguiente sincronización borra su archivo de detalle.
Las solicitudes de asesoría, contacto y visita llegan a una Edge Function de Supabase que valida los datos y los guarda en PostgreSQL.
La carrera completa en una organización de GitHub, con un repositorio por materia, del primer pseudocódigo a sistemas distribuidos, redes con equipos Cisco, inteligencia artificial y visión por computador.
En programación distribuida y paralela, un bingo multijugador por sockets TCP con hilos, un sistema escolar en Spring Boot con una capa GraphQL en FastAPI y React, y un Sudoku que resuelve por RMI.
En inteligencia artificial y datos, un sistema experto en CLIPS, lógica difusa, algoritmos genéticos, clasificadores de música, vinos e imágenes, y detección de enfermedades en lechuga con visión por computador.
En redes y sistemas, routers Cisco reales con OSPF, EIGRP e IPv6, monitoreo por SNMP, algoritmos de memoria y de planificación en Linux, y ensamblador ARM.
En ingeniería de software, pruebas con TDD en seis lenguajes (111 pruebas), patrones de diseño, bases de datos SQL y NoSQL, y una tienda full-stack con Spring Boot, React y MongoDB en Docker Compose.
Tres informes de laboratorio del diplomado, del reconocimiento con Nmap a la escalada de privilegios, y el análisis de un ciberataque con su plan de respuesta.
Laboratorio 1: el reconocimiento de una máquina vulnerable en una red aislada de Docker, con escaneos de Nmap de menos a más detalle hasta identificar vsftpd 2.3.4 y la investigación de su puerta trasera.
Laboratorio 2: el análisis de un phishing que termina en ransomware con doble extorsión, sus amenazas y vulnerabilidades, los principios de confidencialidad, integridad y disponibilidad, una matriz de control de acceso por roles y una arquitectura de nube segura.
Laboratorio 3: un CTF completo, del reconocimiento y la fuga de información a la fuerza bruta autorizada con Hydra y la escalada de privilegios, y una prueba controlada de disponibilidad sobre WordPress con ApacheBench y wrk.
Controles alineados con ISO/IEC 27001, el NIST CSF y las guías SP 800-61 y SP 800-34, y con la ley colombiana de protección de datos.
Un clasificador de imágenes con MobileNetV2 que distingue lechugas sanas, maleza y seis enfermedades, pensado para SmartPot, con una evaluación que muestra dónde falla.
MobileNetV2 con transferencia de aprendizaje sobre el dataset Lettuce Diseases de Kaggle, con ocho clases.
Exactitud de 97,9 % sobre 2.337 imágenes de prueba, con la matriz de confusión y el reporte por clase guardados en el repositorio.
El recall promedio por clase es 65,7 %, porque las seis enfermedades tienen entre 6 y 30 imágenes de prueba y el modelo acierta entre un tercio y dos tercios de ellas.
Un paquete de Python con scripts de entrenamiento, evaluación y predicción, configuración con uv y pruebas de la configuración y del dataset.
Diez imágenes de radar de una zona costera, filtradas, agrupadas con K-Means y convertidas en un dataset, y dos modelos de restauración que no lograron mejorar la entrada.
Diez imágenes mensuales de Sentinel-1 en polarización VV, de mayo de 2025 a febrero de 2026, reescaladas y filtradas con un filtro de Lee de 7 × 7.
K-Means con k = 3 y k = 4 sobre las imágenes con y sin filtro, y una binarización de agua y no agua a partir de los grupos.
Las diez fechas, alineadas y promediadas, forman una referencia sin ruido; de cada par se cortan parches de 512 × 512 para entrenar.
En la clasificación de escenas, ResNet50 con transferencia de aprendizaje llegó a 99,58 % de exactitud, mientras una CNN secuencial desde cero se sobreajustó y colapsó a una sola clase.
La gestión de áreas, oficinas, salones y empleados de un colegio en una API de Spring Boot, con una capa GraphQL en FastAPI encima y un frontend en React.
Una API REST en Spring Boot 3 con Java 21, JPA y H2: CRUD de áreas, oficinas, salones y empleados, y un reporte de empleados por área.
Cada empleado pertenece a un área y tiene una oficina; puede ser administrativo o profesor, y el profesor, de planta o contratista.
Una capa GraphQL con FastAPI y Strawberry que consulta la API REST con httpx y expone consultas y mutaciones sobre los mismos datos.
Un frontend en React 19 y Vite con listas, formularios y el reporte, conectado a la API con Axios.
El inventario de una tienda de moda, con una API en Spring Boot con JWT sobre MongoDB, un frontend en React y las tres piezas empaquetadas en imágenes de Docker.
Una API REST en Spring Boot con Spring Data MongoDB, documentada con Swagger, con búsqueda de productos por nombre, talla y categoría.
Inicio de sesión con Spring Security y JWT; el frontend guarda el token, lo verifica al abrir y lo envía en cada petición.
Un frontend en React, TypeScript y Vite con la tabla de productos y su creación, edición y borrado.
Tres imágenes de Docker publicadas en Docker Hub, para la API, la base de MongoDB con un script que carga datos iniciales y el frontend.
El mismo CRUD escrito prueba por prueba en C#, Python, React, PHP, Rust y Go, más los ejercicios de JUnit 5: ocho suites y 137 casos que corren en Docker.
Un CRUD de listas de reproducción con TDD en seis lenguajes, que son C# con xUnit, Python con pytest, React con Vitest, PHP con PHPUnit, y Rust y Go con sus herramientas de prueba.
Los seis comparten el modelo, con una entidad validada, un repositorio en memoria, identificadores asignados por el repositorio y dos clases de error, y pruebas que se llaman igual en todos.
Los ejercicios de la guía de JUnit 5 en Java y Kotlin, y pruebas unitarias frente a integración con Mockito.
Un docker-compose con un servicio por lenguaje que corre las ocho suites sin instalar ningún SDK.
Los cuatro módulos de la materia, con un sistema experto y uno difuso para velas japonesas, algoritmos genéticos, modelos para SmartPot y un agente reactivo con su tablero.
Un sistema experto en CLIPS, llamado desde Python con clipspy y con interfaz en Tkinter, que reconoce patrones envolventes alcistas y bajistas en dos velas japonesas.
Un sistema de lógica difusa con scikit-fuzzy que, con el tamaño de las velas y el envolvimiento, recomienda invertir poco, normal o mucho.
Algoritmos genéticos que reconstruyen el color de una imagen a partir de su versión en gris, y que optimizan el salto de un paracaidista para caer en el punto pedido.
Para SmartPot, una regresión logística que controla los ventiladores y una red neuronal que dosifica el pH, con versión de escritorio y en Streamlit.
Una aplicación de escritorio que comprime texto con codificación de Huffman, dibuja el árbol con Graphviz y devuelve el archivo idéntico al descomprimir.
Una ventana en PyQt5 donde se suelta un archivo .txt para comprimirlo o un .slo para descomprimirlo.
Cuenta la frecuencia de cada carácter, arma el árbol de Huffman, genera los códigos y escribe el resultado en binario con el árbol dentro del archivo.
Dibuja el árbol de cada archivo con Graphviz, y un instalador incluye los binarios de Graphviz y los agrega al PATH.
Con un texto de 3.215.616 bytes, el .slo pesa 1.712.850 (53,3 %) y al descomprimirlo vuelve idéntico al original.
Un sistema web en PHP y MySQL para reservar los espacios y equipos de la Institución Universitaria Salazar y Herrera, con un sitio de administración aparte.
Un sitio para la comunidad con registro, inicio de sesión, los espacios por bloque, los equipos y las solicitudes de reserva y préstamo.
Un sitio de administración aparte, AdminSitePersist, con sus páginas de CRUD y de historial.
PHP con Composer y MySQL; en local con XAMPP y en la nube con Heroku y una base MySQL en Azure.
Un README que documenta el problema, los objetivos, el alcance, el estado del arte y la propuesta, y un diagrama del flujo de trabajo con Git y del despliegue.
El sitio de una empresa ficticia que ofrece una nómina digital gratuita a emprendedores, en español e inglés, con registro y una calculadora de nómina en PHP y MySQL.
Un sitio en PHP, HTML, CSS y JavaScript con versión en español y en inglés.
Registro e inicio de sesión de usuarios sobre MySQL con PDO.
Un formulario de nómina con salario base, días trabajados, salud, pensión y turnos extra, nocturnos y festivos, que se guarda en la tabla de nóminas.
Informes de laboratorio del diplomado en ciberseguridad, con el análisis de vulnerabilidades de un servicio FTP, un CTF hasta la escalada de privilegios y la respuesta a un caso de ciberataque.
Pruebas y gestión de la configuración, con CRUDs escritos con TDD en seis lenguajes, 111 pruebas además de los ejercicios de JUnit y un script que corre las ocho suites en Docker.
Machine learning con clasificadores de género musical, vinos e iris, regresión de precios de vivienda, accidentes de tránsito, fine-tuning y un detector de imágenes propio.
Visión por computador en cinco guías, sobre convoluciones y color, un modelo de visión detrás de una API, agrupamiento de radar Sentinel-1, aprendizaje profundo y detección de enfermedades en lechuga.
En programación distribuida y paralela, un bingo multijugador por sockets TCP con hilos, un sistema escolar en Spring Boot con una capa GraphQL en FastAPI y React, y un Sudoku que resuelve por RMI.
Java, Spring Boot, Python, FastAPI, GraphQL, React
Inteligencia artificial en cuatro módulos, con un sistema experto en CLIPS, lógica difusa, algoritmos genéticos para colorear imágenes y modelos de clasificación para SmartPot.
Gestión de redes sobre routers Cisco reales, con RIPv2, OSPF y EIGRP, IPv6 con DHCPv6 y EIGRPv6, monitoreo por SNMP y capturas de tráfico en Wireshark.
Bases de datos NoSQL, con agregaciones en MongoDB y una tienda full-stack con API en Spring Boot y JWT, frontend en React y los tres servicios en Docker Compose.