> ## Documentation Index
> Fetch the complete documentation index at: https://docs.malbox.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Dev environment

> Set up a local Malbox development environment with Nix

## Prerequisites

Before you begin, make sure you have the following installed:

* **Git** - to clone the repository
* **Nix** - Malbox uses a [Nix flake](https://nixos.wiki/wiki/Flakes) for reproducible development environments. Install Nix with flakes enabled via the [Determinate Systems installer](https://zero-to-nix.com/start/install) or the [official installer](https://nixos.org/download/)
* A **Linux host** (or WSL2 on Windows)

## Clone and enter the environment

```bash theme={null}
git clone https://github.com/MalboxSandbox/malbox.git
cd malbox
```

Start the development environment:

```bash theme={null}
nix develop
```

This automatically sets up:

* Rust stable toolchain (rustc, cargo, clippy, rustfmt, rust-analyzer)
* PostgreSQL 16
* Node.js and pnpm
* C/C++ build tools (cmake, gcc, clang 18)
* Windows cross-compilation toolchain (MinGW)
* Infrastructure tools (packer, ansible)
* Protobuf compiler and codegen tools
* Pre-commit hooks (cargo-check, clippy, rustfmt)

<Note>
  The first run takes a while as Nix downloads and builds all dependencies. Subsequent runs are near-instant.
</Note>

The flake also provides specialized sub-shells if you only need a subset of tools:

```bash theme={null}
nix develop .#backend   # Rust toolchain, PostgreSQL, build tools
nix develop .#frontend  # Node.js, pnpm
nix develop .#docs      # Node.js (for Mintlify)
```

Each subdirectory (`back-end/`, `front-end/`, `docs/`) includes an `.envrc` file that activates the appropriate sub-shell automatically. If you use [direnv](https://direnv.net/), just `cd` into the directory you want to work in.

## Database

process-compose manages PostgreSQL 16. Start it from the `back-end/` directory:

```bash theme={null}
cd back-end
process-compose up
```

This initializes the data directory, starts PostgreSQL, and creates the `malbox_db` database automatically.

The `DATABASE_URL` environment variable is set for you automatically by the flake:

| Setting       | Value                                          |
| ------------- | ---------------------------------------------- |
| Host          | `127.0.0.1`                                    |
| Port          | `5432`                                         |
| Database      | `malbox_db`                                    |
| User          | `postgres`                                     |
| DATABASE\_URL | `postgres://postgres@localhost:5432/malbox_db` |

To run pending database migrations:

```bash theme={null}
cd back-end
sqlx migrate run
```

## Running the backend

Make sure PostgreSQL is running via `process-compose up` first (see [Database](#database)), then from the `back-end/` directory:

```bash theme={null}
cd back-end
cargo run -p malbox -- daemon start
```

The daemon starts an HTTP server on `http://127.0.0.1:8080`.

## Running the frontend

In a separate terminal:

```bash theme={null}
cd front-end
cp .env.example .env
pnpm install
pnpm dev
```

The dev server starts at `http://localhost:5173`. It proxies API requests to the backend at the URL configured in `.env`:

```bash theme={null}
# .env
MALBOX_API_URL=http://127.0.0.1:8080
BODY_SIZE_LIMIT=0
```

## Running the docs

In a separate terminal:

```bash theme={null}
cd docs
npx mintlify@latest dev
```

The docs site starts at `http://localhost:3000`.

## Daily workflow

### Running tests

```bash theme={null}
# Run the test suite (uses cargo-nextest)
cd back-end
cargo nextest run

# Run doctests separately (nextest doesn't support them)
cargo test --doc
```

### Formatting and linting

Pre-commit hooks run cargo-check, clippy, and rustfmt automatically on every commit. You can also run them manually:

```bash theme={null}
# Backend
cd back-end
cargo fmt
cargo clippy

# Frontend
cd front-end
pnpm lint
pnpm format
```

### Type checking the frontend

```bash theme={null}
cd front-end
pnpm check          # one-off
pnpm check:watch    # continuous
```

### Database migrations

Create a new migration:

```bash theme={null}
cd back-end
sqlx migrate add <migration_name>
```

This creates a new SQL file in the migrations directory. After writing your migration, run it:

```bash theme={null}
sqlx migrate run
```

After changing queries, update the offline query cache so CI builds work without a live database:

```bash theme={null}
cargo sqlx prepare
```

### Building Rust documentation

```bash theme={null}
cd back-end
cargo doc --no-deps --document-private-items
```

## Pre-commit hooks

The Nix flake installs Git hooks that run on every commit:

* **cargo-check** - verifies the project compiles
* **clippy** - catches common mistakes and style issues
* **rustfmt** - enforces consistent formatting

Do not skip these hooks with `--no-verify`. If a hook fails, fix the issue before committing.

## Troubleshooting

### `nix develop` fails or hangs

Make sure Nix is installed correctly and the Nix daemon is running:

```bash theme={null}
nix --version
```

If you see errors about missing flake inputs, try:

```bash theme={null}
nix flake update
```

### Database connection refused

PostgreSQL may not be running. Check its status:

```bash theme={null}
pg_isready -h 127.0.0.1 -p 5432
```

If it reports no connection, make sure `process-compose up` is running in the `back-end/` directory (see [Database](#database)).

### SQLx compile errors about missing queries in CI

If you see SQLx compile-time errors, make sure the offline query cache is up to date:

```bash theme={null}
cd back-end
cargo sqlx prepare
```

For CI or when you don't have a running database, set `SQLX_OFFLINE=true`:

```bash theme={null}
SQLX_OFFLINE=true cargo build
```

### Frontend can't reach the backend

Make sure:

1. PostgreSQL is running (`process-compose up` in `back-end/`)
2. The backend is running (`cargo run -p malbox -- daemon start`)
3. Your `.env` file has the correct `MALBOX_API_URL` (default: `http://127.0.0.1:8080`)
