Skip to content
bizurk
← ALL WRITING

2026-06-02 (Updated 2026-10-23) / 17 MIN READ

The system that runs my own practice

I built the command center, CRM, and deal pipeline that runs my own client work. One person, one screen, brand and code and data in the same place.

Most people who do client work buy the system. They pay for a CRM, a project tool, a proposal app, a scheduling thing, and then spend a chunk of every week keeping those five tools agreeing with each other. I went the other direction. The thing that runs my practice is something I built, and it lives on the same domain you're reading this on right now. Same brand, same database, same code. One screen I open in the morning that tells me what needs me today.

This is a walk through that system. What it is, why I built it instead of buying it, and the part that's mostly just for fun.

The reason I can talk about it openly is that the build itself is the point. The people who can concept the brand and write the React and design the schema and wire the AI orchestration are pretty rare. I'm one of them. The command center is the clearest evidence of the thing I'm actually selling, so I'd rather show it than hide it.

A single monolithic brutalist control tower rising from a wide empty desert plateau, rows of thin glowing slit windows climbing its face under an open sky.
// the command center

What the command center actually is

A single concrete observatory dome standing alone on a cracked desert flat at dusk, a soft pink glow lighting its slit windows.
// the one place I look from

It's an admin cockpit sitting on top of a real CRM. The CRM has the normal stuff: companies, contacts, deals, activities, tasks. The cockpit is the layer on top that I open first thing and that answers one question before I've had coffee, which is what needs me today.

The top panel is a ranked list. Overdue tasks first, then what's due today, then deals that have gone quiet. A deal counts as quiet when nothing's happened on it in fourteen days, and once it crosses that line it surfaces in the list on its own so I don't have to remember to go looking. The list is capped at seven items on purpose. I have ADHD and an unbounded task list is how I lose a whole morning to deciding what to do instead of doing it. Seven things, ranked, then I close the panel and work.

Under that is a kanban board, but the lanes aren't deal stages. The lanes are the areas of my actual work: site, SEO, the cold-outreach funnel, LinkedIn, the freelance channel, client projects, admin. Every task lands in one of those lanes. If a task doesn't have a lane set, the system derives one from the task type, so nothing ends up orphaned in a column called "other." The board reads like my week reads, which is the only reason I look at it.

Why I built it instead of buying it

I get why building your own CRM sounds like a bad idea. It's the classic trap, the thing every engineer wants to do and shouldn't. Yeah, that's fair. I'd push back on it too if a client pitched it to me cold.

It works in this specific case for one reason. The off-the-shelf tools are all built around the assumption that different people do different jobs. Sales lives in one tool, the work lives in another, the brand lives in a third, and the seams between them are where the integrations and the Zapier glue and the weekly reconciliation live. I don't have those seams. It's just me. The brand, the code, the data, the outreach, all of it is one person, so the tool that fits is one tool that holds all of it in one schema.

When the deal and the deliverable and the proposal and the personalized page a prospect saw are all rows in the same database, a lot of work disappears. Nothing to sync, nothing to reconcile between apps. A deal detail page can show me the full proposal record right there, the channel it came through, the bid, the questions I answered, the link to the page I sent them, because it's all one record and I wrote the page that renders it.

A single narrow glowing slit window set into a vast weathered concrete wall, the one bright aperture dominating the frame.
// one record, lit

The other reason is honest: I like building it. The mornings I spend extending the cockpit aren't a tax, they're the thing I'd be doing anyway. A bought tool I'd tolerate. A tool I built I actually open.

The deal pipeline

A deal in my system is a row with the usual fields, plus one I care about a lot, which is a JSON blob that holds the full proposal record. Most CRMs treat a proposal as an attachment or a link off to some other app. Mine treats it as structured data living on the deal: the channel, the job title and URL, when I submitted, the current status, the bid, a summary of what they asked for, the actual text I sent, the screening questions and my answers, and a link to whatever personalized page I pointed them at.

That last field is the one that ties the whole system together, so let me come back to it in a second.

The pipeline view rolls those deals up into a small stat strip. Open count, total value, and a probability-weighted value, which is just each deal's amount times its win probability summed across the pipeline. The weighted number is the honest one. Total pipeline value is a vanity figure because half of it won't close. Weighted value is roughly what I should actually expect, and watching that number is how I know whether I need to be doing more outreach this week or whether I can put my head down and build for the clients I already have.

“

Total pipeline value is the number that makes you feel good. Weighted value is the number that tells you whether to panic.

”

The outreach funnel feeds it, and one channel is freelance

There's a cold-outreach funnel feeding the top of the pipeline. The cockpit shows me a rollup of it: how many contacts, how many active sequences, the open task load, what's due today, and a breakdown by lifecycle stage from lead all the way through to customer. It links out to the full workspace when I need the detail, but the rollup is usually enough to tell me whether the top of the funnel is healthy.

