◆ SHIPPEDEngineering platform

From the route map to the last cent.

A fiber engineering and design firm was tracking projects, purchase orders, invoices, and payments in spreadsheets. I replaced them with one production platform, built end to end: KMZ/KML route maps, segment workflows, invoicing, payments, and payroll. The interesting engineering is where nobody looks — money that stays exact when two people pay the same invoice at once, and financial data only Admins can see.

TypeScriptReactTailwindPrismaSQL ServerAzure
Next.js 16React 19Node 24Prisma 7 MSSQL adapterBetter Auth + Entra IDZod 4TanStack FormGoogle Maps KML layerAzure Blob SASpdf-libSentryshadcn/Radix UIVitestPlaywrightGitHub Actions + OIDC
◆ Under NDA — architecture and engineering approach only. No real geography, client names, or production screenshots; the route map below is illustrative.
97
Server Actions across 20 modules
12
Serializable transactions in the financial modules
4
database triggers enforcing invoice totals and links
58
unit + Playwright test files, up from 26 in under two months
fiber-pm
// The problem

A spreadsheet holds the data. It can't hold the rules.

The work runs from client and carrier, through projects and jurisdictions, down to route segments. Each segment moves through nine statuses and about fifty milestone dates: high- and low-level design, up to five revision cycles, three reviewer sign-offs, and permit steps. Designers, PMs, and QC reviewers are assigned per segment and paid by the foot.

A spreadsheet will hold all of that. It won't stop two people from overpaying the same invoice, keep billing columns away from a designer, or tell you which segments are waiting on QC. The build started with archaeology: mapping legacy spreadsheets and CSV exports into SQL tables and noting where the numbers disagreed.

// How it works

One relational model under the map and the money.

It's a Next.js 16 app on Node 24, deployed to Azure App Service. Server Components read through a cached data-access layer. A typical write is a Server Action that authorizes the user, validates with Zod 4, writes through Prisma 7's SQL Server adapter, invalidates its cache tags, and logs an audit entry after the response. The schema is database-first: idempotent SQL, tested against the live dev database, then pulled into Prisma.

The money is one chain: purchase orders, invoices with line items and a three-reviewer approval, then payments. Payroll is footage times a rate (the project's override, or the person's default), with a fixed reserve held back. KMZ/KML route files live in Azure Blob Storage, and Google's KML layer draws them. Sign-in goes through Microsoft Entra ID, but only for people already on an allowlist, who get that record's role and a dashboard to match.

// What was hard

Where the obvious version was wrong.

Two about money, then the ones that could leak data, blank the map, or lock people out.

Two people, one invoice. Check the balance, then write the payment, and two admins paying the same invoice can both pass the check. Payment changes now run at Serializable isolation, retry conflicts with growing, randomized delays, and re-read the balance inside the transaction. A quieter bug: a PO whose invoices included a zero-balance placeholder rejected valid payments as overpayments. Payments now go to the invoice with the smallest balance that still covers them.

"Paid" has to mean paid, to the cent. Money stays in exact decimals until it's displayed. Zero-total invoices with no payments had been showing as Paid; now Paid needs a real payment. Payroll payouts are split across segments with largest-remainder rounding, so the pieces always add up. Underneath, four database triggers enforce invoice totals and record links, with row locks added after a code review found race conditions.

A cache doesn't know who's asking. Moving reads to Next.js Cache Components risked serving one role's cached result to another, and an Admin's copy carries the money. So the cache holds only raw rows, and the data layer strips financial fields for everyone but Admins after the cache, not inside it. Role-based Playwright tests check that PMs and Designers stay out of the financial pages.

Google fetches the map, not the browser. The route file is rendered on Google's servers, so the app's usual 15-minute private link won't do. Route files get a 24-hour read-only link with the right content type, created only for a signed-in user, and a failed render is flagged to the user and logged to Sentry. There's no geometry code, on purpose; Google's limits are the limits.

The security header that broke sign-in. In February 2026 a strict Content Security Policy first blocked the theme script on Azure, then broke Microsoft sign-in. Three same-day fixes later, enforcement was briefly switched off to restore it. The rebuild added nonces to the auth pages and a CI step that pins the hash of the one Next.js inline script that can't carry a nonce, so an upgrade that changes it fails the deploy instead of the login page. Scripts are enforced today; inline styles are still allowed behind a flag.