Dispatch prompt โ
Paste this into a builder session started with CLAUDE_ALLOW_PM_BUILD=1 claude from this worktree.
Build issue #958: promote the admin Query Console to its own Analytics surface and teach it to query Firestore.
Where you are. You are already in a git worktree at .claude/worktrees/query-console, on branch feat/query-console-958, freshly branched off origin/dev. Do NOT switch, stash, reset, or rebase onto another ref. Just commit here. The operator runs parallel sessions against the main checkout, so staying in this worktree is what keeps you out of their way.
Read first, before touching anything. docs/projects/query-console/README.md and planning.md are already in your tree (uncommitted, commit them as your first commit). The README carries verified ground truth about what is actually in BigQuery, gathered on 2026-08-24 by querying the live project. Do not re-derive it and do not trust any table name that is not in it. Also read the two prior console design specs named in the README's related section, because slices 1 and 2 reshape that shell and you should not fight decisions already made there.
The context that produced this issue. The operator asked the Lantern Assistant for a query and it invented your-project.firestore_export.offers. No such project, no such dataset. The Assistant has zero BigQuery grounding, which is slice 5. Read issue #958 for the full account.
Do the five slices in planning.md, in order. Each is its own logical commit, pushed immediately after you make it. Slice 1 is a pure move and must be reviewable as one: keep /admin/analytics/bigquery/console alive as a redirect so existing links do not break.
On the Firestore field allowlist, slice 3. Start from FIRESTORE_FIELD_ALLOWLIST in services/api/assistant/src/services/tools.js. Extend it only where a real console question needs it, and list every NEW field explicitly in the PR body for her veto. That is her decision from 2026-08-24. The comment in that file explains why it allowlists fields rather than collections (merchantProfiles carried the admin password hash until #875), and that reasoning still binds. Do not widen it quietly.
Gates, all of which bind.
- This has a runtime and data surface. Write the manual test plan FIRST via the test-plan skill at
docs/engineering/testing/runs/<slug>/README.mdand link it in the PR, then actually exercise it via the browser-test skill. Unit tests alone do not close this. - New endpoint means Cloud Run, not a Cloud Function. Follow the cloud-service skill. Extend analytics-api, do not add a service.
- StyledSelect, never a native select. ESLint enforces it. Invoke the design skill before any UI work.
- Run npm run validate ONCE when the work is ready, not per commit. Fix everything locally.
- ONE draft PR for this whole session, base dev. Open it early as a draft. Do NOT mark it ready: that needs her word at the moment of action.
- No em dashes anywhere, including commit messages and the PR body.
Also add the launch-plan row. PROTOTYPE.md Phase 2 (Build; it held this as ALPHA.md Phase 1 before the 2026-08-31 timeline shift) needs an "Analytics hardening" row for #958. The exact row text is drafted in docs/projects/query-console/README.md. Add it if it is not already there.
When you are done, report what landed, what you deliberately did not do, and anything you need her to decide.