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

# Build and test

> Every command, what passes today, and which failures are expected.

## Commands

```bash theme={null}
npm run dev                       # Vite dev server, port 8080
npm run build                     # production build, ~10s
npm test                          # vitest

cd contracts && forge test        # ~96 unit + invariant, 25 fork
cd contracts && forge build --quiet

npx supabase test db              # pgTAP — needs Docker
```

## What passes

| Suite                  | State                                          |
| ---------------------- | ---------------------------------------------- |
| `npm test`             | \~287 passing at last green                    |
| `forge test`           | Passing                                        |
| `npm run build`        | Passing, with pre-existing chunk-size warnings |
| `npx supabase test db` | **Broken** — see below                         |

Two tests are flaky in the full suite and pass in isolation: `App.test.tsx` and `LandingFooter`. Ignore them as full-suite drift; do not chase them as regressions.

Expect chunk-size warnings from the build. They are pre-existing and are not what the bundle budget check guards.

## Traps

<Danger>
  **`forge test` rewrites `contracts/deployments.json`** because `Deploy.t.sol` writes fixtures into it. Always run `git checkout -- contracts/deployments.json` afterwards. CI fails if it is dirty, and a polluted copy breaks the shared contracts module and `/verify` at runtime.
</Danger>

<Warning>
  **Migration tooling is broken.** `supabase db reset` and `npx supabase test db` do not work: migration `20260529090000` references `public.rate_limits` before any migration creates it. Two duplicate version timestamps were fixed, but that was only the first blocker.

  Production tracks 86 migrations and does not record the local colliding versions, so **the repository is not the source of truth for the production schema.**
</Warning>

The consequence: the pgTAP test `supabase/tests/quotes_anon_write_lockout.sql` cannot run until this is repaired.

Docker is required for pgTAP. OrbStack provides it at `/usr/local/bin/docker`; there is no `docker` on the default PATH.

## Guards that fail CI

| Guard                                     | Catches                                                            |
| ----------------------------------------- | ------------------------------------------------------------------ |
| `scripts/check-bundle-budget.mjs`         | `wallet-vendor` becoming statically reachable from the entry chunk |
| `src/lib/__tests__/feeDisclosure.test.ts` | Published fee copy drifting from the actual split                  |
| deployments.json dirty check              | A `forge test` run left uncommitted                                |

<Danger>
  Do not resolve a build error by re-adding a static import of `@/config/appkit`. That single import is what put 5.0 MB into the entry chunk and produced a 4,908 ms first paint on every route.
</Danger>

## CI

`.github/workflows/ci.yml`.

<Warning>
  Before 2026-07-28 there was **no CI at all**, and `core.hooksPath` pointed at another user's home directory — so nothing gated the auto-deploying `main` branch. If hooks appear not to run, check `core.hooksPath` first.
</Warning>

## Testing conventions

Red-test commit **before** green-implementation commit, as separate commits. Never `--no-verify`. Never amend after a hook failure — investigate it.

Any change to address derivation must re-run the full fork and invariant suite and verify a real deploy-and-sweep on Base Sepolia. Fork tests skip silently without their environment variables, so a green local run does not prove they ran.

Any change to the fee split needs a regression test asserting the partner's 0.25% is computed on gross and unaffected. Partner earnings display \$0.00 in the dashboard, so a regression there is invisible.

## Verifying against production

```bash theme={null}
JWT=$(ROLE=merchant node scripts/mint-siwe-jwt.mjs 2>/dev/null)
ANON=$(grep '^VITE_SUPABASE_PUBLISHABLE_KEY=' .env | cut -d= -f2-)
curl -sS "$VITE_SUPABASE_URL/rest/v1/paid_events?select=tx_hash,gross_amount&order=observed_at.desc&limit=5" \
  -H "apikey: $ANON" -H "Authorization: Bearer $JWT"
```

Rows mean RLS and the JWT shape are both correct. PGRST301 or `role "merchant" does not exist` means something regressed. See [Authentication](/platform/auth).

For a live payment against testnet:

```bash theme={null}
NETWORK=base-sepolia TOKEN=EURC node scripts/pay-moneyshot.mjs
```
