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

# Environment Setup

> Configure your development environment for the mobile app, web app, API, and infrastructure.

This guide walks you through configuring your development environment for each Soundcheck component.

## Mobile App Environment

### Environment Variables

Create a `.env` file in the repository root:

```bash theme={null}
cp .env.example .env
```

Required variables:

```env theme={null}
# Required
EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_...

# Optional - defaults to local api-events
EXPO_PUBLIC_API_URL=http://localhost:4000
```

### Expo Configuration

The mobile app uses `app.config.js` for configuration:

| Setting | Value |
| - | - |
| Bundle ID | `com.soundchecklive.app` |
| Scheme | `soundcheck` |
| Splash / icon background | `#9b87f5` |

> [!NOTE]
>
> Stack: Expo SDK 57, React Native 0.86, React 19, Expo Router. In-app UI styling is NativeWind v4
> (the brand primary is now an indigo token, not the `#9b87f5` purple above — see [Mobile
> Architecture](https://docs.soundchecklive.io/engineering/mobile/architecture.md)).

### Physical device on a different VLAN

If a connected Android device can't reach the Expo dev server over LAN, tunnel Metro (keep the subdomain to letters, numbers, and hyphens — Android rejects underscores in TLS hostnames):

```bash theme={null}
EXPO_TUNNEL_SUBDOMAIN=soundcheck-mobile-8083 npx expo start --dev-client --clear --tunnel --port 8083
```

To load the JS bundle in Expo Go instead of the custom development client or TestFlight app, start with `--go` (same Wi-Fi, then scan the QR from Expo Go):

```bash theme={null}
npx expo start --go
```

`npm run start:go` is the same command. A start without `--go` still uses the `soundcheck` scheme and can open TestFlight or the installed dev client.

### Native Project Generation

The `ios/` and `android/` directories are **gitignored** and generated from `app.config.js`:

```bash theme={null}
# Generate iOS native project (macOS only)
npx expo prebuild --platform ios --clean

# Generate Android native project
npx expo prebuild --platform android --clean

# Generate both platforms
npx expo prebuild --clean
```

> [!WARNING]
>
> Never commit changes to `ios/` or `android/` directories. They are ephemeral build artifacts.

***

## Web App Environment

### Environment Variables

Create a `.env.local` file in the `web/` directory:

```bash theme={null}
cd web
cp .env.example .env.local
```

Required variables:

```env theme={null}
# Authentication (Required)
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_...
CLERK_SECRET_KEY=sk_test_...

# API (Required — local dev proxy avoids CORS issues)
NEXT_PUBLIC_API_URL=/api-proxy/api/v1
BACKEND_API_URL=http://localhost:4000

# Optional
NEXT_PUBLIC_GOOGLE_MAPS_API_KEY=...
NEXT_PUBLIC_GTM_ID=...
```

> [!WARNING]
>
> The `/api-proxy` rewrite (defined in `web/next.config.mjs`) is **dev-only** — it returns no
> rewrites unless `NODE_ENV === "development"`, forwarding `/api-proxy/*` to `BACKEND_API_URL`. A
> production build cannot use it; point `NEXT_PUBLIC_API_URL` at the real API origin there.
> `NEXT_PUBLIC_*` vars are baked in at compile time, so clear `.next/` after changing them.

### Development Server

```bash theme={null}
cd web
npm install
npm run dev
```

The web app runs at [http://localhost:3000](http://localhost:3000). `npm run dev` runs a `predev` hook that regenerates the typed API client from the OpenAPI spec (`web/src/lib/generated/api-client/`, gitignored).

***

## Shared infrastructure & api-events

**api-events** (Encore.ts on `:4000`) is the **system of record** — HTTP API, DDL, direct Pub/Sub publication, and notification fan-out. Local Postgres, fake-gcs-server (app file storage), and the Clerk emulator come from shared compose:

```bash theme={null}
npm run dev:infra   # repo root — Postgres :5433, clerk :4711, fake-gcs :4443
```

### Database migrations & seed

Canonical schema + migrations: `api-events/src/db/`. Migrations apply on api-events boot; explicit apply:

```bash theme={null}
cd api-events
export DATABASE_URL='postgresql://postgres:postgres@localhost:5433/soundcheck?schema=public'
npm run db:migrate
npm run db:seed:baseline      # roles, positions, plans
npm run db:seed:demo-full     # demo org + Clerk personas (recommended for web)
```

(Via MCP: `db_migrate` then `db_seed` with `mode=demo-full`.)

### Run api-events locally

Requires the Encore CLI (installed in the devcontainer).

```bash theme={null}
cd api-events
npm install
export DATABASE_URL='postgresql://postgres:postgres@localhost:5433/soundcheck?schema=public'
export GCS_BUCKET=app-files
export GCS_EMULATOR_HOST=http://127.0.0.1:4443
export QB_USE_STUB=true
npm run dev:emulator          # Encore :4000 + Clerk emulator wiring
# or: encore run --port=4000
npm run checks                # typecheck + lint + format:check + test
```

OpenAPI contract checks: `npm run openapi:emit`, `npm run openapi:parity` (TS self-check — not `schema:parity`).

### Access Points

| Service | URL |
| - | - |
| api-events | [http://localhost:4000](http://localhost:4000) |
| Health | [http://localhost:4000/health](http://localhost:4000/health) |
| Clerk emulator | [http://localhost:4711](http://localhost:4711) |
| Database | localhost:5433 |

### Multi-user event chat demo

With shared infrastructure, api-events, and the `demo-full` personas ready,
start the Next.js console with `cd web && npm run dev:emulator`. This enables
event chats unless explicitly overridden and selects the server-backed chat
transport on `:4013`. Open a seeded gig's **Chats** tab, then click
**Open another demo user** to sign in as another persona. Select **Seed Demo Band**
in each session if its personal workspace is active.

Every click opens a fresh `demo-<random-id>.localhost` origin on this web
server’s port. The launcher supplies that port even when the current page uses
a named portless URL, so demo tabs reach the same worktree. Separate
hostnames isolate Clerk sessions, workspace selection, browser storage, and
sign-out while sharing the API and chat history. Ordinary tabs on the same
hostname share auth; changing only the port or a query parameter does not
isolate cookies. The launcher and additional Next development origins are
enabled only for explicit local Clerk-emulator development.

The chat adapter polls messages, typing, and unread counts once per second;
chat-list discovery and metadata refresh every three seconds, including
background tabs. Compose retains provider history in `twilio_emulator_data`.
No carrier SMS is sent by this in-app demo, and the emulator does not implement
the proprietary Twilio SDK WebSocket protocol. Production continues to use
the real SDK. See [local provider emulators](https://docs.soundchecklive.io/engineering/backend/api-events-operations.md#local-provider-emulators)
for provider setup and the emulator README for failure injection and webhook retries.

![Blake Admin and Avery Owner exchanging messages through independently signed-in local demo sessions](https://mintcdn.com/soundchecklive/hbVkejHvwwxEyb3r/images/engineering/chat-emulator-multi-user.jpg?fit=max\&auto=format\&n=hbVkejHvwwxEyb3r\&q=85\&s=5bf33b8e9161473e1199e0b3e6a858ad)

***

## MCP (api-events `/mcp`)

Streamable HTTP MCP is hosted on **api-events** (`http://localhost:4000/mcp`). `mcp-ts/` is the `@soundcheck/mcp` SDK, not a standalone listener.

```bash theme={null}
npm run dev:infra
cd api-events && npm run dev:emulator
curl -i http://localhost:4000/.well-known/oauth-protected-resource
```

***

## CheckAI (eve agent)

`checkai/` is the AI agent, built on Vercel's **eve** framework. It requires **Node 24**.

```bash theme={null}
cd checkai
nvm use 24
npm i
cp .env.example .env            # set API_BASE_URL, CLERK_SECRET_KEY, DEFAULT_CLERK_JWT
npm run dev                     # eve dev — local server + TUI chat
npm run checks                  # typecheck + lint + format:check
```

***

## Fresh worktree / clean checkout

Several build inputs are **gitignored generated artifacts**. A clean checkout must regenerate them before builds pass. In a `git worktree`, run `npm run worktree:setup` from the worktree root: it installs each package for real and generates the clients. Do not symlink them from the main checkout, because install and codegen hooks write through the links.

| Artifact | Regenerate |
| - | - |
| `node_modules` (each package) | `npm install` per package |
| api-events Prisma client | `cd api-events && npm run prisma:generate` |
| Web typed API client (`web/src/lib/generated/api-client/`) | `npm run generate:api-client` (auto via `predev`/`prebuild`) |
| Native `ios/` `android/` | `npx expo prebuild --clean` |

See [Pitfalls](https://docs.soundchecklive.io/engineering/reference/pitfalls.md) for the worktree-artifacts gotcha in more detail.

***

## Infrastructure Environment

### Azure Authentication

```bash theme={null}
az login
az account set --subscription "your-subscription-name"
```

### Terraform Initialization

```bash theme={null}
cd infra/environments/dev
terraform init
```

### VPN Configuration

For accessing protected resources in dev environment:

1. Download Azure VPN Client
2. Import `azurevpnconfig.xml` from 1Password
3. Connect using Azure AD authentication

***

## Shared Configuration

### Git Configuration

Ensure your Git is configured with your identity:

```bash theme={null}
git config --global user.name "Your Name"
git config --global user.email "your.email@soundchecklive.com"
```

### SSH Keys

Generate an SSH key for GitHub access:

```bash theme={null}
ssh-keygen -t ed25519 -C "your.email@soundchecklive.com"
```

Add the public key to your GitHub account.

### Editor Setup

#### VS Code / Cursor

Recommended extensions:

* TypeScript and JavaScript Language Features
* Oxc / oxlint
* Expo Tools
* Tailwind CSS IntelliSense
* Go (for api-events / web TypeScript work, Node tooling is sufficient)

The repository includes `.vscode/` settings for consistent configuration.

***

## Verification

### Mobile App

```bash theme={null}
npm install
npm run type-check  # Should pass with no errors
npm start          # Should start Expo dev server
```

### Web App

```bash theme={null}
cd web
npm install
npm run typecheck  # Should pass with no errors
npm run dev        # Should start at localhost:3000
```

### api-events

```bash theme={null}
npm run dev:infra
cd api-events && npm run db:migrate && npm run dev:emulator
curl http://localhost:4000/health
```

***

## Troubleshooting

### Common Issues

> [accordion] npm install fails with permission errors
>
> Clear the npm cache and try again:
>
> ```bash theme={null}
> npm cache clean --force
> rm -rf node_modules package-lock.json
> npm install
> ```

> [accordion] Docker containers won't start
>
> Ensure Docker Desktop is running, then restart the containers while preserving the database and chat-history volumes:
>
> ```bash theme={null}
> docker compose -p api -f dev/docker-compose.yml down
> npm run dev:infra
> ```

> [accordion] Clerk authentication fails
>
> Verify your environment variables are set correctly:
>
> * Mobile: `EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY` in `.env`
> * Web: Both `NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY` and `CLERK_SECRET_KEY` in `.env.local`
> * api-events: Clerk secrets via `npm run dev:emulator` or env; local emulator on `:4711` after `npm run dev:infra`

> [accordion] First local user gets 404 / has no org
>
> Clerk delivers user and org data via webhooks; locally, prefer the **Clerk emulator** + `db:seed:demo-full`:
>
> ```bash theme={null}
> npm run dev:infra
> cd api-events
> export DATABASE_URL='postgresql://postgres:postgres@localhost:5433/soundcheck?schema=public'
> npm run db:seed:demo-full
> npm run dev:emulator
> cd ../web && npm run dev:emulator
> ```
>
> Sign-in lists demo personas for one-click auth.

***

## Next Steps

> [card] [Engineering Overview](https://docs.soundchecklive.io/engineering/index.md)
>
> Architecture, services, and dev workflows

> [card] [Troubleshooting](https://docs.soundchecklive.io/reference/troubleshooting.md)
>
> Common issues and solutions


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.