---
id: w3/m3/t001
title: Wire Apollo to bex-api GraphQL: metrics query + codegen types + session auth
worker: worker3
status: done
estimate: 40m
depends_on: []
---

## Objective

Turn the dashboard's dormant Apollo setup into a real bex-api client: a typed `metrics(...)` query generated from a `.graphql` document, executed against bex-api's `/graphql` with the caller's Kratos session credential.

## Context

- `dashboard/codegen.ts` exists but no `src/**/*.graphql` files do; its `schema` must point at bex-api's `/graphql` (see `dashboard/CLAUDE.md` "GraphQL (bex-api, not auth)").
- Apollo factories: `dashboard/src/common/apollo/factory.client.ts` / `factory.server.ts` — kept from the scaffold, not yet pointed at bex-api. API base URL comes from `dashboard/src/config/config.ts` (`VITE_API_URL`).
- bex-api GraphQL field (`operator/internal/api/graphql.go:295`): `metrics(resource!, metric!, startTime, endTime, resolutionSeconds, quantile, percentage, statusCode, host, path, groupBy) → [MetricSeries {unit, labels{field,value}, points{timestamp,value}}]`. Metric ids: `cpu|memory|instance_count|http_requests|http_latency|bandwidth`.
- Auth: bex-api accepts Kratos sessions (cookie or `X-Session-Token`) — `docs/ADR006-bex-api.md#auth`. The browser fetch must send credentials (`credentials: 'include'`).

## Steps

1. Create `dashboard/src/features/metrics/api/metrics.graphql` with a named `Metrics` query covering all args the page needs (`resource`, `metric`, `startTime`, `endTime`, `resolutionSeconds`, `quantile`, `percentage`).
2. Point `codegen.ts`'s `schema` at bex-api's `/graphql` (env-overridable; document running codegen against `https://api.bex.co/graphql` or a local `make run` api) and generate `src/graphql/definitions.ts`.
3. Configure the Apollo link in `factory.client.ts` to target `${VITE_API_URL}/graphql` with `credentials: 'include'`; keep SSR factory consistent.
4. Add a `useMetrics(resource, metric, opts)` hook in `src/features/metrics/hooks/` wrapping the generated query with 30s `pollInterval`.

## Files

- `dashboard/codegen.ts`
- `dashboard/src/features/metrics/api/metrics.graphql`
- `dashboard/src/features/metrics/hooks/use-metrics.ts`
- `dashboard/src/common/apollo/factory.client.ts`, `factory.server.ts`
- `dashboard/src/config/config.ts` (if a new env var is needed)

## Acceptance criteria

- [ ] `yarn codegen` (or equivalent) generates types for the `Metrics` query with no hand-written response types.
- [ ] `useMetrics("beancount-cms", "cpu")` returns live series data in the dev app when logged in. (`beancount-cms` is the App's resource/CR name; `beancount-cms-v2` is only its `.onbex.co` hostname — confirmed live via `/v1/services`, don't query by the hostname.)
- [ ] The request carries the Kratos session credential (verify a 200, and a 401 when logged out).

## Out of scope

- The page UI (t002); CORS/deployment changes (t003).
