---
id: w6/m10/t003
title: "Thread the enriched fields through the REST, GraphQL, and MCP fragments identically"
worker: worker6
status: done
estimate: 30m
depends_on: [w6/m10/t002]
---

## Objective

All three adapters expose the t002 fields with identical names and semantics: REST picks them up via `MemberView`'s JSON tags, GraphQL adds `userId`/`email` fields to the member type, and the MCP member-list tool's result/schema documents them. One service verb, three thin fragments — the backend house rule.

## Context

- `lego/backend/internal/members/rest.go` — `GET /v1/workspaces/{workspaceId}/members` writes `[]MemberView` directly; JSON tags from t002 should make REST automatic (verify, don't assume).
- `lego/backend/internal/members/graphql.go` — the member object type (fields `subject`/`role`/`createdAt` around :45) gains `userId` + `email` resolvers via `gqlutil.Field`.
- `lego/backend/internal/members/mcp.go` — the list-members tool result; update its description/schema so agents see the new fields.
- `TestAuthzGuardsEveryVerb` and the existing surface-parity tests in `members_test.go` must stay green.

## Steps

1. Verify REST emits the new fields (adjust only if the handler reshapes).
2. Add `userId`/`email` GraphQL fields.
3. Update the MCP tool schema/description.
4. `cd lego/backend && go test ./internal/members/...`.

## Files

- `lego/backend/internal/members/rest.go`
- `lego/backend/internal/members/graphql.go`
- `lego/backend/internal/members/mcp.go`

## Acceptance criteria

- [ ] The same member listed via REST, GraphQL, and MCP shows identical `userId`/`email` values (asserted by a test or a three-surface parity check in `members_test.go`).
- [ ] No fragment reimplements enrichment — all three read the one `MemberView`.

## Out of scope

- Dashboard consumption (t004).
- New verbs or mutation shape changes.
