I came to software the long way round. For years I worked in healthcare operations, where the margin for error was thin. Somewhere in there I started automating the parts that kept breaking, and the building never stopped.
These days the work is mostly backend: pulling messy data into something coherent, designing dashboards people actually use, and wiring up workflows that run without anyone babysitting them. The interesting problems are rarely the happy path. They are the edge cases and the failure modes.
It is one thing to make something work once; it is another to make it auditable, documented, and safe to hand over. A long stint working under operational pressure, plus a clinical and management background, taught me to design for the day things go wrong rather than the day they go right.
Right now I am going deep on backend development through the boot.dev track: Python, data structures and algorithms, Linux, and a bit of C for the memory-management fundamentals. I build to understand things from the ground up, and I would rather ship a practical solution than talk about one. On the side, I am chipping away at German.
A Flask web app that runs an inter-team fitness and sports competition: teams score across four pillars, participants connect Strava so their runs, rides, and swims sync and get verified, and officials record results and close out each month’s challenges through an admin area. The stack is Flask and SQLAlchemy over SQLite in WAL mode, with Strava OAuth for activity data and Firebase for sign-in, deployed on Railway behind gunicorn. The design deliberately splits identity from permission: Firebase proves who you are, but the app’s own database decides what you can do, including an account kill-switch that takes effect on the very next request. Server-rendered pages carry an httponly session cookie rather than a bearer token, because a rendered page has nowhere to put an Authorization header.
A PowerShell tool that scans every environment in a Power Platform tenant and reports broken, expired, or soon-to-expire connections before they take flows down. For each unhealthy connection it maps the flows that depend on it, so you see the blast radius instead of a bare error list. The fiddly part was the mapping itself: a flow references its connection by an internal connectionName string rather than an id, so the tool resolves those references directly. Built on the Power Apps administration cmdlets, with retry logic and progress reporting for large tenants.
The incident-response companion to the connection health checker: a PowerShell script that sweeps all environments for flows that failed in the last 24 hours, or any window you give it, and produces a single failure report. It installs the administration modules it needs on first run, so it works from any admin workstation. Written for the boring but vital job of knowing every morning exactly what broke overnight.
A self-hosted homelab on a ZimaBoard 2 running ZimaOS, with a RAID1 mirror (2 x 4 TB, BTRFS) holding media, backups, and personal archives, and Docker services running off the pool. Everything is published through Cloudflare Tunnels rather than port forwarding, so it is reachable from anywhere without opening a single inbound port on the home network. The sharpest lessons have come from storage: a migration once filled the system disk and left the storage layer unable to cleanly reattach the array, which taught me to treat the OS as disposable and the data as authoritative, and to rebuild from a verified backup rather than chase a half-recovered state.
A spreadsheet model for analysing residential buy-to-let investments across financing, cash flow, and tax treatment. One set of inputs scores a deal; assessing a new property means changing the inputs, not rebuilding the maths. The hard part is keeping the tax treatment readable and auditable: the rules are encoded as transparent formulas that can be traced, rather than a black box. Built in Excel and Google Sheets.