Story-1683 pramaan-admin firm detail

Firm detail now shows the actual firm membership roster

Operators can inspect every accepted firm member on the firm permalink, not only the firm-admin subset or PRAMAAN support roster. The panel consumes the existing generated adminListMembers path backed by GET /admin/firms/{firmId}/members.

What changed

Single roster panel

The old FirmAdminsPanel was replaced by FirmMembersRosterPanel in the firm detail composition. The page no longer renders a duplicate admins-only list beside the support roster.

Generated members data

FirmDetailPage prefetches adminListMembersQueryOptions, and the client panel uses useAdminListMembers with the same query. The browser refetch path is /api/internal/firms/[firmId]/members.

Trust boundary

firmDetailGateway.listMembersWithResponseHeaders calls the gateway as unknown and parses with generated adminListMembersQueryResponseSchema before the UI trusts the payload.

Operator view

Existing contamination path

The previous Firm admins panel rendered firm.admins from the firm-detail aggregate, not the filtered members endpoint. That matches the staging symptom where internal PRAMAAN rows appeared as firm admins.

This Story keeps the scope to the accepted baseline: consume the existing GET /admin/firms/{firmId}/members endpoint. No functions endpoint or reconciliation endpoint was added.

Coverage

Storybook coverage lives at Firms/FirmMembersRosterPanel with populated, empty first-run, and identity-hat-violation stories. Visual checks were captured from Storybook for the populated and empty states.

Unit coverage includes the panel rendering/empty/diagnostic states and the BFF route's generated path/query validation plus x-pramaan-* header forwarding.

Verification proof

Local verification for this story: pnpm exec tsc --noEmit, pnpm lint, NEXT_PUBLIC_ENV=local GATEWAY_SERVICE_KEY=local-test-key pnpm build, pnpm test, pnpm run test:storybook, and git diff --check.

Lint passes with the existing React Compiler warnings around shared TanStack Table usage in src/hooks/use-data-table.ts, src/components/data-table/data-table.stories.tsx, and tests/unit/data-table.test.tsx.