One of the channels that feeds the pipeline is freelance work through Upwork. It gets its own slice in the cockpit because the rhythm is different from cold outreach, but it's the same idea: proposals become deals, deals get a weighted value, the work flows into the same board as everything else.

The outreach itself is hand-written. Every proposal and every first message is something I actually wrote, looking at the actual job and the actual person. The system holds the record of it, ranks my follow-ups, and keeps me from dropping a thread. It doesn't write the message and it doesn't blast anything out. A prospect is a person I'm talking to, not a row getting processed. The tooling is there so the personal part has room to stay personal, because the part that wins the work is the part a script can't fake.

The base corner of a single massive brutalist concrete tower meeting cracked desert ground, one sharp structural edge anchoring the frame.
// where it meets the ground

The personalization layer

Now the fun part. The proposal record holds a link to a personalized page, and that link is a real feature of the site, not a mockup.

If you land on the site with a ?to= on the URL, the page knows who you are. At the simplest level it greets you by name in the hero. Underneath that there's a quieter mechanism: a ?to= can carry a short codename instead of a literal name, and the codename resolves through an API to a fuller record, a real display name plus a couple of hooks into the parts of the site that are mostly built for delight.

The way it's wired matters, so a quick note on the engineering. The server never blocks render on the lookup. The HTML that ships is generic, the same for everybody and safe to cache, and the personalization resolves on the client after the page is interactive. A personalized URL also tells search engines not to index that variant, because a page addressed to one person has no business showing up in results. The lookups cache per session so a refresh doesn't re-hit the API. None of that is visible to the person it's for. It just feels like the site knew they were coming.

The part that's mostly for fun

Tied to that personalization layer is a chaotic-evil 1997 Furby that lives on the site, runs a fictional backend, and will greet some visitors by name. There's a tiny TV room you can wander into. There's a hidden game. Most visitors never trip any of it, which is correct. The people who do are usually the ones who'd appreciate that a practice built around making delightful things put some delight in its own front door.

The site experiments show another part of the same practice. A working Furby with voice lines, a hidden game, and a greeting for a specific visitor all require design and browser implementation alongside the idea. I enjoy that work as much as the records and automation behind the command center.

Looking straight up the face of a single towering brutalist concrete structure against open sky, rows of thin glowing slit windows receding toward the top.
// all the way up

How it actually gets built

The whole thing runs on a Claude Code multi-agent setup. I work across several terminal sessions, each one a different piece of the build, and I orchestrate them the way you'd orchestrate a small team if the team never needed a meeting. One session extends the cockpit, another writes an article, another renders images on a separate machine. The work that used to need a brand person and a developer and a data person happens in parallel because the typing is parallelized, and the judgment stays in one head. Mine.

I've written about the morning sequence that feeds this in the studio routine I run before the first meeting, and the council-of-agents pattern I use for harder decisions in the agent council post. The two-machine render pipeline that made the images on this page lives in the batch orchestration write-up. The command center is where all of that lands, the surface the agents are building toward.

The records and maintenance sections below cover the documents underneath the cockpit. Reading that project state lets me open a session with the next decision already visible.

A single distant brutalist tower seen far across a sweeping empty plateau at dusk, the vast foreground plain leading toward it.
// the long view

The records underneath the command center

A dashboard is useful only if the work behind each row has enough context. The earlier practice notes described four groups of records. They still make a useful checklist for the system shown here, even when the storage tools change.

Intake and agreement

Save the original inquiry, the problem in the buyer's words, the relevant system access, and the decision owner. Before a call, record what is known and which questions affect scope. The agreement should name the deliverable, acceptance criteria, dependencies, revision boundary, and the date or cadence both sides accepted. Keep the sent version with the deal and a dated next action.

Delivery and decisions

Use a kickoff record to confirm scope and access. At the end of a working session, update the project state with what changed, the evidence location, the next action, and any blocker. A decision log should retain the choice, why it was made, alternatives considered, and who approved it. Run a deliverable check against the agreed acceptance criteria before handoff.

A status update can draw from those records: completed work, the result, the next commitment, and anything that needs the client's decision. The recurring document should make the update easier to write without turning it into generic prose.

Access, files, and maintenance

Keep credentials in the appropriate secret store with a clear client boundary. Use the project record to point to the access owner and renewal or revocation process, rather than copying secret values into a state document. The earlier architecture used Notion for records, 1Password for client vaults, and a private repository for templates. Those were tools in that account of the practice, rather than a required stack for using the checklist.

A consistent project folder should hold source material, working files, approved outputs, and the handoff record. Version reusable intake questions, agreements, checklists, and status formats so the reason for an update can be recovered. Test the backup and archive process instead of assuming an export means the files can be restored.

