Skip to main content

Work

Seven platforms. Four stories.

Each one starts with what was broken and ends with what changed. All of these run — not prototypes, not weekend projects. The wiring is one click down, if you want it.

7platforms designed, built and kept running
4languages I’ve shipped the same product in, on the server side
2publicly live right now, and you’re on one of them

Most of the code is in private repositories — some of it is a real company’s operations. So I’ve written these up properly instead of linking you to a login page: what broke, what I did, what changed, and the wiring one click down on each. Read as much of that as you want without talking to me. The walkthrough at the bottom of the page is for going further than a page can go, not for getting past a locked door.

Seven doesn’t count the company I built before this one. That’s on the about page.

In production today

Pelican

It proves a caregiver showed up. That’s how the company gets paid.

What was broken

Healthcare operations run on proof. Somebody has to be able to show that a caregiver arrived at the right house, at the right time, and did the things they were supposed to do. If you can’t show it, the company doesn’t get paid — and when the state comes to check, “we’re pretty sure” is not an answer.

This company was running on paper. Intake on paper. The medication schedules and the timesheets living in spreadsheets. Visit notes that arrived by fax, sometimes. Nobody could answer “how many visits happened last Tuesday” without a person and an afternoon.

What I did

I built the replacement, from the database up, and I still maintain it. Client intake and enrollment. Scheduling. Proof that a caregiver arrived where and when they said they did. Care notes. Staff records. Billing preparation. And underneath all of it, the evidence an inspector asks for — collected as the work happens, rather than reconstructed afterwards.

What changed

Leadership got live numbers instead of a monthly guess. Nobody lost a job over it; people just stopped spending their week re-typing things a system should have remembered.

It has been in production since 2023. Around 235 people open it to do their job every working day — caregivers, nurses, office staff — and it has recorded tens of thousands of confirmed visits.

They’ll act as a reference on request — ask, and I’ll put you in touch. There is no quote printed here.

PELICAN IntakeSchedulingVisitsCare notesBilling prep VISIT CONFIRMED
A diagram of Pelican’s scheduling screen, drawn here in the browser. Not a screenshot — there is no real client data on this page and there never will be.
If you want the wiring

An Angular front end over a C# and .NET web interface, with PostgreSQL and Entity Framework Core underneath. The whole cloud setup is described in Terraform files rather than clicked together by hand, so it can be rebuilt from nothing. Containers, a managed database, a delivery network, a web firewall, a load balancer, and secrets held outside the code. Sign-in is Google-only. Releases go out through GitHub Actions, and nothing in the release process holds a permanent key to my cloud account.

None of that is the hard part. The hard part is the visit proof: a record of where and when, written while the visit is happening rather than assembled at month-end, and still standing up months later when somebody asks to see it. That is a problem about clocks, locations, patchy signal and an audit trail long before it is a problem about a form — which is why it is the part of Pelican I would rather talk about than the stack above.

The experiment

One product, built four times on purpose

Python, C#, Go, Node. Same screens. Same database. The same rules about who’s allowed to do what, bar one key. Four different engines underneath.

What was broken

This one’s mine, not a client’s. Every developer has opinions about programming languages and almost nobody has paid for them. You use what your job uses, you read arguments online, and you form a preference you can’t really defend.

What I did

I picked one genuinely hard product and built it four separate times. It’s an access-control console: the tool an administrator uses to decide who inside a company can get into what, see who’s signed in right now, and cut somebody off mid-session. Real product, not a toy.

I kept the front end and the database identical, built the permission model the same way in all four — one key differs, and the caveats say which — and swapped only the engine underneath: Python, then C#, then Go, then TypeScript. Everything that changed, changed because of the language. That’s what makes it an experiment rather than four portfolio entries. I called them Kingfisher, Sharpbill, Goldfinch and Merlin.

What changed

Less than the internet argues about. All four do the same job to the same standard. What actually differed was how much code it took to be careful, how quickly each one started up, and how much the language caught before I did.

What didn’t differ was where the bugs were, or which part was hardest. Deciding who may do what to whom was the hard part every single time, for reasons that had nothing to do with the language.

One more thing

I turned a fleet of AI agents loose on each one with instructions to break its permission rules. They found real ways to give yourself access you shouldn’t have — in my code, before any of it shipped. That’s why I trust these four. I’ve tried to break them, and I brought help.

What I’d actually pick

Depends entirely on who maintains it after me, which is the same answer as everywhere else on this site. The table below is the short version of my reasoning, one verdict at a time, and you’re welcome to read it and disagree with me. Applying it to your problem rather than to mine is a conversation and not a paragraph — but the reasoning is on the page either way. It isn’t a preference, it’s four data points, and I can tell you what each one costs you because I paid it.

