# Biggus Dickus

![Biggus Dickus](docs/biggus-dickus.jpg)

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`](https://pnpm.io/) (web frontend)
- [`just`](https://github.com/casey/just) — optional, for the shortcuts below

### 1. Start the backing services
```bash
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
```bash
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
```bash
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):
```bash
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)
```bash
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`:
```bash
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:
```bash
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:
```bash
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.
