[{"data":1,"prerenderedAt":398},["ShallowReactive",2],{"about-es":3,"cases-es":65,"adrs-es":192},{"id":4,"title":5,"body":6,"description":56,"extension":57,"locale":58,"meta":59,"navigation":60,"path":61,"seo":62,"stem":63,"__hash__":64},"about\u002Fabout\u002Fes.md","Es",{"type":7,"value":8,"toc":52},"minimark",[9,31,42,45],[10,11,12,13,17,18,22,23,26,27,30],"p",{},"Soy desarrollador de software fullstack basado en ",[14,15,16],"strong",{},"Huila, Colombia",", con alrededor de tres años de experiencia y una base —poco común a mi nivel— en infraestructura y ",[19,20,21],"em",{},"DevSecOps",". Mi base de años está en el backend con ",[14,24,25],{},"Java (Spring Boot)"," y la arquitectura de microservicios; hoy, en mi día a día, trabajo con ",[14,28,29],{},".NET Core",".",[10,32,33,34,37,38,41],{},"Empecé como desarrollador junior en LianBPO, y fue en ",[14,35,36],{},"MetrixAL",", durante casi dos años, donde construí la mayor parte de lo que sé: microservicios, CI\u002FCD soberano, contenedores, despliegues en la nube y observabilidad, llegando a liderar técnicamente proyectos. Hoy, como desarrollador fullstack en ",[14,39,40],{},"Transportes del Huila",", aplico ese conocimiento desarrollando y manteniendo sistemas.",[10,43,44],{},"No tengo (aún) un cargo de arquitecto, pero pienso y trabajo como tal: priorizo el diseño, las buenas prácticas y la visión de sistema por encima de la solución apresurada. Uso la IA como amplificador, manteniendo el criterio y las decisiones de mi lado.",[10,46,47,48,51],{},"Estudio ",[14,49,50],{},"Ingeniería de Software"," (5.º semestre) en el Politécnico Grancolombiano y soy Tecnólogo en Análisis y Desarrollo de Software.",{"title":53,"searchDepth":54,"depth":54,"links":55},"",2,[],"Soy desarrollador de software fullstack basado en Huila, Colombia, con alrededor de tres años de experiencia y una base —poco común a mi nivel— en infraestructura y DevSecOps. Mi base de años está en el backend con Java (Spring Boot) y la arquitectura de microservicios; hoy, en mi día a día, trabajo con .NET Core.","md","es",{},true,"\u002Fabout\u002Fes",{"description":56},"about\u002Fes","e98iiIrG59_RbiNA0gJj0DYigkSUmkt-ZGfYsHfkrXI",[66,96,120,146,170],{"id":67,"title":68,"body":69,"code":81,"description":82,"extension":57,"impact":83,"impactLabel":84,"locale":58,"meta":85,"navigation":60,"order":86,"path":87,"pct":88,"seo":89,"stack":90,"stem":93,"year":94,"__hash__":95},"cases\u002Fcases\u002Fes\u002F01.md","Optimización extrema · Lawyer.Metrix",{"type":7,"value":70,"toc":79},[71],[10,72,73,74,78],{},"En MetrixAL, los módulos de reportes masivos de Lawyer.Metrix tardaban más de diez minutos y provocaban caídas de servicio. Diagnostiqué los cuellos de botella con ",[75,76,77],"code",{},"EXPLAIN ANALYZE",", apliqué indexación dirigida y refactoricé la lógica de consulta, bajando los tiempos a menos de un minuto.",{"title":53,"searchDepth":54,"depth":54,"links":80},[],"C\u002F01","Reportes masivos llevados de más de diez minutos a menos de uno mediante análisis con EXPLAIN ANALYZE, indexación quirúrgica y refactor lógico.",">10 min → \u003C1 min","Impacto:",{},1,"\u002Fcases\u002Fes\u002F01","−90%",{"title":68,"description":82},[91,77,92],"PostgreSQL","Indexación","cases\u002Fes\u002F01","2024","f_ZpF_Gfa2wpVQvYnZLU5lIfoystAoCj2KQk7LC0J9Y",{"id":97,"title":98,"body":99,"code":106,"description":107,"extension":57,"impact":108,"impactLabel":109,"locale":58,"meta":110,"navigation":60,"order":54,"path":111,"pct":112,"seo":113,"stack":114,"stem":118,"year":94,"__hash__":119},"cases\u002Fcases\u002Fes\u002F02.md","Migración multi-inquilino · Cashing",{"type":7,"value":100,"toc":104},[101],[10,102,103],{},"Lideré la transformación de la plataforma transaccional de Cashing desde un monolito en Laravel hacia una red de microservicios, adoptando el patrón Database-per-Tenant para garantizar aislamiento estricto de datos y escalado independiente por inquilino, con una migración por fases sin downtime crítico.",{"title":53,"searchDepth":54,"depth":54,"links":105},[],"C\u002F02","Monolito Laravel llevado a microservicios con patrón Database-per-Tenant, con aislamiento estricto por inquilino y migración por fases.","aislamiento estricto por tenant","Resultado:",{},"\u002Fcases\u002Fes\u002F02",null,{"title":98,"description":107},[115,91,116,117],"Laravel","Database-per-Tenant","Docker","cases\u002Fes\u002F02","vx_lQ6UuAEEvDFs4f51_mas-oznDrKDhMwC7Ia-Pi64",{"id":121,"title":122,"body":123,"code":130,"description":131,"extension":57,"impact":132,"impactLabel":133,"locale":58,"meta":134,"navigation":60,"order":135,"path":136,"pct":112,"seo":137,"stack":138,"stem":143,"year":144,"__hash__":145},"cases\u002Fcases\u002Fes\u002F03.md","Infraestructura K3s · ISO 27001",{"type":7,"value":124,"toc":128},[125],[10,126,127],{},"Diseñé e implementé en MetrixAL un clúster Kubernetes con K3s en alta disponibilidad (1 nodo maestro + 3 de trabajo), con CI\u002FCD soberano basado en Gitea (Actions, Packages y Secrets) y observabilidad activa con Prometheus y Grafana, alineado a prácticas de la certificación ISO 27001.",{"title":53,"searchDepth":54,"depth":54,"links":129},[],"C\u002F03","Clúster Kubernetes (K3s) en alta disponibilidad con CI\u002FCD soberano en Gitea y observabilidad activa, alineado a prácticas de ISO 27001.","K3s HA · 1 maestro + 3 workers","Estado:",{},3,"\u002Fcases\u002Fes\u002F03",{"title":122,"description":131},[139,140,141,142],"K3s","Gitea","Prometheus","Rocky Linux","cases\u002Fes\u002F03","2025","hMKrc-_iN4h5DSsOzP2B0qwHTFCjlw7YL1enJrsgBDs",{"id":147,"title":148,"body":149,"code":156,"description":157,"extension":57,"impact":158,"impactLabel":159,"locale":58,"meta":160,"navigation":60,"order":161,"path":162,"pct":112,"seo":163,"stack":164,"stem":168,"year":144,"__hash__":169},"cases\u002Fcases\u002Fes\u002F04.md","Motor asíncrono de notificaciones",{"type":7,"value":150,"toc":154},[151],[10,152,153],{},"Diseñé un motor de mensajería asíncrona de alto rendimiento que integra la API de WhatsApp de Meta, Email y SMS, con rate limiting, throttling y paralelismo concurrente nativos para sostener envíos masivos sin degradar el servicio.",{"title":53,"searchDepth":54,"depth":54,"links":155},[],"C\u002F04","Mensajería de alto rendimiento sobre WhatsApp, Email y SMS, con rate limiting, throttling y procesamiento concurrente nativos.","WhatsApp · Email · SMS","Canales:",{},4,"\u002Fcases\u002Fes\u002F04",{"title":148,"description":157},[165,166,167],"WhatsApp API","Async","Rate Limiting","cases\u002Fes\u002F04","VwpHQ_Z4uZShfhpcy7bzixXB_afyFr8BYHNnCNLu86U",{"id":171,"title":172,"body":173,"code":180,"description":181,"extension":57,"impact":182,"impactLabel":133,"locale":58,"meta":183,"navigation":60,"order":184,"path":185,"pct":112,"seo":186,"stack":187,"stem":189,"year":190,"__hash__":191},"cases\u002Fcases\u002Fes\u002F05.md","Gestión de turnos de carga · turnos.tdh.com.co",{"type":7,"value":174,"toc":178},[175],[10,176,177],{},"Como desarrollador fullstack en Transportes del Huila, desarrollo y mantengo turnos.tdh.com.co, que resuelve la gestión, asignación y auditoría de turnos de carga para las flotas operativas, proponiendo soluciones integrales e impulsando su mejora continua.",{"title":53,"searchDepth":54,"depth":54,"links":179},[],"C\u002F05","Sistema para Transportes del Huila que gestiona, asigna y audita los turnos de carga de las flotas operativas. Mi trabajo actual.","en desarrollo y mantenimiento activo",{},5,"\u002Fcases\u002Fes\u002F05",{"title":172,"description":181},[29,188],"Vue.js","cases\u002Fes\u002F05","2026","4GZuTAq1rHdV7Tqd1Qs7Yqz1po5ljmK-gLm0MPHmzOk",[193,235,272,321,357],{"id":194,"title":195,"body":196,"code":226,"date":227,"description":228,"extension":57,"locale":58,"meta":229,"navigation":60,"order":86,"path":230,"seo":231,"status":232,"stem":233,"__hash__":234},"adrs\u002Fadrs\u002Fes\u002Fadr-001.md","Nuxt 4 con renderizado estático (SSG)",{"type":7,"value":197,"toc":224},[198,204,218],[10,199,200,203],{},[14,201,202],{},"Contexto."," El portafolio es contenido que no cambia por petición y debe posicionar en buscadores.",[10,205,206,209,210,213,214,217],{},[14,207,208],{},"Decisión."," Nuxt 4 con ",[75,211,212],{},"ssr: true"," + prerender (",[75,215,216],{},"nuxt generate","): HTML estático real, sin servidor en runtime. La migración a SSR\u002Fhíbrido queda trivial si más adelante hace falta.",[10,219,220,223],{},[14,221,222],{},"Consecuencias."," Máxima velocidad y SEO, costo de cómputo cero; las funciones dinámicas (formulario, OG dinámico) se añadirán como rutas puntuales cuando se necesiten.",{"title":53,"searchDepth":54,"depth":54,"links":225},[],"ADR-001","2026 · 05","Contexto. El portafolio es contenido que no cambia por petición y debe posicionar en buscadores.",{},"\u002Fadrs\u002Fes\u002Fadr-001",{"title":195,"description":228},"accepted","adrs\u002Fes\u002Fadr-001","uLL-ZDrTth1iBp0oSaQULPVrZxIaN1sbBxIjWPek_K8",{"id":236,"title":237,"body":238,"code":264,"date":265,"description":266,"extension":57,"locale":58,"meta":267,"navigation":60,"order":54,"path":268,"seo":269,"status":232,"stem":270,"__hash__":271},"adrs\u002Fadrs\u002Fes\u002Fadr-002.md","Hosting en Netlify (no self-host en K3s)",{"type":7,"value":239,"toc":262},[240,245,253],[10,241,242,244],{},[14,243,202],{}," Sé operar K3s, pero para un sitio estático montar un clúster propio sería sobreingeniería.",[10,246,247,249,250,30],{},[14,248,208],{}," Desplegar en Netlify (estático): build por git, CDN global, HTTPS y 404 con status correcto automáticos. Config declarada en ",[75,251,252],{},"netlify.toml",[10,254,255,257,258,261],{},[14,256,222],{}," Gestión mínima y despliegue continuo en cada push. La config es portátil (mismos ",[75,259,260],{},"_headers"," y build) si algún día migro a Cloudflare Pages u otra plataforma.",{"title":53,"searchDepth":54,"depth":54,"links":263},[],"ADR-002","2026 · 06","Contexto. Sé operar K3s, pero para un sitio estático montar un clúster propio sería sobreingeniería.",{},"\u002Fadrs\u002Fes\u002Fadr-002",{"title":237,"description":266},"adrs\u002Fes\u002Fadr-002","wNqDW-U0K9BtYnN46DgH3tAYN7nZ3a8vYYtt5eKPs2Q",{"id":273,"title":274,"body":275,"code":314,"date":227,"description":315,"extension":57,"locale":58,"meta":316,"navigation":60,"order":135,"path":317,"seo":318,"status":232,"stem":319,"__hash__":320},"adrs\u002Fadrs\u002Fes\u002Fadr-003.md","i18n con rutas (prefix_except_default)",{"type":7,"value":276,"toc":312},[277,282,307],[10,278,279,281],{},[14,280,202],{}," El sitio es bilingüe ES\u002FEN y debe posicionar en ambos idiomas.",[10,283,284,286,287,290,291,294,295,298,299,302,303,306],{},[14,285,208],{}," ",[75,288,289],{},"@nuxtjs\u002Fi18n"," con estrategia ",[75,292,293],{},"prefix_except_default",": español en ",[75,296,297],{},"\u002F",", inglés en ",[75,300,301],{},"\u002Fen",", con ",[75,304,305],{},"hreflang"," y canonical por idioma. Se descartó la opción sin prefijo (un solo URL) por SEO.",[10,308,309,311],{},[14,310,222],{}," Cada idioma es indexable y compartible por separado; el cambio de idioma es navegación SPA (instantáneo), solo cambia la URL.",{"title":53,"searchDepth":54,"depth":54,"links":313},[],"ADR-003","Contexto. El sitio es bilingüe ES\u002FEN y debe posicionar en ambos idiomas.",{},"\u002Fadrs\u002Fes\u002Fadr-003",{"title":274,"description":315},"adrs\u002Fes\u002Fadr-003","DF84WhZxDmMEy8_ZcjVDCX-gDZX7qmS8Ihkqh1ZCuQk",{"id":322,"title":323,"body":324,"code":350,"date":265,"description":351,"extension":57,"locale":58,"meta":352,"navigation":60,"order":161,"path":353,"seo":354,"status":232,"stem":355,"__hash__":356},"adrs\u002Fadrs\u002Fes\u002Fadr-004.md","Modo claro\u002Foscuro con @nuxtjs\u002Fcolor-mode",{"type":7,"value":325,"toc":348},[326,331,343],[10,327,328,330],{},[14,329,202],{}," En SSG el tema parpadea en la primera carga si se decide en cliente tras el pintado.",[10,332,333,335,336,339,340,30],{},[14,334,208],{}," Tras prototipar dos opciones (módulo vs. script propio con VueUse), se eligió ",[75,337,338],{},"@nuxtjs\u002Fcolor-mode",": inyecta su script anti-flash antes del primer pintado. Storage con prefijo de marca ",[75,341,342],{},"dannrodd-theme",[10,344,345,347],{},[14,346,222],{}," Cero flash de tema, una dependencia que resuelve el caso completo en vez de mantener un script propio.",{"title":53,"searchDepth":54,"depth":54,"links":349},[],"ADR-004","Contexto. En SSG el tema parpadea en la primera carga si se decide en cliente tras el pintado.",{},"\u002Fadrs\u002Fes\u002Fadr-004",{"title":323,"description":351},"adrs\u002Fes\u002Fadr-004","gUJh6iFvusQlTL61hwqsLNYsLO3y35rL7of1YTWNXbc",{"id":358,"title":359,"body":360,"code":391,"date":265,"description":392,"extension":57,"locale":58,"meta":393,"navigation":60,"order":184,"path":394,"seo":395,"status":232,"stem":396,"__hash__":397},"adrs\u002Fadrs\u002Fes\u002Fadr-005.md","Contenido en Markdown con @nuxt\u002Fcontent",{"type":7,"value":361,"toc":389},[362,367,380],[10,363,364,366],{},[14,365,202],{}," El contenido largo (sobre mí, casos, ADRs) necesita ser versionable, bilingüe y fácil de editar.",[10,368,369,371,372,375,376,379],{},[14,370,208],{}," Prosa y documentos en Markdown con ",[75,373,374],{},"@nuxt\u002Fcontent"," (frontmatter validado por Zod, un archivo por idioma); los registros estructurados en ",[75,377,378],{},"data\u002F*.ts"," y el chrome de UI en i18n.",[10,381,382,384,385,388],{},[14,383,222],{}," Editar un caso o ADR es abrir un ",[75,386,387],{},".md",", sin tocar componentes ni escapar JSON; el contenido queda en git, diff-eable y con esquema validado.",{"title":53,"searchDepth":54,"depth":54,"links":390},[],"ADR-005","Contexto. El contenido largo (sobre mí, casos, ADRs) necesita ser versionable, bilingüe y fácil de editar.",{},"\u002Fadrs\u002Fes\u002Fadr-005",{"title":359,"description":392},"adrs\u002Fes\u002Fadr-005","5_RK8uskh40Qp0SWQrzkbN_aKhycdJTD7YPMmUMEUy8",1782517743859]