Shared by all four. The same React and TypeScript front end. Sign-in tied to the account’s permanent identifier rather than an email address somebody could reuse. Roles and permissions stored in the database and checked on every single request, not once at sign-in. Live presence, and a one-click switch to end somebody’s session. The same database. The same packaging, so every one of them runs the same way on any machine. And an adversarial review before any of them was called finished.
Four builds of the same access-control console, compared by language, the toolkit it runs on, and what each one taught me.
NameLanguageWhat it runs onWhat building it taught me
Kingfisher
Python 3.13 / FastAPI 0.139
PythonFastAPIThe first one, and the one where I worked out what finished meant. Quickest to something running. Its way of doing several things at once is as easy to misuse as it is to use, and it’s the one where I leaned hardest on tests to replace what a compiler wasn’t telling me.
Sharpbill
.NET 10 / ASP.NET Core
C#ASP.NET CoreThe most structured: the code is split into separate layers, one job each, with real browser tests and automatic checks for known-vulnerable packages built into the release process. Slowest to first light. Easiest to change six months later, and the one I’d hand to a team of five without worrying.
Goldfinch
Go 1.26 / Chi 5.2
GoChiThe leanest. Almost nothing acting on my behalf, which meant I understood every line and had to write every mechanism myself. It felt like the most code of the four; the count says it wasn’t. Smallest to run, fastest to start, fewest surprises in production.
Merlin
NestJS 11 / published API contract v1
TypeScript on NodeNestJSOne language from the database all the way to the browser, with a published description of the interface so other software can talk to it. Less switching between languages than I expected; more setup than I expected.

The repositories are private, so the longest version you can read without me is the nest: the four of them side by side with the measurements, the method that produced each column, where the languages made no difference at all, and one place where a number argues with a verdict of my own. A call goes past that: the architecture, the trade-offs, the parts that went wrong, and the code on the screen. Neither of those requires you to ask nicely for it.

You’re using it

Northwest Fortune Solutions

The public pages you’re reading are the front of a working internal console.

What was broken

A portfolio that only describes software is a claim. I wanted one that is the software.

What I did

Built the console. Staff records, permissions the server re-checks on every request, live presence and notifications, an admin area for the AI features, opt-in location sharing on a live map, and a permanent record of who did what. Then I put marketing pages on the front of it.

What changed

You can check my work without asking me. The AI console needs no account. And when I say I found a privacy bug in my own code, the write-up is on this same website, one click away.

The part I’d point at is the AI admin panel. In most software the instructions given to an AI model are written into the code, so changing a word of them is a development job. Mine treats each AI feature as something you configure: pick the provider, pick the model, rewrite the instructions, save. Every edit is kept as its own version, so if this week’s wording is worse than last week’s you switch back in one click. Nobody redeploys anything. And when it can’t reach a real AI service, it says so in amber instead of quietly making something up.

If you want the wiring

Angular 22, C# on .NET 10, PostgreSQL 17, live updates over SignalR, Entity Framework Core, Docker, deployed to Amazon Web Services on every push to the main branch. Sign-in is Google-only and the session lives in a cookie the page’s own scripts can’t read. Permissions are re-read from the database on every request rather than trusted from the sign-in, so revoking access takes effect immediately.

Live

Usage IQ

Teams are spending real money on AI coding assistants. The ones I’ve talked to couldn’t tell me how much. This tells them.

What was broken

Developers now hire AI assistants to help write code, and those assistants bill by usage. So a team of twenty is quietly running up a bill that arrives as one line on a statement. Nobody can see who spent what, on which project, or whether it was worth it.

The tools report usage differently, double-count the same work, and price each model separately, so “what did this cost us” has no simple answer. Finance asks anyway.

What I did

Built an analytics product that reads the usage from Claude Code and OpenAI Codex, strips out the double-counting, and prices each model correctly. The whole team lands on one screen. One Google sign-in, publicly live, and it’s grown into a hub of related tools since. A handful of people other than me use it, which is small and is not nobody.

What changed

A manager can answer “what are we spending, and on whom” in about ten seconds.

It has processed 40 billion tokens of assistant usage getting to that answer. Tokens are the unit these tools bill by, so the figure is the size of the pile it has had to de-duplicate and price.

If you want the wiring

Angular 21, .NET 9, PostgreSQL, live updates over SignalR, Google Gemini for the summarising, Docker, Amazon Web Services. Auto-deployed on every change to the main branch.

usageiq.online (opens in a new tab)

Want to look closer?

The code is private. I’m not.

The repositories aren’t public. Some of it is a real company’s operations and that’s not mine to open up; the rest I just haven’t cleaned up for strangers. That’s a real limitation of this page and I’d rather name it than dress it up.

What I can do is walk you through any of it live: the architecture, the decisions I’d defend, the ones I wouldn’t, and the actual code on screen. Half an hour is usually enough to tell whether I’m any good, and you can ask anything.

My GitHub — most repos are private (opens in a new tab)