Wide (>=1024px): right-hand pane beside the table with a close control. Narrow: Base UI Drawer sliding from the right (lazy-loaded so its code splits out of the main chunk). Both preserve the table's query string on close. Remove the index SelectPrompt route (the table is the landing view) and delete the now-unused SelectPrompt. Make table rows keyboard-activatable (role=link, tabIndex, Enter). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Biggus Dickus
A museum collection-management system: a Rust (axum + sqlx + Postgres) API with a React + TypeScript admin SPA and optional Meilisearch-backed full-text search.
Running locally
The whole backing stack runs from one docker compose file (PostgreSQL + Meilisearch).
Prerequisites
- Docker (PostgreSQL + Meilisearch)
- Rust (stable; plus a nightly toolchain for
cargo +nightly fmt) - Node.js and
pnpm(web frontend) just— optional, for the shortcuts below
1. Start the backing services
docker compose up -d
PostgreSQL listens on localhost:5432 (database cms_dev) and Meilisearch on
localhost:7700. Give them a few seconds to become healthy on first start.
2. Configure the environment
cp .env.example .env
The defaults already match the compose services. Note SESSION_COOKIE_SECURE=false:
local development is plain HTTP, and browsers drop Secure cookies on http://localhost,
so leaving it true would make login silently fail. Set it back to true for any HTTPS
deployment.
3. Run the API server
just run # or: cargo run -p server
On startup the server connects to PostgreSQL, runs database migrations automatically,
ensures the Meilisearch index exists, and listens on http://localhost:8080. (If the
MEILI_* variables are unset, search is disabled and everything else still works.)
4. Create a login user
There is no seeded account — create one (you'll be prompted for a password, minimum 8 characters):
cargo run -p server -- create-user --email you@example.com --role admin
# non-interactive:
BOOTSTRAP_PASSWORD=changeme123 cargo run -p server -- create-user --email you@example.com --role editor
Roles are admin or editor.
5. Seed the baseline cataloguing fields (idempotent)
just seed # or: cargo run -p server -- seed
Populates the baseline Spectrum cataloguing vocabularies and field definitions. Safe to re-run — the seed is idempotent.
6. Run the web frontend
The API server serves JSON only; in development the SPA is served by Vite, which proxies
/api to :8080:
cd web
pnpm install
pnpm dev # http://localhost:5173
Open http://localhost:5173 and sign in with the user from step 4.
Single-binary alternative
To serve the built SPA and the API from one process (no Vite), build the web assets and
enable the embed-web feature:
cd web && pnpm build # outputs web/dist
cargo run -p server --features embed-web # SPA + API on http://localhost:8080
Assets are embedded at compile time, so rebuild web/dist and recompile after frontend
changes.
Running tests
Backend tests reuse the same compose services — PostgreSQL provisions a throwaway database
per test (sqlx::test) and Meilisearch tests use isolated, unique index names, so they
don't touch your dev data. With docker compose up -d running and .env in place:
just test # cargo test --workspace (reads .env via dotenv)
cd web && pnpm test # frontend tests (Vitest + MSW; no services needed)
just check runs format + lint + the Rust test suite. Run cargo test directly only if
DATABASE_URL/MEILI_URL/MEILI_MASTER_KEY are exported in your shell — the Meilisearch
tests require them; just loads them from .env for you.