Closing an engagement

Review the remaining work and ownership before the last session. The closing memo needs the delivered artifacts, current system state, decisions still open, known risks, and the next person's starting instructions. Attach the access inventory and confirm the agreed transfer, rotation, or revocation with the client. Schedule a later check in when it serves the relationship and the client has agreed to it.

The retainer closeout guide keeps that final working session and transition timeline separate from everyday project tracking.

Put maintenance on a calendar

The original notes used session end updates, a weekly client status rhythm, monthly invoice and backup checks, quarterly access and tool reviews, and a review of each retainer around the six month point. Treat the timing as a starting schedule to adapt to the engagement.

At the quarterly review, compare templates with current pricing and terms, check access owners and subscriptions, sample a restored archive, and remove superseded instructions. A template that caused confusion during real delivery should be corrected then, with its reason recorded. At the annual review, compare the offer, capacity, and positioning with the work the practice actually delivered.

Start with the record that keeps getting lost. Running a useful status review for a month will show which fields the template needs. Extend the system from that observed friction instead of building every possible dashboard in advance.

What this is evidence of

I didn't build the command center to sell command centers. I built it because I run a practice and I needed one, and buying five tools that half-fit was more annoying than writing one that fit exactly. But the thing it ended up proving is the thing that's hard to prove any other way.

A retainer is a bet that one person can hold the whole picture. The brand, the build, the tracking, the data, the follow-up, without dropping the threads between them. The command center is me holding my own whole picture in one screen. If I can do that for my own practice, with my own brand and my own database and my own outreach all in one place, that's a pretty direct preview of what holding yours looks like.

An ultra-wide panorama of a single brutalist tower standing alone on the crest of a low rise, a pink dusk band glowing along the horizon behind it.
// one structure, the whole ridge

Frequently asked questions

Why build your own CRM instead of using a normal one?

Off-the-shelf CRMs assume different people do different jobs, so they split sales, work, brand, and data across tools that you then have to keep in sync. I'm one person doing all of it, so the tool that fits is one schema that holds all of it. When the deal, the deliverable, and the proposal are rows in the same database, the syncing and reconciliation work just disappears. I'm not recommending most people build their own. It fits my specific situation because there are no seams between roles to integrate across.

Is the outreach automated?

No. Every proposal and first message is something I wrote looking at the actual job and the actual person. The system holds the record, ranks my follow-ups, and keeps me from dropping a thread, but it doesn't write the message and it doesn't send anything in bulk. The part that wins the work is the part a script can't fake, so I keep that part by hand and let the tooling carry the bookkeeping.

What is the `?to=` personalization actually doing?

A ?to= on the URL lets a page greet a specific visitor and, with a codename, turn on a couple of small delight features tuned to them. The server never blocks render on the lookup, so the shipped HTML stays generic and cacheable and the personalization resolves on the client after the page is interactive. Personalized variants are flagged not to be indexed, since a page addressed to one person shouldn't show up in search.

Why is there a Furby in a portfolio site?

Because a site that runs a Furby with its own voice lines, a hidden game, and a per-visitor greeting was clearly built by someone who can do the brand, the front-end, and the playful bit on the same afternoon. The command center proves I can build the boring systems. The easter eggs prove I'd enjoy building yours. Most visitors never trip any of it, which is the right amount.

How does the multi-agent setup work day to day?

I run several Claude Code sessions at once, each on a different piece of the build, and I orchestrate them like a small team that never needs a meeting. One session extends the cockpit, one writes, one renders images on a separate machine. The typing parallelizes; the judgment stays in one head. I've written more about the daily sequence in the studio routine post.

Sources and specifics

The cockpit composes existing CRM helpers and mostly reads their data. Its implementation added neither tables nor migrations. A list capped at seven items ranks overdue tasks first, then tasks due today, followed by deals without activity in fourteen days.

Kanban lanes represent work areas: site, SEO, outreach funnel, LinkedIn, freelance channel, projects, and admin. Deal stages remain part of the underlying deal records. Each proposal record stores its channel, job title and URL, submission time, status, bid, request summary, sent text, screening answers, and link to the personalized page.

Pipeline value appears as an open count, a total amount, and an amount adjusted by each deal's win probability. Personalized greeting lookups are cached for the session and do not block the server render. Those personalized variants carry an instruction to exclude them from indexing.

The working command center demo remains on this page. Availability describes the current engagement path.

// related

Let us talk

If something in here connected, feel free to reach out. No pitch deck, no intake form. Just a direct conversation.

>Get in touch

Tell me what you’re trying to ship.

Send a quick message and I read it within a day, or talk to AI Michael first if you want to feel out your project before you write to me.

By sending this, you agree to the Terms and acknowledge the Privacy Policy.