Skip to content

Repository files navigation

Barback

Home-bar pantry app: inventory shelf, "what can I make tonight," shopping-list gap analysis, recipe index. The product thesis is templates, not recipes.

Barback is a client. The backend is an unmodified, version-pinned Bar Assistant instance — see ADR-001. The visual identity is The Back Bar design system — docs/design/the-back-bar.md, tokens in docs/design/tokens.css.

Architecture

Decisions live in docs/adr/:

ADR Decision
001 Bar Assistant as pinned upstream appliance; never forked
002 Family taxonomy as API tags; ratio templates as typed client data
003 Vite + Preact + TypeScript strict SPA, TanStack Query
004 Search direct to Meilisearch with scoped keys
005 One compose stack; single-origin reverse proxy as end state
006 Design system consumed as an unmodified vendored delivery via @ds alias
007 Installable PWA; shell-cache worker + list snapshot; API never cached; sync deferred
008 Staples are standing orders (auto-queue); app suggestions require a tap; aspiration outranks server rank

Running the stack

cp deploy/.env.example deploy/.env   # then set MEILI_MASTER_KEY (openssl rand -base64 32)
pnpm install && pnpm build:deploy    # the web container serves dist/ (ADR-005)
ALLOW_REGISTRATION=true docker compose -f deploy/docker-compose.yml up -d
./scripts/seed.sh                    # creates your user while registration is open
docker compose -f deploy/docker-compose.yml up -d   # re-up: registration closes
python3 scripts/tag_families.py      # family:* tags + assignments (idempotent)

Family curation lives in scripts/family-assignments.json (normalized slugs → family tag); edit it and re-run the script. Par-level staples (bottles the bar should never run out of) are curated in src/data/staples.ts by canonical ingredient slug — the file is a standing order: a staple that leaves the shelf is queued to the shopping list automatically, with a toast and a "staple" note on the row. The First pours roster (onboarding classics; each pick favorites the drink and queues its missing bottles) lives in src/data/first-pours.ts. A minimal shell-cache service worker plus a stamped localStorage snapshot keep the shopping list readable away from the LAN (the store aisle); the API itself is never cached. For the uncurated backlog, python3 scripts/propose_families.py drafts structural proposals with reasons to scripts/family-proposals.json — review, move keepers into the assignments file, rerun the tag script.

  • App (single-origin front door): http://localhost:8080 — proxies /bar/ → API, /search/ → Meilisearch; set BARBACK_ORIGIN in deploy/.env for LAN access
  • API direct: http://localhost:8000 (OpenAPI docs at /docs)
  • Salt Rim (upstream admin/reference UI): http://localhost:3000
  • Local dev credentials seeded by the script: admin@example.com / password

Vintage imports

Public-domain books live as transcribed batches in scripts/vintage/ (Thomas 1862, Winter 1884 — period measures modernized, substitutions noted per-ingredient). Imports are idempotent (duplicates skipped by name) and each maintains a per-book collection:

python3 scripts/import_vintage.py scripts/vintage/thomas-1862.json

Client development

pnpm install
pnpm dev

A note before exposing this to the internet

The compose stack is tuned for a home LAN: the :8080 front door is the only port the network sees (API, Meilisearch and Salt Rim bind to loopback), registration is closed outside first boot, and login is the only write gate — but nothing terminates TLS. That is the right posture behind your router and still the wrong one on a public host. If you must expose it, change the seeded password first, and put real TLS and an auth proxy in front.

Built on

Barback is a client; the heavy lifting is upstream open source, consumed as pinned Docker images (ADR-001) and gratefully acknowledged:

  • Bar Assistant (MIT, Karlo Mikuš) — inventory, matching and recipe engine
  • Salt Rim (MIT, Karlo Mikuš) — upstream web client, kept alongside as the admin/reference UI
  • Meilisearch (MIT) — search
  • Preact + preact-iso, TanStack Query, Vite, TypeScript — the client stack
  • Libre Caslon Display & Text (SIL OFL) — the system's two voices
  • Jerry Thomas' How to Mix Drinks (1862) and George Winter's How to Mix Drinks — Bar Keepers' Handbook (1884) — public-domain sources for the vintage imports

Barback itself is MIT licensed.

About

Self-hosted home-bar pantry: the shelf, what pours tonight, and a shopping list ranked by what it unlocks. A Bar Assistant client with an 1885 ledger face.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages