---
id: w6/m3/t001
title: Workspace switcher dropdown + selected-workspace context scoping all queries
worker: worker6
status: done
estimate: 40m
depends_on: [w6/m1]
---

## Closeout

Shipped as `src/features/workspaces/{context,components/workspace-switcher.tsx,hooks/use-workspaces.ts}`. The context provider is mounted in `RootProvider` (not `DashboardLayout` — pages call `useServices`/`useDatabases` in their own body before returning `<DashboardLayout>`, so a provider inside the layout can never reach them), persists the selection to `localStorage` under `bex.selectedWorkspaceId`, and falls back to the first workspace when nothing is stored or the stored id was deleted. `useServices`/`useDatabases` thread `currentWorkspaceId` in as the `ownerId` GraphQL variable (the filter m2/t004 already exposes) and `skip` until it resolves. Verified in a real browser via the extended `local-bex.mjs` stub (see milestone README's verification note) — switching workspaces correctly re-scopes the services list to empty for an unseeded workspace.

## Objective

A Render-style workspace dropdown at the top of the left pane: shows the current workspace, lists the caller's workspaces (from m1's `workspaces` GraphQL query) with plan badges, offers **+ New Workspace**, and switching updates a selected-workspace context that scopes every data query in the app. Selection persists across reloads.

## Context

- Dashboard: TanStack Start + Apollo + shadcn (`dashboard/CLAUDE.md`); layout/sidebar components under `dashboard/src/components/`.
- Today the app implicitly operates in the caller's single workspace; this introduces the workspace dimension — existing queries (services, databases, env, metrics) need the selected workspace threaded through (GraphQL variables or request header, matching what m1/t006 and m2/t004 expose).
- Persistence: URL or localStorage for the selected workspace **id only** (not a credential — DO_NOT_DO's token rule is about tokens, not ids).
- Render reference: dropdown at the top of the left pane (RESEARCH-workspaces.md finding 2–3).

## Steps

1. Add a workspace context/provider + persisted selection with a sane default (m9-minted workspace).
2. Build the dropdown (current name, list with plan badges, + New Workspace linking to `/new/workspace`).
3. Thread selection into Apollo operations; audit each route's queries for workspace scoping.

## Files

- `dashboard/src/components/` (sidebar/dropdown)
- `dashboard/src/routes/` (context wiring)
- `dashboard/src/graphql/` (query variables)

## Acceptance criteria

- [ ] Switching workspaces re-scopes services/databases/env/metrics pages without reload artifacts
- [ ] Selection survives a page reload; deep links respect it
- [ ] Dropdown lists name + plan and marks the current workspace

## Out of scope

- The creation flow itself (t002); settings (t003).
