From complaint to deploy in a week
One August feature in Dental Prospector, the territory map I built and still run for three regional offices while working there in field sales, walked day by day. This is how the loop typically runs, and it is the reason I am looking at forward deployed engineering: the job is to sit inside the customer's world and ship into it.
2 minutes 50 seconds. Real commit messages from the repository; all product data shown is synthetic.
The loop
A rep calls. I write the spec that night. I ship it behind a version number, with a migration, a service worker bump and a what's new note in the app. Then I measure, and I call the same rep back. Typical time from the call to the deploy is about a week, and there is no ticket queue anywhere in it. Five hundred and eighty nine commits between February and September 2026 and forty nine minor versions, one developer working with Claude Code, all while carrying a full sales territory. That is a minor version about every four days on average, so a week from call to deploy is the usual pace, not the best case. No model runs in this fix, on purpose: the doctor names were already in the data and search could not see them, so the answer was a column and a trigger, not a prompt.
One week, one feature
- Day 1
The call
A rep searched for an office by the doctor's name and got nothing. The person calling is a colleague, not a ticket. That night I wrote the spec on one page: what they said, what the data actually looks like, and what would make the complaint impossible.
- Day 2
The data
Search matched doctor names against a JSON field on each office. Months earlier, a speed update had stopped sending that field with the map load, to cut a payload of about 36 MB. Nothing errored. The doctor-name match just quietly stopped finding anyone whose name lived only in that field, so the fix had to happen in the data, not in the search box.
- Day 3
The migration
One flat doctor_names column, small enough to ride along in the fast load, kept in step with the JSON by a trigger and backfilled in one pass. The backfill only touches rows that still disagree, so running it twice is harmless, and the rollback statements sit at the top of the file.
- Day 4
The client
The app loads the new column and searches it. Earlier that week, a search with zero hits had started telling the rep who manages the office instead of showing an empty list, because an empty list is where reps stop trusting the tool.
- Day 5
The deploy
Version 1.46.2 ships on 19 August with the migration, a service worker bump and a what's new note inside the app. The same release fixed a panel that said "loading" forever when a fetch failed; it now says the load failed and how to retry. The version, the migration and the dates are in the commit log.
- Day 6
The call back
I call the same rep back and have them run the search that failed. Measuring is part of shipping; a feature nobody uses is a bug I own.
- Day 7
The next complaint
The next release, a day later, logs every search and location check that finds nothing, and I review that log. The next gap shows up before anyone has to call.
The migration
The fix lives in the data. This is migration 135, trimmed to the three statements that matter. The trigger function it names checks the JSON type in separate branches before it asks for an array length, because Postgres does not promise to evaluate an OR left to right.
alter table public.dental_offices
add column if not exists doctor_names text;
create trigger sync_doctor_names_from_enrichment_trigger
before insert or update of enrichment_data on public.dental_offices
for each row execute function public.sync_doctor_names_from_enrichment();
update public.dental_offices d
set doctor_names = sub.computed
from ( /* one computed value per office */ ) as sub
where d.id = sub.id
and sub.computed is distinct from d.doctor_names;What it adds up to
- Adopted with no mandate and no official project status behind it.
- Three offices onboarded in person.
- One to two hours a week returned to selling, reported by the reps who use it.
- Zero tickets between the person with the problem and the person who can fix it.
I would like to do this next for your customers, with your platform, in their environment.