# ๐Ÿงน AYO โ€” Leaderboard Migration Checklist Manual steps to finish the leaderboard rollout. **All code changes are already applied** in the working tree โ€” these are the external actions on Firebase and Netlify that have to be done by hand. > One project (`secure-moment-188701`), one difference between environments: the > **collection namespace**. Production uses `mw-*`, dev/test uses `mw-test-*`. > Full rationale: [`docs/leaderboard-env-migration.md`](docs/leaderboard-env-migration.md). --- ## โœ… Step 1 โ€” Deploy Firestore rules + indexes From the repo root: ```bash npx firebase login npx firebase deploy --only firestore:rules,firestore:indexes --project prod ``` - Uses committed [`firestore.rules`](firestore.rules) + [`firestore.indexes.json`](firestore.indexes.json). - `prod` โ†’ `secure-moment-188701` (via [`.firebaserc`](.firebaserc)). - โš ๏ธ Deploying **replaces** the console rules. The committed rules cover every collection (`mw-*` and `mw-test-*`), so it's safe โ€” but review first. - No composite indexes to build โ€” rolling windows (`time_stamp >=`) and all-time (`orderBy score`) use Firestore's automatic single-field indexes. ## โœ… Step 2 โ€” Set Netlify environment variables In the Netlify site settings, add: | Variable | Value | | --- | --- | | `VITE_FIREBASE_API_KEY` โ€ฆ (all 8) | **same as [`app/.env.development`](app/.env.development)** (same project) | | `VITE_LB_NAMESPACE` | **`mw`** โ† makes production use the `mw-*` collections | > Local dev already uses `mw-test` via the committed `.env.development` โ€” nothing > to do there. ## โœ… Step 3 โ€” (Optional) Seed the test config doc Create `mw-test-config/configuration` in Firestore with the same `passingStatus` and `message` as the prod `mw-config/configuration`. Skip it and the test board still works โ€” the default qualifier just accepts all wins in test. ## โœ… Step 4 โ€” Seed the dev database with sample scores > โš ๏ธ **Must run _after_ Step 1.** The seed writes to `mw-test-scores`, which is > only allowed once the generalized rules are deployed โ€” otherwise every write > returns `permission-denied`. (No indexes to wait on โ€” the windows use > automatic single-field indexes.) Populate the dev boards so they aren't empty while developing: ```bash (cd app && node ../scripts/seed-dev-scores.js) ``` - Uses [`scripts/seed-dev-scores.js`](scripts/seed-dev-scores.js) โ€” ~12 sample scores per level, timestamps spread across today / this week / this month / older so **all four tabs** populate. - Dev-only and idempotent-ish (re-running just adds more rows); it never touches the production `mw-*` collections. > ๐Ÿ’ก **Local dev uses the emulator by default โ€” this cloud seed is optional.** > `pnpm dev` points at the local **Firestore emulator** (needs a JDK): run > `pnpm emulators` + `pnpm seed:emulator` and you're set โ€” no deploy, no cloud. > The cloud seed above is only needed for a hosted/preview environment. To opt > out of the emulator, set `VITE_FIRESTORE_EMULATOR=` empty in `app/.env.local`. > See [`docs/firebase-leaderboards.md`](docs/firebase-leaderboards.md#local-firestore-emulator-default-for-local-dev). ## โœ… Step 5 โ€” Verify | Environment | How | Expected | | --- | --- | --- | | **Production** (`mw`) | Win a game on the live site | Score shows; doc in `mw-scores/{level}/games` | | **Local dev** (`mw-test`) | `pnpm dev` (after Step 4) | Board shows sample scores; winning adds to `mw-test-scores/{level}/games`; prod `mw-scores` untouched | | **Rules** | Read both boards | Reads succeed; a malformed write is rejected | --- ## ๐Ÿ“Œ Still open (not blocking) - **Nothing is committed yet** โ€” all changes are in the working tree. - **`scripts/export-legends.js`** still hard-codes the (dev = prod) Firebase keys from the one-off Legends export. It's identical to `app/.env.development`; can be de-duped to read from the env file on request. - **Legends** is already frozen into static HTML ([`app/legends.html`](app/legends.html)) โ€” no action needed.