# Capability Spec Delta: api-openapi-ui-redoc (api-openapi-ui-redoc) **Package**: `@suaveplan/api-openapi-ui-redoc` **Status**: PROPOSED > Every requirement below carries a `**Verified by:**` line at authoring time. ## ADDED Requirements ### Requirement: ReDoc UI handler renders the host's OpenAPI document The package SHALL expose `createRedocUiHandler({ openapiUrl, title, theme, expandResponses })` returning an HTTP handler responding with the ReDoc HTML shell pointing at `openapiUrl`. #### Scenario: handler returns HTML referencing openapiUrl - WHEN the handler is invoked with `openapiUrl = "/openapi.json"` - THEN response is `text/html` AND the body references `/openapi.json` #### Scenario: expandResponses configured - WHEN `expandResponses: "200,201"` - THEN the embedded ReDoc config expands those response codes by default **Verified by:** `src/handler/handler.test.ts::"handler returns HTML referencing openapiUrl"` AND `src/handler/handler.test.ts::"expandResponses is embedded in config"` --- ### Requirement: Per-plugin handler points at filtered URL The package SHALL expose `createPerPluginRedocUiHandler({ openapiUrlForPlugin, plugin })` whose shell references the plugin-filtered URL. #### Scenario: per-plugin URL embedded - WHEN the per-plugin handler is invoked - THEN the response body references the filtered URL **Verified by:** `src/per-plugin/per-plugin.test.ts::"per-plugin handler embeds filtered URL"` --- ### Requirement: Options validated by Zod The package SHALL validate `RedocUiOptions` via a Zod schema. Invalid options raise `OPENAPI_UI_REDOC_INVALID_OPTIONS`. #### Scenario: invalid option rejected - WHEN `expandResponses` is set to a non-allowed value - THEN handler construction throws `OPENAPI_UI_REDOC_INVALID_OPTIONS` **Verified by:** `src/options/options.test.ts::"invalid expandResponses rejected"` --- ### Requirement: Asset strategy supports cdn and bundled The package SHALL resolve the ReDoc runtime asset URL from `host.openapi.uiAssets`. `"cdn"` returns the upstream CDN URL; `"bundled"` returns the embedded path. A missing bundled asset raises `OPENAPI_UI_REDOC_ASSETS_MISSING`. #### Scenario: cdn mode - WHEN `uiAssets = "cdn"` - THEN the resolved asset URL points at the documented ReDoc CDN #### Scenario: bundled mode without asset raises - WHEN `uiAssets = "bundled"` AND the bundled asset is missing - THEN handler construction throws `OPENAPI_UI_REDOC_ASSETS_MISSING` **Verified by:** `src/assets/assets.test.ts::"cdn mode returns CDN URL"` AND `src/assets/assets.test.ts::"bundled mode without asset raises ASSETS_MISSING"`