
Andrew Smith
Backend software engineer
I build backends where a wrong number is the bug — double-entry ledgers, insurance billing, data migration at scale.
On a ledger migration at ChiroHD, the test suite reported 4 of 4 gates passing. All 478 balances were wrong. The gates had been reading an inactive flag, so they were checking nothing at all.
That is the work: finding out what “passing” actually proved.
The path here
Before software I supervised the night shift at UPS in Baldwin, Wisconsin, from October 2017 to December 2021 — the only member of management on site after every other supervisor went home, running two sorts at once. One of them loaded air cans that go straight onto an aircraft with no further inspection, audited by the FAA, IATA and the TSA.
Part of that job was SALT testing — Service Awareness Label Testing. I would route a package that did not belong down a belt into a regulated area, or leave one where it was easy to miss, and see whether the process caught it. A clean audit tells you the audit passed; it does not tell you the check is working. That is the same question I ask a green test suite, and I did not learn it from software.
The A.A.S. came while I was still on the sort line — Web Design and Software Development at Wisconsin Indianhead Technical College,Summa Cum Laude — and I was already building websites for pay by then. I left UPS in December 2021, moved to Florida for a remote internship at GreyCastle Security, and finished a B.S. in Information and Communication Technology at University of Wisconsin Stout,Magna Cum Laude, after that.
What I work on
Correctness-critical backends
I build systems where a wrong number is the failure, not a cosmetic bug. At ChiroHD I built Ledger V2, a double-entry accounting system that tracks healthcare billing transactions, payments, adjustments, credits and insurance workflows for a multi-tenant SaaS platform.
Data migration at scale
Moving legacy financial data into new infrastructure is mostly a reconciliation problem wearing a migration costume. I wrote the tooling that moved ChiroHD's legacy financial data into Ledger V2 while holding balance integrity, plus the internal migration and validation tools the team used to see what production was actually doing instead of investigating it by hand.
Multi-tenant and regulated data
Healthcare data means HIPAA and PHI, and multi-tenant means one bad query can be both a performance problem and a disclosure problem. I work in multi-tenant PostgreSQL and tune the queries behind reporting, billing and financial reconciliation.
Agentic development infrastructure
AI agents repeat the same mistakes unless the corrections live in the repo instead of a chat log. I authored our agentic development infrastructure: repo-versioned subagent definitions, layered convention files that record anti-patterns alongside the failure mode each one caused, and deterministic pre-commit gates that block commits to protected branches — across a 15,000-commit codebase.
Stack
- Languages
- TypeScript, SQL, Rust, C#
- Backend
- Node.js, REST APIs, AWS Lambda, API Gateway, Serverless Framework, Express
- Data
- PostgreSQL, DynamoDB, SQL Server, schema design, multi-tenant architectures, query optimization
- Frontend
- React, Angular, Tailwind CSS, Vite
- Cloud and CI
- AWS, Terraform, GitHub Actions
- Testing
- Jest, Cypress, Playwright
- Agentic
- Claude Code, multi-agent orchestration, git-worktree isolation, custom subagent definitions, deterministic verification gates
Experience
ChiroHD
Full Stack Software Developer · Remote · December 2023 – present
- Built Ledger V2, a double-entry accounting system tracking billing transactions, payments, adjustments, credits and insurance workflows for a multi-tenant healthcare SaaS platform. TypeScript, Node.js, AWS Lambda, PostgreSQL.
- After the validation failure above, rewrote how the migration suites assert: fail-closed validation, bidirectional assertions, denominator checks. A suite with nothing to check now fails instead of passing.
- Built an internal EHR migration tracking platform — ~14,800 LOC across Rust, React, TypeScript and Terraform — in 9 working days over 5 weeks, directing AI agents across a stack I had not shipped before. 41 REST endpoints, a single-table DynamoDB design with 3 GSIs, Lambda authorization with Google SSO and RBAC, CI/CD on ARM64 Lambda, under $5/month to run.
- Authored the team's agentic development infrastructure: repo-versioned subagent definitions, layered convention files that record anti-patterns alongside the failure they caused, and deterministic pre-commit safeguards that block commits to protected branches.
Eastern Metal Supply
Full Stack Software Developer · Fort Myers, FL · March – November 2023
- Backend systems for manufacturing workflows: production scheduling, batching and labeling.
- Designed and tuned the SQL behind the business applications running those operations.
Earlier
Information Technology Intern at GreyCastle Security (Troy, NY, remote, Jan 2022 – Jan 2023); Web Developer, part-time, at First Presbyterian Church of Hinckley (Hinckley, MN, Jun 2019 – Aug 2021); Local Sort and Air Sort Supervisor and personal-vehicle-driver instructor at UPS (Baldwin, WI, Oct 2017 – Dec 2021) — the church work overlapping the UPS years, not following them. The UPS shift is described above.
Education
- B.S. Information and Communication Technology — University of Wisconsin Stout — Magna Cum Laude
- A.A.S. Web Design and Software Development — Wisconsin Indianhead Technical College — Summa Cum Laude
TurfOps — field-service software for lawncare, landscaping and snow
A landscaping operator's information lives in three places that do not talk to each other: scope of work in a Word document, money in QuickBooks, property details on paper in the truck. The gate code is on a sheet in the cab, the price is in an invoice nobody in the field can see, and what was actually agreed to was written weeks ago and never opened again. You find out whether you made money in the spring.
TurfOps is one durable record per property instead — scope, access details, service history and money in a single thread, quote to scheduled work to completed work to invoice, where each stage inherits from the last rather than being retyped.
It is two things at once, and both are honest. It is the public project on this page a reader can open and read. It is also software a real operator will run, which is why most of the interesting decisions in it are about cost and durability rather than features.
I have worked with or for three landscaping companies. The domain model comes from having done the work, not from interviewing someone who has. That is why the crew screen assumes gloves and sunlight — big targets, one thumb, readable on a phone in a truck — and why snow is not modeled as mowing in winter. Snow is event-driven and overnight, with different contract types, different materials and different liability exposure: a four-inch snowfall means every per-push client gets a visit in the same six-hour window, and the visit records accumulation and timestamps a mow never does.
Three decisions worth clicking for
- Seven requested features were one record. The owner asked for seven things: equipment right-sizing, arrival and departure times, revenue per worker-hour, drive-time analysis, dual-service bundling (lawn and landscape at one address, one trip), account keep/drop decisions, and crew color-coding on the master list. Read as a feature list, that is seven screens and a year of work. Read carefully, it is one record:who did what job, on what equipment, from when to when, for how much revenue. Capture that well and all seven are queries over one dataset. Capture it badly and they are seven half-features that do not reconcile. So the build order inverts the request: the data lands first, the dashboards last.
- Money is structurally absent from crew payloads, and three attempts to decide that by field name failed first. Row scoping is not enough — a crew member legitimately reads a visit on their own route, and that same row carries
revenue_microsandlabor_cost_micros. Selecting the row is allowed; letting those columns reach the tablet is not. Deciding “is this field name money?” was the hard part. A substring match claimedtotalStops, the crew screen's “Stop 3 of 11” counter. Segmenting the identifier fixed that and then claimedapplicationRate— lbs of salt per 1,000 sq ft, a number that belongs on the crew screen. The third attempt was wrong in both directions at once. No name rule separates “$/hour” from “inches/hour”: both are genuinely rates and the unit is not in the identifier. So the heuristic declines to judge ambiguous names and an explicit list decides them, over the one rule that generalizes — every money column carries its unit, soperSqFtRateMicrosis caught with no vocabulary at all, including a column added next year by someone who has never opened the file. The part worth arguing about: “false positives fail closed” is a claim about the field, not the filter. Over-redacting is harmless only when the field is unused. Where a rule cannot tell which direction it is wrong in, it should decline to answer. Written up as ADR-0013. - A portability budget, in dollars. Two facts decide the architecture: Vercel's Hobby tier forbids commercial use, and free Postgres tiers pause on inactivity — a crew tapping “complete” before dawn does not wait for a cold database. So the move off the free tier is not aspirational, it is dated, and the only open question is whether it is a config change or a rewrite. Named up front with numbers attached:~$0/month in phase 1, ~$8/month self-hosted in phase 2.What that costs concretely: geocoding from the US Census Geocoder because its free tier has no non-commercial clause, weather from NWS rather than the better-documented Open-Meteo for the same reason, S3 Signature V4 written by hand in about 60 lines rather than a 15MB vendor SDK, and the rule that makes the rest real — reject any dependency that cannot be swapped without touching business logic.
On rigor: a unit suite there passed 103 of 103 with a feature's wiring deleted. The contract tests built the payload themselves instead of observing what the component actually sent, so they were asserting about a shape no user ever received. There is averify script in the repo because “typecheck clean, lint clean, tests pass” were three claims nobody had run in one command.
Status: in active development. The roadmap is six numbered slices; the spine of the first is sound and demoable, and the first slice is not done. Recurring agreements, invoicing and the profitability dashboards are not built — the dashboards last on purpose, because they need a season of accumulated data to be anything but noise. What has shipped and what has not is listed on the demo's landing page, which is current in a way this page will not be.
Try TurfOps with the demo loginAsk me for the source
The repository is private for now. If you want to read the code — the redaction rule, the ADRs, the schema — email me and I will walk you through it.
Outside work
Running — four 5Ks and currently training for a half Ironman. National parks, with a standing goal of all of them. A house I am slowly rebuilding.The rest is on the about page.
Contact
New Richmond, WI · open to remote