01 / 05
THE SYSTEM
The system maintains a Charlotte-only catalog.
Restaurant specials are scattered across web pages, menus, PDFs, images, and social posts. Charlotte Specials checks those sources ahead of time, maintains an approved Charlotte-only catalog, and serves that catalog to people without waiting on a model.
- Restaurant content and user reports enter as source material. The catalog contains the approved listings served by the website.
- The operating target is practical: dozens of restaurants and 100+ specials for less than $20 per month and about two hours of owner attention per week.
Restaurant sourcesweb · PDF · image↓Fetch + fingerprintnormalize · SHA-256↓Typed candidatesschema · schedule · location↓Apply or reviewpublish · stage↓Approved catalogPostgreSQL↓Charlotte Specials website↓Feedback intakereport · photo · suggestion
02 / 05
OBSERVE
Sources are checked for changes before extraction.
Scheduled jobs discover likely specials pages and revisit known sources. The system normalizes HTML and extracted PDF text, removes unstable boilerplate, and computes a SHA-256 checksum. Unchanged content can stop here.
- GitHub Actions triggers source discovery, staged curation, feedback triage, backups, and proactive audits. Vercel Cron queues recurring parsing work.
- URL ranking, content fingerprints, due-date checks, retries, and queueing are deterministic operations.
Restaurant sourcesweb · PDF · image↓Scheduled workflowsGitHub Actions · Cron↓Fetch + fingerprintnormalize · SHA-256
03 / 05
INTERPRET
Structured and unstructured sources follow different extraction paths.
Structured menu data can be read directly. Prose, PDFs, screenshots, and photos are harder, so an LLM or OCR step extracts the useful fields. Both paths produce the same typed candidate shape for the rest of the application.
- JSON-LD and deterministic rules bypass the model when they are sufficient.
- Model output is constrained to candidate titles, descriptions, schedules, locations, types, and confidence signals. It does not receive authority to write arbitrary data.
Structured extractionJSON-LD · rules↓LLM / OCR extractiontext · PDF · image↓Typed candidatesschema · schedule · location
04 / 05
DECIDE
Candidate changes are compared with the approved catalog.
A changed checksum may represent new information, harmless rewording, an old menu, a duplicate, the wrong location, or a bad extraction. Candidates are validated and compared with the approved catalog before the system applies a change or preserves it as a pending diff for review.
- Schema checks, schedule rules, deduplication, location matching, prior catalog state, and confidence all contribute to the routing decision.
- Review mode writes a ParseDiff. I can inspect the source and proposed change, then approve, edit, or reject it without re-running extraction.
Typed candidatesschema · schedule · location↓Apply or reviewpublish · stage↓Operator reviewapprove · edit · reject↓Approved catalogPostgreSQL
05 / 05
SERVE + CORRECT
The website serves approved records and returns feedback to the maintenance loop.
The public website reads cached, approved catalog data and never waits on an LLM. Feedback is stored as untrusted input and routed separately. A report can queue a review-mode source check; a photo can be interpreted into candidates, but the resulting changes are still staged before approval.
- Feedback routing is deterministic. Reports and photos can produce candidate changes, but they do not publish records directly.
- Parse jobs, diffs, feedback routes, run records, and change logs record what ran and where review entered the loop.
Approved catalogPostgreSQL↓Charlotte Specials website↓Feedback intakereport · photo · suggestion↓Operator reviewapprove · edit · reject