R1: Migration 0010 now writes revision 0 into every ground_dinner job payload that has none. Jobs queued before the upgrade carry only dinner_id, so the boot cleanup, which matches a pending dinner to its job by revision, failed those dinners as interrupted while their jobs were still queued. The migration runs before the job runner starts. A new test migrates a database to 0009, adds a pending Regular with a legacy queued job, upgrades and boots, and checks the dinner stays pending and is then grounded. R2: Archiving a dinner, or renaming a pending one, now cancels the grounding of any ground_dinner job running for it at an older revision, so no further search, page fetch, photo download or model call is made. The job is registered before it reads the dinner, so an archive or rename committed after that read always finds it. A stopped job succeeds and reports the dinner's current grounding status. The archive and rename tests now check that the job ends while its search is still held, with no page fetched and no model call for the stale name. R3: gen_folds.py writes web/src/dinners/letterFolds.json from the same table as folds_table.go, and names.ts folds through it instead of a hand-copied subset. names.ts also lowercases letter by letter, as Go's strings.ToLower does, rather than by context. TestLetterFoldsMatchPWA fails when the two tables differ. The shared cases add "Ƈhili", "Ꞔarbanzo Stew" and "ΜΟΥΣΑΚΑΣ" (final sigma). Maestro task 5037ff86-181d-448e-927b-c2fd2258a25d. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MealQuest
MealQuest is a mobile-first Progressive Web App for weekly dinner planning for one household. The household lists the dinners it makes regularly, an AI assistant suggests new dinners to try (swipe "Try it" or "Pass"), and the app builds a weekly plan, pushes it to Google Calendar, and generates a shopping list grouped by dinner, kept as a browsable weekly history. It ships as a single Go service with the React PWA embedded in the binary.
Status: this repository is the Feature 01 scaffold (Go service with
/health, embedded PWA skeleton, Makefile, Dockerfile, CI). The planned application is described in docs/ARCHITECTURE.md.
Quick start
Requirements: Go 1.25 and Node.js ^22.22.2 || ^24.15.0 || >=26.0.0 — that
is, 22.22.2 or later on the 22 line, 24.15.0 or later on the 24 line, or 26.0.0
or later. Node.js 23, 24.0–24.14 and 25 are not supported: this is the
engines range of jsdom in the committed lockfile, the strictest of all the
web dependencies.
(cd web && npm ci)
mkdir -p ~/.mealquest-dev # outside the repository: it holds a secret
chmod 700 ~/.mealquest-dev
head -c 32 /dev/urandom | base64 > ~/.mealquest-dev/secret_key
chmod 600 ~/.mealquest-dev/secret_key
export MEALQUEST_HTTP_ADDR=:8080
export MEALQUEST_PUBLIC_URL=http://localhost:5173
export MEALQUEST_DATA_DIR="$HOME/.mealquest-dev"
export MEALQUEST_SHUTDOWN_TIMEOUT=10s
export MEALQUEST_SECRET_KEY_FILE="$HOME/.mealquest-dev/secret_key"
# Authentik OAuth2/OpenID provider for MealQuest (redirect URI:
# $MEALQUEST_PUBLIC_URL/auth/callback). Save its client secret to the file.
export MEALQUEST_OIDC_ISSUER=https://auth.example.com/application/o/mealquest/
export MEALQUEST_OIDC_CLIENT_ID=mealquest
export MEALQUEST_OIDC_CLIENT_SECRET_FILE="$HOME/.mealquest-dev/oidc_client_secret"
export MEALQUEST_OIDC_ALLOWED_GROUPS=mealquest-admin
# Optional: sessions end after MEALQUEST_SESSION_IDLE unused (default 720h)
# and always MEALQUEST_SESSION_MAX after sign-in (default 4320h).
# export MEALQUEST_SESSION_IDLE=720h
# export MEALQUEST_SESSION_MAX=4320h
# Optional: comma-separated IPs/CIDRs of reverse proxies whose
# X-Forwarded-For/-Proto headers are honoured (production: Traefik). Unset
# trusts no peer, which is right for local development.
# export MEALQUEST_TRUSTED_PROXY=10.60.1.33
# Optional: a SearXNG instance the Settings screen suggests as the recipe
# search URL until one is saved.
# export MEALQUEST_SEARXNG_URL=http://localhost:8888
export MEALQUEST_DEFAULT_TZ=America/New_York
make dev
make dev runs the Go server on :8080 and the Vite dev server on :5173
(which proxies /api, /auth and /media to :8080). Open
http://localhost:5173. Configuration is environment-only and fails fast:
every variable above is required except the commented-out session
lifetimes (when set they must be positive, with MAX at least IDLE),
trusted proxy list (every entry must be an IP or CIDR), the SearXNG URL
(an absolute http:// or https:// URL without credentials, a query or a
fragment) and MEALQUEST_DEFAULT_TZ, and
secrets are read only from files named by *_FILE variables. MEALQUEST_PUBLIC_URL, MEALQUEST_OIDC_ISSUER and the
endpoints the issuer advertises must be https://; plain http:// is
accepted only for localhost, 127.0.0.1 and [::1].
MEALQUEST_DEFAULT_TZ is the IANA zone the household settings are created
with on first boot: until those settings exist, boot fails unless it is a
valid IANA zone. Later boots ignore it, set or not (change the zone in
household settings instead).
Common commands
| Command | What it does |
|---|---|
make dev |
Go server plus Vite dev server. |
make test |
gofmt check, go vet, go test -race, web typecheck and tests. |
make build |
Build the PWA, embed it, build the static binary bin/mealquest. |
make docker |
Build the container image from the root Dockerfile. |
Where to read next
- AGENTS.md — house rules, approved dependencies, conventions.
- docs/ARCHITECTURE.md — architecture of record.
- design/MealQuest Requirements.md — product requirements.
- design/MealQuest UI Designs/design_handoff_mealquest/README.md — UI handoff.