Command Palette

Search for a command to run...

All Projects
Impact Hub

Impact Hub

Built for Impact Hub Houston. The project fixed an AI matching feature that had never produced a usable result, added the missing scheduling and volunteer tools, and did it by improving the system the four-person admin team already controlled instead of replacing it.

Next.jsReactTypeScriptClaudeSupabaseClerkVercelFigmaVS CodeLinear

The Problem

Impact Hub Houston used a large operations system built in Airtable, with 22 tables, three role-based views, and an AI feature meant to match people. In real use, that matching feature had never produced a single usable match. The intelligence existed in theory, but it gave the team nothing to act on.

Two other important pieces were missing. There was no way to schedule office hours, and there was no system for managing volunteers. On top of that, the data was getting messier over time, with duplicate records for the same person building up and no process to catch them.

A four-person admin team kept everything running by hand, matching about 15 entrepreneurs with 24 supporters manually. The system that was supposed to help them was not actually helping.

Why It Mattered

Every match the team made by hand took time away from work only they could do. The matching feature was supposed to handle that automatically. Instead, it was one more thing to check that never gave a useful answer.

I did not include a number for how much time this cost, because the team never measured it and I did not want to invent a figure. The simple point is that a small team was doing by hand the exact job the software was built to do for them.

How the Work Was Won

I organized the project around three goals: make the matching feature produce useful results, build the missing scheduling and volunteer tools, and stop the data from getting messier. The client signed a fixed-fee contract with four milestones.

The contract turned out to be more than a business document. It became the deciding factor whenever my design ideas and the agreed scope did not match. In those cases, the contract came first, and I wrote the project documents so that rule was clear.

Discovery

Discovery had two parts that ran at the same time. The first was interviews. I talked with all four members of the admin team, which was everyone who would use the product, not just a few of them.

The second part was a technical review of the live system. With permission, I had read access and made one approved test change, and I mapped how the 22 tables, the views, and the existing matching feature actually worked, rather than trusting the documentation.

I used a set list of open questions for both parts, so the interviews produced answers I could compare side by side instead of four separate conversations.

Discovery research and staff interviews
Discovery had two parts at once: interviews with the full admin team, and a technical review of the live system.

What I Found That I Did Not Expect

The finding that changed the project was this: the team did not want the product I had planned to build. They wanted to keep working in Airtable.

They liked being able to control their own automations and data structure without needing a developer. A custom app would have taken that control away and made them depend on me for every change. The more advanced option was not the better one for the people who used it every day.

What I Chose Not to Build

That finding turned the scope into a list of things to remove. Most of what a project like this would normally include, I decided not to build.

There is no custom admin screen. The team keeps working in Airtable, the tool they already control, instead of a new screen that I would own and they would need me to change.

There is no data move. The system copies from the Airtable base instead of moving the data out of it, so the client always keeps ownership of their records. The syncing goes one direction only, one field at a time, with a single source for each field. That choice removes a whole category of conflict bugs that would otherwise be hard to fix for the length of the contract.

Anything the contract listed as out of scope stayed out. I kept a backup option to buy a syncing tool if building it myself became too expensive. I set up the system so it could support other Impact Hub chapters later, but I did not spend extra time on that, because using it for other chapters depends on a separate agreement that does not exist yet.

Three-part system architecture
The three-part system adds to the Airtable base the team already controlled instead of replacing it.

Defining the Product

I wrote the documentation in two layers. A product requirements document explains the why and the what in twelve sections. Six build specs explain the how. Keeping them separate lets the goals stay steady while the technical details change.

One rule applies to both: if any document disagrees with the signed contract, the contract wins. Each of the three main parts in the requirements document points to a specific part of the contract, so scope disagreements get settled by checking the contract instead of by opinion.

Every build spec follows the same nine-part format and ends with acceptance criteria written as behavior. Each criterion describes an input and the result the system should produce, so a feature can be tested instead of just called done.

Execution

The build plan lives in Linear, with about 55 tasks organized into four phase projects plus one shared project for the AI work. I set up the workspace so the phases line up one to one with the contract milestones, which means I can show the client the board as the plan without rearranging it first.

Each task has two kinds of labels: one for its phase, so I can see the order of work, and one for the part of the system it belongs to, so I can see which part of the contract it serves. The same board answers both questions without a second tool.

Matching pipeline and scoring system
The matching process reads from the base, computes results, and writes scores back, so the client keeps ownership of their data.

Working With the Subconsultant

The matching intelligence is handled by an outside AI service, brought in as a subconsultant. I set a clear line between the two systems: my application owns the data and the workflow, and the subconsultant only does the computing. That line answered most of the integration questions on its own.

I gave the subconsultant a spec written like a proposed agreement for how the two systems would talk, including the exact endpoints, the data formats, the login method, and how repeated requests should behave. I marked it for their confirmation instead of assuming it was correct. When a detail was unclear, I tracked it in a single numbered list of open questions with one owner, instead of letting the questions get lost in messages.

I also planned for the outside service failing. Requests wait in a queue with a backup path if they cannot be delivered, retries slow down over time instead of hammering the service, and if the service stays down, the system falls back to basic similarity matching so it still returns a ranked list instead of nothing.

The Hard Calls

Three decisions were difficult, and one was simply wrong.

The first was whether to build a custom app or keep everything in Airtable. The contract allowed a custom build unless it slowed the client down. Discovery showed that the custom build itself was the thing that would slow them down, so the exception became the main rule, and the combined approach won.

The second was using AWS instead of the stack named in the contract. I chose AWS and recorded the change in the requirements document, along with a note about its cost, so the client could see the trade-off instead of being surprised by a bill.

The third was using the client's own words instead of the contract's terms. I named things the way the team already named them, even when the contract used different words, because people are more likely to use a product that matches how they already talk about their work.

The wrong decision was my first architecture recommendation. I had argued for a single custom app and specifically against a combined approach. Discovery showed that was wrong. I changed my recommendation, and the combined approach, the one I had argued against, became the core of the project.

Delivery

The work is checked at two levels. Each phase is approved in writing by the client at a review point, and each feature has acceptance criteria that either pass or fail. Below that is a set of required standards: following Texas data privacy law, encrypting data, keeping the database on a private network, and making sure the client owns the accounts rather than me.

The combined approach, which copies the base the team controls instead of replacing it, is what makes the result something they can actually run day to day.

Delivery and client sign-off
Each phase ends with written client approval, and each feature is checked against clear acceptance criteria.

What I Would Do Differently

The reversal is the lesson. I wrote an architecture recommendation before checking its main assumption with the people who would use it. The fix is about order: test the assumption with users first, then write the recommendation.