The 'narrow: detail renders inside a portaled drawer' test lazy-loads the drawer chunk and exceeded the 5s default on the slow CI container (setup alone took ~486s). Bump testTimeout on both vitest projects. 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.
