[{"data":1,"prerenderedAt":156},["ShallowReactive",2],{"work-mevi":3},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":7,"order":9,"slug":10,"company":11,"role":12,"stack":13,"duration":19,"demoUrl":20,"featured":21,"summary":22,"body":23,"_type":150,"_id":151,"_source":152,"_file":153,"_stem":154,"_extension":155},"/work/mevi","work",false,"","Clinic Management SaaS",0,"mevi","Mevi","Founder & Principal Engineer",[14,15,16,17,18],"Rails 8","Vue 3","Inertia.js","PostgreSQL","Kamal","Aug 2025 – Present","https://mevi.pro/",true,"A Brazilian SaaS for medical clinic management, built end to end. Scheduling, electronic medical records, care orchestration, patient self-booking and subscription billing, on a multi-tenant Rails 8 monolith with clinical data strictly scoped per organization.",{"type":24,"children":25,"toc":142},"root",[26,35,41,47,52,58,67,81,89,94,102,107,115,120,126,131,137],{"type":27,"tag":28,"props":29,"children":31},"element","h2",{"id":30},"the-problem",[32],{"type":33,"value":34},"text","The Problem",{"type":27,"tag":36,"props":37,"children":38},"p",{},[39],{"type":33,"value":40},"Brazilian medical clinics run on a patchwork: one tool for the calendar, another for records, a spreadsheet for billing, WhatsApp for everything else. Nothing talks to anything. And clinical data carries LGPD obligations that most of that patchwork quietly ignores.",{"type":27,"tag":28,"props":42,"children":44},{"id":43},"my-role",[45],{"type":33,"value":46},"My Role",{"type":27,"tag":36,"props":48,"children":49},{},[50],{"type":33,"value":51},"Founder and Principal Engineer. Product, architecture, implementation, deploys. Every decision is mine, which means every decision has to be one I can still defend a year from now.",{"type":27,"tag":28,"props":53,"children":55},{"id":54},"what-i-built",[56],{"type":33,"value":57},"What I Built",{"type":27,"tag":36,"props":59,"children":60},{},[61],{"type":27,"tag":62,"props":63,"children":64},"strong",{},[65],{"type":33,"value":66},"Multi-tenant core",{"type":27,"tag":36,"props":68,"children":69},{},[70,72,79],{"type":33,"value":71},"A Rails 8 monolith with PostgreSQL Row-Level Security. Tenant scoping lives in the database, not in application code, so a forgotten ",{"type":27,"tag":73,"props":74,"children":76},"code",{"className":75},[],[77],{"type":33,"value":78},"where",{"type":33,"value":80}," clause can't leak one clinic's patients into another's. An in-database transactional event bus keeps side effects consistent with the writes that triggered them.",{"type":27,"tag":36,"props":82,"children":83},{},[84],{"type":27,"tag":62,"props":85,"children":86},{},[87],{"type":33,"value":88},"Server-driven SPA",{"type":27,"tag":36,"props":90,"children":91},{},[92],{"type":33,"value":93},"Inertia.js with Vue 3 and TypeScript. No separate API layer to keep in sync, no duplicated validation, but still a fully typed frontend on a shadcn-based design system. The stack most people reach for here would have been two codebases; this is one.",{"type":27,"tag":36,"props":95,"children":96},{},[97],{"type":27,"tag":62,"props":98,"children":99},{},[100],{"type":33,"value":101},"The product surface",{"type":27,"tag":36,"props":103,"children":104},{},[105],{"type":33,"value":106},"Scheduling, electronic medical records, care orchestration, patient self-booking, subscription billing. All of it in one place because that's the entire point.",{"type":27,"tag":36,"props":108,"children":109},{},[110],{"type":27,"tag":62,"props":111,"children":112},{},[113],{"type":33,"value":114},"Deploys",{"type":27,"tag":36,"props":116,"children":117},{},[118],{"type":33,"value":119},"Kamal, single command, database provisioning through zero-downtime container swap. Shipping should not be an event.",{"type":27,"tag":28,"props":121,"children":123},{"id":122},"engineering-approach",[124],{"type":33,"value":125},"Engineering Approach",{"type":27,"tag":36,"props":127,"children":128},{},[129],{"type":33,"value":130},"Every non-obvious decision is written down as an ADR — 24 and counting — and the domain is backed by 170+ RSpec suites. Not for ceremony. A solo founder's codebase has no one to ask, so the codebase has to answer for itself. That turned out to matter twice over: it's what makes the project navigable for AI agents too.",{"type":27,"tag":28,"props":132,"children":134},{"id":133},"outcome",[135],{"type":33,"value":136},"Outcome",{"type":27,"tag":36,"props":138,"children":139},{},[140],{"type":33,"value":141},"In production and running clinics. Still the codebase I reach for when I want to show what I actually think good software looks like.",{"title":7,"searchDepth":143,"depth":143,"links":144},2,[145,146,147,148,149],{"id":30,"depth":143,"text":34},{"id":43,"depth":143,"text":46},{"id":54,"depth":143,"text":57},{"id":122,"depth":143,"text":125},{"id":133,"depth":143,"text":136},"markdown","content:work:mevi.md","content","work/mevi.md","work/mevi","md",1785441145423]