Migration recap · week of September 28 · 2026

Where’s my stuff? Now the dashboard answers first.

This week: shipments come to the customer instead of the customer going to a carrier website, five requirement documents get audited against the project’s own log, and a button that was hand-built for exactly three customers becomes a design for everyone.

The lead feature answers the question every B2B customer logs in to ask. The portal dashboard now opens with a card of your undelivered shipments — and tracking happens in the site. Click a shipment and a panel shows the actual scan history, cached so it loads instantly and refreshed live every few minutes, instead of bouncing you to a carrier website to paste a number into somebody else’s form. Zero clicks to see what’s coming; one click to see where it is.

The build had two instructive moments. First, the data archaeology: the tracking numbers we’d migrated turned out to be a one-shot historical backfill — there was no ongoing feed. But the colleague who owns the legacy sync confirmed that tracking numbers enter the legacy system at the moment a package is scanned, on the open order — which means the existing five-minute order sync, already running for other reasons, becomes the near-real-time delivery path. No new pipeline; one more field riding a train that already departs every five minutes. Second, the architecture: the feature got its own module specifically because wiring it into either of the two obvious homes would have created a dependency cycle between them. Sometimes the cleanest room in the house is a new one. Honest status: built and working on staging, with live carrier-side status polling waiting on the carriers switching on their API products — the keys exist; the switches aren’t flipped yet.

Second: this week the requirements got audited against the log. Five stakeholder requirement documents, swept line by line against 212 worklog entries, to separate “already shipped and verified” from “genuinely missing” — the output being a persistent gap register and a decision sheet with a deliberate format: every open decision states today’s actual behavior first, so choices get made against reality instead of an abstraction. The sweep paid for itself twice before it was even finished. It surfaced a real bug — a search page’s “Shop All” button silently dropping clicks in a redraw race, fixed the same day and confirmed by retesting under deliberately throttled network conditions. And it caught that two features had quietly been using two different definitions of “past due” — one counting days from the invoice, one counting from payment terms lapsing. Each is defensible; holding both at once is a contradiction no test suite would ever flag, because each feature passes its own tests. It’s now a named decision on the sheet instead of a latent surprise in production.

Third, a small story about generalizing privilege. The legacy site has a self-release button for held orders — hand-built, years ago, for exactly three customers. Rebuilding it verbatim would have meant hardcoding a VIP list into the new platform. Instead, archaeology found that the legacy hold field already records why each order is held — staff review, customer’s own request, sales-entered — which means the new design can offer self-service holds and releases to every account, gated on the hold’s reason rather than the customer’s name. The dig also shook out two sync bugs: a case-sensitive comparison quietly mislabeling held orders, and a hold code that fell through the mapping entirely. The design is locked and out for review with the colleague who owns the sync; the build comes next. Designed, not shipped — the distinction still matters here.

Two closers. A set of AI-researched claims about carrier capabilities crossed my desk this week, and checking them against the carriers’ actual published API specifications found several claimed capabilities that simply don’t exist — invented fields, a nonexistent operation. The usable answer turned out to be a no-code account setting. Entry 8’s lesson, applied to research instead of code: AI output is a draft, and primary sources are the referee. And some coordination housekeeping — a full sweep of everything this project is waiting on from other people, consolidated into one honest list. Unglamorous, and exactly the kind of thing that keeps a multi-person migration from deadlocking politely.

A dashboard that answers the first question, an audit that caught a contradiction, and a three-customer privilege redesigned as an everyone feature. The migration keeps paying down the past by generalizing it.