ProjectR Docs
Getting Started

The Type Contract

How Convex types flow into both apps, and the check-all rule.

Both apps import Convex types straight from backend source. There are no copied _generated folders and no codegen scripts.

  • Mobile resolves @convex/* to packages/backend/convex/* (tsconfig, babel, and jest configs all agree).
  • Dashboard resolves convex/_generated/* to packages/backend/convex/_generated/*.

What this means in practice

A backend schema or validator change immediately re-types both apps. After touching packages/backend/convex, run bun run check-all at the repo root. New type errors in apps/* are the contract change surfacing, not noise — fix them in the same PR.

CI enforces the same coupling: dashboard-ci.yml and every mobile workflow also fire on packages/backend/** changes.

Deploys are not atomic

Even though types are shared, deploys are not. Shipped mobile binaries keep calling the deployed backend for weeks. Therefore:

  1. Add fields first (optional/nullable), deploy the backend.
  2. Migrate clients to read/write the new fields.
  3. Remove old fields only after the fleet has moved — old binaries break if the backend stops serving what they read.

The same rule is why about 110 public Convex functions with no caller in the current apps stay in the backend. Store builds still in use may call them, and nobody has checked the production call metrics yet.

Reading order for a backend change

  1. Edit packages/backend/convex/...
  2. bun run check-all from the root — fix contract errors in both apps
  3. bun run test — backend tests, app tests
  4. Deploy backend first, then dashboard (see Deploy Topology)

On this page