Menu sync
A serverless system that keeps a restaurant’s menu and prices the same everywhere. The owner edits one master menu in a Drive sheet; every change — new item, price update, sold-out, seasonal special — flows out to the website, the online-order platforms, and the printable PDF; any place that rejects a change gets flagged. Big changes wait for a tap; routine price syncs can flow automatically within rules the owner sets. Seven posts on the same system — one diagram at a time — with an engineering reference at the end.
-
01
A menu sync on AWS for a few dollars a month
The whole system on one page — a change intake, a planner, and a publisher, plus the four moves they share for every item and channel.
-
02
How a menu change gets made
Three lanes feed the master menu — the Drive sheet itself, a phone quick-edit lane for sold-out and small tweaks mid-service, and a supplier-price lane that parses forwarded lists into proposed prices for one-tap approval.
-
03
How a change turns into updates
The planner reads the menu, diffs each item against what each channel currently shows, checks the change against the auto-sync limits, and picks one of four moves: in sync, push, hold, flag. No model on the planner.
-
04
How an update reaches each place
Channel resolution per item, the approval gate for held changes, per-channel formatting, idempotent sends, and the four guardrails between the planner’s chosen move and the change actually landing.
-
05
How a rejected update gets fixed
Three actions on a flag: retry (resend after a fix), edit (correct the value and resend), and skip (accept the channel can’t take it, but keep it on the out-of-step report). Every action is logged.
-
06
What the menu sync costs
A few dollars a month at single-restaurant volume. The sync only does work on a change, calls no models in the planner, and only fires Bedrock on the supplier-price lane and the monthly summary.
-
07
Engineering reference: the menu sync architecture
Same system, drawn purely for engineers. Service names, resource identifiers, region, Bedrock model IDs, Lambda inventory, IAM scopes, the SES inbound rule set, EventBridge config, the channel-adapter contract, and the DynamoDB schemas.
Frequently asked questions
- What is a menu sync?
- A small serverless system that keeps a restaurant’s menu and prices the same everywhere. The owner edits one master menu in a Drive sheet; the system pushes every change — a new item, a price update, a sold-out flag, a seasonal special — out to the website, the online-order platforms, and the printable PDF. Any place that rejects an update is flagged so somebody can fix it. Big changes wait for a tap; routine price syncs flow automatically within rules the owner sets.
- How much does it cost to run?
- About $3/month at single-restaurant volume (around 120 menu items across the usual channels). The fixed cost is essentially zero. The variable cost is dominated by the work of pushing each change to each channel; Bedrock and Textract fire only on the supplier-price lane and the monthly summary, so they’re small slivers. At 2,000 items across a chain the bill lands around $15.
- Which AWS services does it use?
- Lambda (Python 3.14, arm64) with Function URLs for the quick-edit page and the Slack fix buttons, EventBridge for the change events and the scheduled audit, DynamoDB on-demand, S3 (with versioning), SES inbound + outbound, Secrets Manager, Parameter Store, CloudWatch Logs (7-day retention), AWS Budgets, and Bedrock (Claude Haiku 4.5 via Global cross-Region inference) for the supplier-price parsing and the monthly summary. No API Gateway, no NAT Gateway, no always-on compute, no Knowledge Base.
- Where does the master menu live?
- In a Google Sheet in a Drive folder. One row per item with name, description, category, price, a sold-out flag, a seasonal flag, and which channels the item publishes to. A small
menu-syncLambda mirrors the sheet to S3 on each change; the planner reads from S3 to keep Drive API calls predictable and to get S3 versioning for free. - Does the menu sync use AI?
- Sparingly. The planner uses no AI — it’s plain comparison that diffs the master menu against what each channel currently shows. Bedrock Haiku 4.5 fires only when somebody forwards a supplier price list (Textract + Haiku match each line to a menu item and propose the new price for human approval) and once a month for the owner summary. Most of the system is deterministic by design.
- What stops a bad price from going out everywhere?
- Auto-sync limits in the rules doc. Routine changes the owner has marked safe — a sold-out toggle, a small price tweak under the limit — flow automatically. Anything bigger (a large price jump, a new dish, a removed category) is held and waits for the owner’s one-tap approval before it ships. Each price push also carries an idempotency key, so a retry can never apply the same change twice.
- What happens when a channel rejects an update?
- It gets flagged, never swallowed. The owner gets a Slack card with the item, the channel, and the channel’s reason, plus three buttons: Retry resends after the channel issue is fixed; Edit corrects the value — say a price in the wrong units — and resends; Skip accepts the channel can’t take it, which stops the nagging but keeps the item on the weekly out-of-step report. Every action is recorded in the
ms-auditDynamoDB table with timestamp, item, channel, action, by-user, and a before-and-after snapshot, so changes are reversible and the trail is auditable for years.