Design-first gate · UX approval · frames-only PR

developers.fuzefront.com — Approval Frames

Nine navigable frames covering the five flows of the new developer portal: a standalone app at developers.fuzefront.com (not a Module-Federation remote — it must be reachable pre-shell, at sign-in, on its own subdomain), structurally modeled on fuzefront-website/frontend/ and sibling to it at repo root. Plan of record: docs/planning/developers-portal.md §4.1 and §7. Built in fuse-seam tokens only. Approving a flow approves its slice of the build inventory below, so the implementation cannot quietly invent a different component or package layout.

1 · Home — flow home · route /

What the portal is, quick links, the sign-in CTA — and, once signed in, the personalized recent-specs and sandbox-activity panels with their empty first-sign-in variants.

Frame 01 · anonymous

Home — signed out

Hero, quick links (Playground shown locked, not hidden), the providesTo product directory, and the sandbox-safety promise stated up front.

Frame 02 · authenticated

Home — signed in

Quota strip, your recent specs, your sandbox activity — plus both panels' empty state for a developer's very first sign-in.

2 · Catalog — flow catalog · route /catalog

Browse product → service → spec, search and filter, with every state the harvest can produce.

Frame 03 · populated

Catalog

TreeNav rail, search + product/tag/sandbox-mode filters, result cards carrying version, operation count, harvest age and sandbox mode (mock vs sandbox).

Frame 04 · states

Catalog states

Loading skeletons · empty (nothing harvested yet) · filtered-empty · error (harvest failed, degrading to a badged stale catalog) · 403 not-a-Developer.

3 · Spec viewer — flow spec-viewer · route /catalog/:product/:service

Our aggregated overview wrapped around an OSS OpenAPI render (Stoplight Elements / Swagger UI — the plan's §3 spike decides which), themed with fuse-seam tokens.

Frame 05 · populated

Spec viewer

Three panes — operations by tag, overview + selected operation (params, request/response schemas, examples, Try it), and copy-paste code samples.

Frame 06 · states

Spec viewer states

Loading · spec-fetch failed (502) · invalid spec (validator output shown, Try-it disabled, source repo named) · 404 not found · stale-spec badge.

4 · Playground — flow playground · route /playground

The "Try it" panel. This is where a wrong state is a security incident, so the fail-closed cases get a frame of their own.

Frame 07 · populated

Playground

Request builder (target selector, params, non-editable auth header, body), response panel, quota meter, and the permanent “this never touches production” notice.

Frame 08 · fail-closed

Playground states

Sending · request-invalid (blocked locally, no quota spent) · 429 quota exceeded · sandbox target unavailable with an explicit no-production-fallback statement · no-sandbox · 403 · proxy 5xx · and target 4xx rendered as data, not as a portal error.

5 · My access — flow my-access · route /access

What the developer holds, and — just as important — what the Developer role does not grant.

Frame 09 · membership · quota · keys

My access

Root-org developer membership with an explicit grants/does-not-grant split, sandbox quota with per-target breakdown, sandbox keys with reveal-once and revoke — plus provisioning, denied (403), empty-keys, error and revoke-confirm states.

Build inventory — approving each flow approves its slice of this plan

Flows (per-flow approval)

home DevPortalHomeFlow · / · approved: false devportal-frontend/src/pages/home/** · packages/devportal-ui/src/home/**
catalog SpecCatalogFlow · /catalog · approved: false devportal-frontend/src/pages/catalog/** · packages/devportal-ui/src/catalog/**
spec-viewer SpecViewerFlow · /catalog/:product/:service · approved: false devportal-frontend/src/pages/spec/** · packages/devportal-ui/src/spec-viewer/**
playground PlaygroundFlow · /playground · approved: false devportal-frontend/src/pages/playground/** · packages/devportal-ui/src/playground/**
my-access MyAccessFlow · /access · approved: false devportal-frontend/src/pages/access/** · packages/devportal-ui/src/access/**

React components

DevPortalShellPortalTopBar HomeHeroQuickLinkGrid ProductDirectorySignInCta RecentSpecsPanelSandboxActivityPanel CatalogTreeCatalogFilters CatalogResultListSpecResultCard SandboxModeBadgeSpecHeader SpecOverviewPanelEndpointList OperationPanelSchemaTable SpecRendererEmbedCodeSamplePanel TryItButtonPlaygroundPanel SandboxTargetSelectorRequestBuilder ParamTableResponsePanel QuotaMeterSandboxSafetyNotice RequestHistoryPanelMembershipPanel RoleScopeSummarySandboxKeyTable RevealOnceKey

npm packages

@fuzefront/devportal-ui @fuzefront/devportal-client

@fuzefront/devportal-ui holds every component above; devportal-frontend/ is the thin standalone Vite app (own Helm Deployment/Service/Ingress) that routes them. @fuzefront/devportal-client is generated from the frozen services/devportal-service/openapi.yaml. Both publish privately to GitHub Packages (access: restricted).

Design-system additions (foundation PRs, owned by frontend-engineer)

CodeBlockTreeNav Badge — HTTP method tone map

These three are not in @fuzefront/design-system today and are drawn here from tokens only, never one-offed into feature code. Everything else composes existing primitives: ProgressMeter (→ QuotaMeter), StatusCallout, EmptyState, Skeleton, StatusPill, Badge, Button, SearchField, Select, Input, CodeField (multiline → request body), DataTable, Tabs, Breadcrumb, TopBar, Avatar.

● Awaiting approval — all 5 flows

Design system: @fuzefront/design-system (fuse-seam) · Contract: services/devportal-service/openapi.yaml → @fuzefront/devportal-client (frozen by contract-designer in plan phase 0 — these frames name the endpoints they bind to) · Flag: fuzefront.devportal.enabled (default OFF, builders audience targeted).
Coverage for gate-frames-first is declared, not inferred: implementation.paths at feature level and per flow, pointing at devportal-frontend/** and packages/devportal-ui/**.
Approve per flow via the design-approval workflow (never hand-edit approved on master), or reply @claude approve <flow-id> / @claude reject: <reason>. Reject re-dispatches product-designer; it does not close the thread.

Review · devportal approve or reject each flow ↓
homependingApproveReject
catalogpendingApproveReject
spec-viewerpendingApproveReject
playgroundpendingApproveReject
my-accesspendingApproveReject