Files
sustenance/README.md
T
2026-08-01 21:24:48 -04:00

2.9 KiB

Sustenance

A small shared grocery list built with Rust, Axum, Maud, htmx, WebSockets, and SQLite.

Run locally

cargo run

Open http://127.0.0.1:3000. The application creates sustenance.db in the working directory on first start.

Configuration

Variable Default Purpose
DATABASE_PATH sustenance.db SQLite database path
BIND_ADDRESS 127.0.0.1:3000 Listen address
PUBLIC_BASE_URL derived from BIND_ADDRESS Base URL used in invitation links
COOKIE_SECURE false Add the Secure attribute to session cookies
REGISTRATION_MODE invite_only Use open for local development; otherwise registration requires a valid list invitation after the first account
SEED_CONFIG seed.json Optional JSON file with a default user to create when the database is first initialized
RUST_LOG sustenance=debug,tower_http=info Log filter

Seeding a default user

If a JSON config file exists at the path given by SEED_CONFIG (default seed.json), Sustenance creates the configured user on startup when the database has no users yet. The file is optional — if it is missing or invalid, seeding is silently skipped.

{
  "user": {
    "email": "you@example.com",
    "display_name": "You",
    "password": "a-strong-password"
  }
}

Current features

  • Email/password accounts with Argon2 password hashes
  • Cookie-backed sessions and CSRF tokens for list mutations
  • Shared lists with one-time, seven-day invitation links
  • Invite-only registration by default after the first account
  • Add, edit, check, and delete grocery items
  • Global categories with common defaults seeded at startup and custom category creation
  • Items grouped by category and assigned from the add/edit forms
  • Meals with ingredients, markdown descriptions, and one-click "add meal to list"
  • Server-authoritative last-write-wins updates
  • Per-list WebSocket updates with server-rendered htmx fragments
  • In-memory presence for members currently viewing a list
  • Responsive layout for phone, tablet, and desktop

The htmx scripts are currently loaded from unpkg. They can be vendored into static/ before production deployment.

Verification

cargo fmt --all -- --check
cargo check
cargo test

End-to-end tests (Playwright)

The e2e tests live in e2e/ and use Playwright with a real browser. Each test starts its own server against a fresh, throwaway database on a unique port, so tests are fully isolated from each other and from your real sustenance.db.

# one-time setup
cd e2e
npm install
npx playwright install chromium

# run the tests (builds the server automatically via globalSetup)
cd e2e
npx playwright test

The Playwright globalSetup runs cargo build before the suite, and each test launches its own server against a fresh database, so no manual build or server start is required.