[{"data":1,"prerenderedAt":398},["ShallowReactive",2],{"about-en":3,"cases-en":65,"adrs-en":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\u002Fen.md","En",{"type":7,"value":8,"toc":52},"minimark",[9,31,42,45],[10,11,12,13,17,18,22,23,26,27,30],"p",{},"I'm a fullstack software developer based in ",[14,15,16],"strong",{},"Huila, Colombia",", with around three years of experience and a foundation —uncommon at my level— in infrastructure and ",[19,20,21],"em",{},"DevSecOps",". My foundation of years is backend with ",[14,24,25],{},"Java (Spring Boot)"," and microservices architecture; today, day to day, I work with ",[14,28,29],{},".NET Core",".",[10,32,33,34,37,38,41],{},"I started as a junior developer at LianBPO, and it was at ",[14,35,36],{},"MetrixAL",", over nearly two years, where I built most of what I know: microservices, sovereign CI\u002FCD, containers, cloud deployments and observability, growing to technically lead projects. Today, as a fullstack developer at ",[14,39,40],{},"Transportes del Huila",", I apply that knowledge developing and maintaining systems.",[10,43,44],{},"I don't (yet) hold an architect title, but I think and work like one: I prioritize design, good practices and a systems view over the rushed fix. I use AI as an amplifier, keeping judgment and decisions on my side.",[10,46,47,48,51],{},"I'm studying ",[14,49,50],{},"Software Engineering"," (5th semester) at Politécnico Grancolombiano and I'm a Technologist in Software Analysis and Development.",{"title":53,"searchDepth":54,"depth":54,"links":55},"",2,[],"I'm a fullstack software developer based in Huila, Colombia, with around three years of experience and a foundation —uncommon at my level— in infrastructure and DevSecOps. My foundation of years is backend with Java (Spring Boot) and microservices architecture; today, day to day, I work with .NET Core.","md","en",{},true,"\u002Fabout\u002Fen",{"description":56},"about\u002Fen","d7C-R2r3rBDFSqrxyL3ZI8KsFS2ea8Dcif-5yD4Szfw",[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\u002Fen\u002F01.md","Extreme optimization · Lawyer.Metrix",{"type":7,"value":70,"toc":79},[71],[10,72,73,74,78],{},"At MetrixAL, Lawyer.Metrix's mass-report modules took over ten minutes and caused service outages. I diagnosed the bottlenecks with ",[75,76,77],"code",{},"EXPLAIN ANALYZE",", applied targeted indexing and refactored the query logic, bringing times down to under a minute.",{"title":53,"searchDepth":54,"depth":54,"links":80},[],"C\u002F01","Mass reports brought from over ten minutes to under one through EXPLAIN ANALYZE analysis, surgical indexing and logic refactoring.",">10 min → \u003C1 min","Impact:",{},1,"\u002Fcases\u002Fen\u002F01","−90%",{"title":68,"description":82},[91,77,92],"PostgreSQL","Indexing","cases\u002Fen\u002F01","2024","DyjWsZ-5xiK0PT2pIl8eq-G0TpckIUeqYxTeos71J_Q",{"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\u002Fen\u002F02.md","Multi-tenant migration · Cashing",{"type":7,"value":100,"toc":104},[101],[10,102,103],{},"I led the transformation of Cashing's transactional platform from a Laravel monolith into a network of microservices, adopting the Database-per-Tenant pattern to guarantee strict data isolation and independent per-tenant scaling, with a phased migration and no critical downtime.",{"title":53,"searchDepth":54,"depth":54,"links":105},[],"C\u002F02","Laravel monolith moved to microservices with the Database-per-Tenant pattern, with strict per-tenant isolation and a phased migration.","strict per-tenant isolation","Result:",{},"\u002Fcases\u002Fen\u002F02",null,{"title":98,"description":107},[115,91,116,117],"Laravel","Database-per-Tenant","Docker","cases\u002Fen\u002F02","VQmFLGgsozVNU8Xj7BfiVCz1S-2YFK0D1QCJIWoMJKs",{"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\u002Fen\u002F03.md","K3s infrastructure · ISO 27001",{"type":7,"value":124,"toc":128},[125],[10,126,127],{},"At MetrixAL I designed and deployed a high-availability Kubernetes cluster with K3s (1 master + 3 worker nodes), with sovereign CI\u002FCD based on Gitea (Actions, Packages and Secrets) and active observability with Prometheus and Grafana, aligned to ISO 27001 certification practices.",{"title":53,"searchDepth":54,"depth":54,"links":129},[],"C\u002F03","High-availability Kubernetes (K3s) cluster with sovereign CI\u002FCD on Gitea and active observability, aligned to ISO 27001 practices.","K3s HA · 1 master + 3 workers","Status:",{},3,"\u002Fcases\u002Fen\u002F03",{"title":122,"description":131},[139,140,141,142],"K3s","Gitea","Prometheus","Rocky Linux","cases\u002Fen\u002F03","2025","MrbVvSysH3VKs8dWNhIdiSnGDmtIuvx8D7cF-Mu81UE",{"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\u002Fen\u002F04.md","Async notification engine",{"type":7,"value":150,"toc":154},[151],[10,152,153],{},"I designed a high-throughput async messaging engine integrating Meta's WhatsApp API, Email and SMS, with native rate limiting, throttling and concurrent parallelism to sustain mass sends without degrading the service.",{"title":53,"searchDepth":54,"depth":54,"links":155},[],"C\u002F04","High-throughput messaging over WhatsApp, Email and SMS, with native rate limiting, throttling and concurrent processing.","WhatsApp · Email · SMS","Channels:",{},4,"\u002Fcases\u002Fen\u002F04",{"title":148,"description":157},[165,166,167],"WhatsApp API","Async","Rate Limiting","cases\u002Fen\u002F04","pjMp4kl3eCJwhhgEjp_xa1uMbUy0Hyn9EsKob4G-jFM",{"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\u002Fen\u002F05.md","Load-shift management · turnos.tdh.com.co",{"type":7,"value":174,"toc":178},[175],[10,176,177],{},"As a fullstack developer at Transportes del Huila, I develop and maintain turnos.tdh.com.co, which handles the management, assignment and auditing of load shifts for the operating fleets, proposing end-to-end solutions and driving its continuous improvement.",{"title":53,"searchDepth":54,"depth":54,"links":179},[],"C\u002F05","System for Transportes del Huila that manages, assigns and audits load shifts for the operating fleets. My current work.","in active development & maintenance",{},5,"\u002Fcases\u002Fen\u002F05",{"title":172,"description":181},[29,188],"Vue.js","cases\u002Fen\u002F05","2026","B1JpCfcZ4uSIGG7u51BLOUg_MgXUmAhHltRZPZy5Fus",[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\u002Fen\u002Fadr-001.md","Nuxt 4 with static rendering (SSG)",{"type":7,"value":197,"toc":224},[198,204,218],[10,199,200,203],{},[14,201,202],{},"Context."," The portfolio is content that doesn't change per request and must rank in search engines.",[10,205,206,209,210,213,214,217],{},[14,207,208],{},"Decision."," Nuxt 4 with ",[75,211,212],{},"ssr: true"," + prerender (",[75,215,216],{},"nuxt generate","): real static HTML, no runtime server. Migrating to SSR\u002Fhybrid stays trivial if needed later.",[10,219,220,223],{},[14,221,222],{},"Consequences."," Top speed and SEO, zero compute cost; dynamic features (contact form, dynamic OG) will be added as targeted routes when needed.",{"title":53,"searchDepth":54,"depth":54,"links":225},[],"ADR-001","2026 · 05","Context. The portfolio is content that doesn't change per request and must rank in search engines.",{},"\u002Fadrs\u002Fen\u002Fadr-001",{"title":195,"description":228},"accepted","adrs\u002Fen\u002Fadr-001","UYCm6wuF9bP1tx4OiI268_YqbWkYZ4yb7FNOhAhlAQY",{"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\u002Fen\u002Fadr-002.md","Hosting on Netlify (no K3s self-host)",{"type":7,"value":239,"toc":262},[240,245,253],[10,241,242,244],{},[14,243,202],{}," I know how to run K3s, but standing up my own cluster for a static site would be over-engineering.",[10,246,247,249,250,30],{},[14,248,208],{}," Deploy on Netlify (static): git-based builds, global CDN, HTTPS and correct 404 status out of the box. Config declared in ",[75,251,252],{},"netlify.toml",[10,254,255,257,258,261],{},[14,256,222],{}," Minimal management and continuous deploy on every push. The config is portable (same ",[75,259,260],{},"_headers"," and build) if I ever migrate to Cloudflare Pages or another platform.",{"title":53,"searchDepth":54,"depth":54,"links":263},[],"ADR-002","2026 · 06","Context. I know how to run K3s, but standing up my own cluster for a static site would be over-engineering.",{},"\u002Fadrs\u002Fen\u002Fadr-002",{"title":237,"description":266},"adrs\u002Fen\u002Fadr-002","BU5YyqP2XFqaOggbHvHX8hwh1CSoNIshgVpS9kAZBJg",{"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\u002Fen\u002Fadr-003.md","i18n with routes (prefix_except_default)",{"type":7,"value":276,"toc":312},[277,282,307],[10,278,279,281],{},[14,280,202],{}," The site is bilingual ES\u002FEN and must rank in both languages.",[10,283,284,286,287,290,291,294,295,298,299,302,303,306],{},[14,285,208],{}," ",[75,288,289],{},"@nuxtjs\u002Fi18n"," with the ",[75,292,293],{},"prefix_except_default"," strategy: Spanish at ",[75,296,297],{},"\u002F",", English at ",[75,300,301],{},"\u002Fen",", with per-language ",[75,304,305],{},"hreflang"," and canonical. The no-prefix (single URL) option was discarded for SEO reasons.",[10,308,309,311],{},[14,310,222],{}," Each language is independently indexable and shareable; switching language is SPA navigation (instant), only the URL changes.",{"title":53,"searchDepth":54,"depth":54,"links":313},[],"ADR-003","Context. The site is bilingual ES\u002FEN and must rank in both languages.",{},"\u002Fadrs\u002Fen\u002Fadr-003",{"title":274,"description":315},"adrs\u002Fen\u002Fadr-003","lL4kryC6Rtw_kSrMRecV33tyCvKJjkDvYlsapdv-Y84",{"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\u002Fen\u002Fadr-004.md","Light\u002Fdark mode with @nuxtjs\u002Fcolor-mode",{"type":7,"value":325,"toc":348},[326,331,343],[10,327,328,330],{},[14,329,202],{}," In SSG the theme flashes on first load if decided client-side after paint.",[10,332,333,335,336,339,340,30],{},[14,334,208],{}," After prototyping two options (module vs. a custom VueUse script), I chose ",[75,337,338],{},"@nuxtjs\u002Fcolor-mode",": it injects its anti-flash script before first paint. Storage with the brand prefix ",[75,341,342],{},"dannrodd-theme",[10,344,345,347],{},[14,346,222],{}," Zero theme flash, one dependency that solves the whole case instead of maintaining a custom script.",{"title":53,"searchDepth":54,"depth":54,"links":349},[],"ADR-004","Context. In SSG the theme flashes on first load if decided client-side after paint.",{},"\u002Fadrs\u002Fen\u002Fadr-004",{"title":323,"description":351},"adrs\u002Fen\u002Fadr-004","7XNUTPrPgmvce4fPpqnwNCqyzle11g8uoaI47hzOVSI",{"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\u002Fen\u002Fadr-005.md","Content in Markdown with @nuxt\u002Fcontent",{"type":7,"value":361,"toc":389},[362,367,380],[10,363,364,366],{},[14,365,202],{}," Long-form content (about, cases, ADRs) needs to be versionable, bilingual and easy to edit.",[10,368,369,371,372,375,376,379],{},[14,370,208],{}," Prose and documents in Markdown with ",[75,373,374],{},"@nuxt\u002Fcontent"," (Zod-validated frontmatter, one file per language); structured records in ",[75,377,378],{},"data\u002F*.ts"," and UI chrome in i18n.",[10,381,382,384,385,388],{},[14,383,222],{}," Editing a case or ADR means opening a ",[75,386,387],{},".md"," — no touching components or escaping JSON; content lives in git, is diff-able and schema-validated.",{"title":53,"searchDepth":54,"depth":54,"links":390},[],"ADR-005","Context. Long-form content (about, cases, ADRs) needs to be versionable, bilingual and easy to edit.",{},"\u002Fadrs\u002Fen\u002Fadr-005",{"title":359,"description":392},"adrs\u002Fen\u002Fadr-005","i5mPy12NTrQUgNXseREb_3fIzUsd960Ja7XSylRqPog",1782517743860]