Initial Commit
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
# `@suaveplan/api-graphql-ui-altair` — Altair UI mount at `/graphql/ui`
|
||||
|
||||
**Package**: `@suaveplan/api-graphql-ui-altair`
|
||||
**Status**: PROPOSED
|
||||
**Type**: new-package
|
||||
**Stage**: 7 (GraphQL + WebSocket / SSE engines) — see umbrella `openspec/changes/api-plugin-foundation/`
|
||||
|
||||
## Why
|
||||
|
||||
Per design doc §10.6 Altair is the explicit alternative GraphQL UI alongside GraphiQL: "GET /graphql/ui — GraphiQL (or Altair via `api-graphql-ui-altair`)". Altair has a richer feature set — environment management, response history, query-saving collections — preferred by teams who do heavy in-browser API development. Operators wire one OR the other; the engine adapters (`api-graphql-yoga`, `api-graphql-apollo`) return 404 at `/graphql/ui` when neither is wired.
|
||||
|
||||
This package is the structural sibling of `api-graphql-ui-graphiql` — same plugin shape, same mount semantics, different bundled UI.
|
||||
|
||||
## What changes
|
||||
|
||||
Net-new package depending on `@suaveplan/api-types`, `@suaveplan/api-router`, `@suaveplan/api-graphql`, `@suaveplan/error`, `@suaveplan/logger`, and `altair-static` (peer; bundled assets).
|
||||
|
||||
- ADDED: `createAltairUi(opts)` — factory returning a `RouterPlugin` value mounting `GET <uiEndpoint>`.
|
||||
- ADDED: `AltairUiOptions` — Zod-validated config: `uiEndpoint` (default `/graphql/ui`), `graphqlEndpoint` (default `/graphql`), `subscriptionEndpoint` (default `/graphql/ws`), `theme` (`"light"` | `"dark"` | `"system"`), `initialQuery`, `initialHeaders`, `initialEnvironments` (Altair-specific feature).
|
||||
- ADDED: Static-asset serving from package's own `dist/assets/` (no CDN).
|
||||
- ADDED: CSP headers — same posture as the GraphiQL variant.
|
||||
- ADDED: `GRAPHQL_UI_ALTAIR_*` error codes: `GRAPHQL_UI_ALTAIR_ASSET_MISSING`, `GRAPHQL_UI_ALTAIR_ENDPOINT_COLLISION`.
|
||||
- ADDED: OTel instrument: `graphql.ui.requests_total { ui: "altair" }` — same metric name as the GraphiQL variant, only the label differs, so dashboards can sum across both UIs.
|
||||
|
||||
## Out of scope
|
||||
|
||||
- A CDN-fetched Altair variant.
|
||||
- The GraphiQL alternative.
|
||||
- Co-mounting both UIs on the same path — host config refuses if both are wired against the same `uiEndpoint`.
|
||||
|
||||
## Source mapping
|
||||
|
||||
Genesis-original. Source of design intent: `docs/superpowers/specs/2026-05-13-api-plugin-foundation-design.md`.
|
||||
|
||||
| Requirement | Design doc section |
|
||||
|---|---|
|
||||
| Altair as alternative at `/graphql/ui` | §10.6 |
|
||||
| UI as opt-in, separate package | §10.6 |
|
||||
| Bundled assets only | §10.6 + foundation security posture |
|
||||
|
||||
## Verification approach
|
||||
|
||||
- `src/factory/create-altair-ui.test.ts` — factory returns `RouterPlugin`; HTML response embeds configured endpoints; CSP header.
|
||||
- `src/factory/create-altair-ui.spec-conformance.test.ts` — same conformance shape as the GraphiQL spec — endpoint mount + embedded-config.
|
||||
- `src/assets/assets.test.ts` — no external host references; missing asset raises `GRAPHQL_UI_ALTAIR_ASSET_MISSING`.
|
||||
- `tests/integration/altair-end-to-end.test.ts` (30000ms) — boots `api-graphql-yoga` + this UI plugin, Playwright opens `/graphql/ui`, runs a query, asserts results render.
|
||||
|
||||
## Migration impact
|
||||
|
||||
None — additive only.
|
||||
Reference in New Issue
Block a user