---
id: w2/m7/t005
title: GraphQL adapter (nouns per t001 capture)
worker: worker2
status: done
estimate: 40m
depends_on: [w2/m7/t002]
---

## Objective

GraphQL surface over the same core, using the operation/field names t001 observed on Render's dashboard (never guessed — the postgres lesson: dashboard noun was `database*`, not the REST noun). Expected shape: list/get queries, a connection-info query, create/delete mutations, plus suspend/resume mutations once t004 lands — mirroring `internal/postgres/graphql.go`.

## Context

- `lego/backend/internal/postgres/graphql.go` — resolver wiring, type definitions, error mapping.
- The dashboard milestone (w5/m12) consumes exactly this schema; its stub (`dashboard/scripts/local-bex.mjs`) will mirror these operations — keep names/nullability stable once merged.
- If the capture shows Render still uses `redis*` GraphQL nouns (legacy), follow the capture and note the naming in the ledger row.

## Steps

1. Define the KV GraphQL types + queries/mutations per capture; wire resolvers to the core.
2. Register in the schema/server alongside `database*`.
3. Resolver tests: happy path + not-found + authz-denied.

## Files

- `lego/backend/internal/keyvalue/graphql.go` (new)
- GraphQL schema/server registration (wherever `database*` registers)

## Acceptance criteria

- [ ] Queries/mutations serve the same data as REST (same core), names matching the capture.
- [ ] connection-info via GraphQL matches the REST 3-field contract.
- [ ] Schema introspection shows the new noun set; backend tests green.

## Out of scope

- Dashboard client work (w5/m12).
