A nutrition logger built around a chat box, not a chat box bolted onto a nutrition logger
The build started with a frustration. Every nutrition app on the phone took more than thirty seconds to log a single meal. They wanted a search box, a serving picker, a unit dropdown, a confirmation tap. None of them survived contact with the people who were actually supposed to use them. They got installed, opened twice, and died.
The fix was to delete the app. Not the data, the app. There is no MooreDiet app. There is a chat box on a website, and behind the chat box is a middleware that owns the truth. The user describes what they ate the way they would describe it to a person, and the AI does the structured-data work the user used to have to do.
Why this works
Two things had to be true. First, the AI had to be good enough to extract a structured meal record from "I just had four chicken tenders" without a multi-turn interrogation. It is, now. Second, the AI had to be stoppable when it was wrong. That is what the middleware exists for. The AI is allowed to be confident. The middleware is allowed to disagree.
The middleware does three jobs. It authenticates against a household allowlist. It owns the canonical record of every meal the household has ever logged. And it runs a Sanity Layer between the AI's claims and the database, so a value the AI invented out of thin air is flagged before it commits, with a number derived from either USDA FoodData Central or the household's own personal ledger.
The personal ledger
The first version of the project leaned hard on a generic food database. That database has 400,000 items in it. It also has nine entries for "pizza" and none of them match the homemade pizza the household actually eats. Generic databases are good for a guess and bad for a household.
The personal ledger is the household's own dictionary. The first time pizza is logged, the AI guesses, the user corrects, and the correction goes into the ledger. The next time pizza is logged, the AI looks up the ledger first and gets the right answer without asking. Three weeks in, a household has its own private nutrition database that knows exactly how it eats. The AI's own training is the third source of truth, not the first.
Honest list of what it cannot do yet
Photo-of-the-plate input has not shipped. Vision models identify dishes well and estimate quantity poorly. Until the image budget is measured against the AI billing, the feature stays parked behind a flag.
Barcode scanning is the next push, because barcodes are deterministic and burn no AI tokens. The browser's native BarcodeDetector API plus Open Food Facts as the lookup chain handles most packaged foods. USDA covers the rest.
Schema migrations are still hand-rolled ALTER TABLE statements on the production database. Alembic exists and is configured. It is not yet in the deploy script. That is a paper cut, not a problem, but it is an open one and worth naming.
Why household-first
The allowlist is household-only Phase 1. Anyone whose Gmail is on the list can sign in. Anyone else cannot. There is an admin page for managing the list with role badges, joined-versus-pending status, and a self-revoke guard so an admin cannot lock themselves out by accident.
A general-public version of the same tool is the easy follow-on. The hard part of the build was making the household tier work, which meant making it usable by people who do not care that there is a FastAPI behind it. The general-public version is the same code with a different allowlist policy. The household tier is the version where every design decision had to survive contact with people who would close the tab if anything took longer than ten seconds.
That is the bar to beat. So far, it does.