# Runbook

This runbook starts the cloud API, dashboard web views, and mobile web view for
manual testing.

## Ports

For the browser demo, open these TCP ports on the Vultr firewall:

- `80` - redirects to HTTPS
- `443` - HTTPS web views using the existing Let's Encrypt certificate

Keep these ports private/local only:

- `3000` - Fastify cloud API, proxied publicly at `https://www.pinball.cv/api/`
- `8081` - Expo mobile web view, proxied publicly at `https://www.pinball.cv/mobile/`
- `3306` - MySQL

## Start Services

Use two terminal sessions from the repo root. The normal nginx site serves the
landing page and dashboard HTML on port `443`.

Terminal 1:

```bash
npm run api:start
```

Terminal 2:

```bash
npm run mobile:web
```

## Open Web Views

Dashboard URLs under `/apps/web/` use HTTP Basic Auth:

```text
Username: admin
Password: apple29
```

- Landing page: [https://www.pinball.cv/](https://www.pinball.cv/)
- Runbook: [https://www.pinball.cv/runbook.php](https://www.pinball.cv/runbook.php)
- Raw runbook markdown: [https://www.pinball.cv/docs/DEMO.md](https://www.pinball.cv/docs/DEMO.md)
- Dashboard launcher: [https://www.pinball.cv/apps/web/](https://www.pinball.cv/apps/web/)
- Operator dashboard: [https://www.pinball.cv/apps/web/operator-dashboard.html](https://www.pinball.cv/apps/web/operator-dashboard.html)
- Admin dashboard: [https://www.pinball.cv/apps/web/admin-dashboard.html](https://www.pinball.cv/apps/web/admin-dashboard.html)
- Admin API Lab: [https://www.pinball.cv/apps/web/admin-console.html](https://www.pinball.cv/apps/web/admin-console.html)
- Mobile app web view: [https://www.pinball.cv/mobile/](https://www.pinball.cv/mobile/)

Each dashboard has a Cloud API base URL field. It should default to:

```text
https://www.pinball.cv/api
```

If it shows localhost from your browser, replace it manually with
`https://www.pinball.cv/api`.

The [runbook page](https://www.pinball.cv/runbook.php) also includes an embedded [Cloud API Test Console](https://www.pinball.cv/runbook.php#api-lab) with
preloaded demo values. Use that first when you want to exercise the API without
opening the standalone [Admin API Lab](https://www.pinball.cv/apps/web/admin-console.html).

Click an endpoint name in the embedded console to load its request path and
payload into the `Selected API Payload` panel. Click `Execute selected API call`
to run the loaded request. Generated claim, device, user, and score IDs are
shown in the console state readout.

## Test API Health

1. Open the [runbook page](https://www.pinball.cv/runbook.php).
2. Scroll to [Cloud API Test Console](https://www.pinball.cv/runbook.php#api-lab).
3. Confirm API base URL is `https://www.pinball.cv/api`.
4. Click `GET /health`.
5. Expected response:

```json
{
  "ok": true,
  "service": "pinballcv-api"
}
```

## Test Device Boot and QR Claim

Use either the [Operator dashboard](https://www.pinball.cv/apps/web/operator-dashboard.html) or the [Cloud API Test Console](https://www.pinball.cv/runbook.php#api-lab) embedded on
the [runbook page](https://www.pinball.cv/runbook.php).

1. Open the [Operator dashboard](https://www.pinball.cv/apps/web/operator-dashboard.html).
2. Confirm Cloud API base URL.
3. Leave the test MAC address as `b8:27:eb:12:34:56`, or enter another valid MAC.
4. Click `Boot test Pi`.
5. Expected: the Claim token field fills in.
6. Click `Claim device`.
7. Expected: Selected device ID fills in and the fleet list shows a device.

This simulates an unassigned Pi booting, receiving a QR claim token, and being
claimed by the operator profile.

## Test Operator Fleet

1. Open the [Operator dashboard](https://www.pinball.cv/apps/web/operator-dashboard.html).
2. Click `Load fleet`.
3. Click a device in the Fleet list.
4. Expected: Selected device ID updates to that device.

## Test Custom Playfield Message

1. Open the [Operator dashboard](https://www.pinball.cv/apps/web/operator-dashboard.html).
2. Select a device.
3. Edit Custom playfield message.
4. Click `Save message`.
5. Click `Load fleet`.
6. Expected: the saved message appears in the last API response and persists in
   the database.

## Test Score Submission

1. Open the [Operator dashboard](https://www.pinball.cv/apps/web/operator-dashboard.html).
2. Select a claimed device.
3. Click `Submit demo score`.
4. Expected: last API response includes `scoreId`, `localRank`, and `globalRank`.

## Test Local Leaderboard Button

1. Open the [Operator dashboard](https://www.pinball.cv/apps/web/operator-dashboard.html).
2. Select a claimed device.
3. Click `Local leaderboard`.
4. Expected: leaderboard table shows scores submitted from that selected device.

## Test Global Leaderboard Button

1. Open the [Operator dashboard](https://www.pinball.cv/apps/web/operator-dashboard.html).
2. Click `Global leaderboard`.
3. Expected: leaderboard table shows scores across all devices.

## Test Admin Users and Devices

1. Open the [Admin dashboard](https://www.pinball.cv/apps/web/admin-dashboard.html).
2. Click `Load users`.
3. Expected: operator users appear in the Users list.
4. Click a user.
5. Expected: that user's devices appear in the Devices list.
6. Click a device to select it.

## Test Admin Subscription Override

1. Open the [Admin dashboard](https://www.pinball.cv/apps/web/admin-dashboard.html).
2. Click `Load devices`.
3. Select a device.
4. Click `Set paid`.
5. Expected: selected device tier changes to `paid`.
6. Click `Set free`.
7. Expected: selected device tier changes back to `free`.

## Test Admin Username Moderation

1. Open the [Admin dashboard](https://www.pinball.cv/apps/web/admin-dashboard.html).
2. Leave Banned Stern username as `luna_spin`, or enter another username.
3. Click `Ban username`.
4. Open the [Operator dashboard](https://www.pinball.cv/apps/web/operator-dashboard.html).
5. Select a device and click `Submit demo score`.
6. Expected: score submission for the banned username fails.
7. Return to the [Admin dashboard](https://www.pinball.cv/apps/web/admin-dashboard.html) and click `Unban username` to remove the test
   ban.

## Test Every API From Runbook Page

1. Open the [runbook page](https://www.pinball.cv/runbook.php).
2. Scroll to [Cloud API Test Console](https://www.pinball.cv/runbook.php#api-lab).
3. Click `Run full demo flow`.
4. Expected: the response log shows successful calls for health, device boot,
   claim, heartbeat, score submission, local leaderboard, global leaderboard,
   operator fleet, users, user devices, subscription overrides, ban, and
   unban.
5. Click `New demo identity` before re-running the full flow if you want a fresh
   unclaimed device and operator email.

## Test Admin Delete APIs

1. Open the [runbook page](https://www.pinball.cv/runbook.php).
2. Scroll to [Cloud API Test Console](https://www.pinball.cv/runbook.php#api-lab).
3. Click `New demo identity`.
4. Click `Run full demo flow` to create a demo user and device.
5. Click `DELETE device`.
6. Expected: the response log shows `deleted: true` for the selected device.
7. Click `New demo identity`, then `Run full demo flow` again.
8. Click `DELETE user`.
9. Expected: the response log shows `deleted: true` and `releasedDevices` for
   the selected demo user.

## Test Mobile App Web View

1. Open the [Mobile app web view](https://www.pinball.cv/mobile/).
2. Confirm Cloud API base URL is `https://www.pinball.cv/api`; edit it if needed.
3. On the Claim tab, click `Boot test Pi`.
4. Click `Claim device`.
5. Go to Fleet and click `Refresh fleet`.
6. Go to Scores.
7. Click `Submit demo score`.
8. Click `Local leaderboard`.
9. Click `Global leaderboard`.

On a real phone running the Expo app, use the camera scanner instead of pasting
the claim token. In web view, use the token field because browser camera support
for Expo Camera is limited.
