Skip to content

Commit e9576eb

Browse files
committed
docs(providers-ui): archive capability spec
Sync delta specs from openspec/changes/providers-ui-3-screen-refactor/specs/providers-ui/ to openspec/specs/providers-ui/. Change lifecycle complete: PASS WITH WARNINGS verdict on 808da59.
1 parent 808da59 commit e9576eb

9 files changed

Lines changed: 181 additions & 2 deletions

File tree

openspec/changes/providers-ui-3-screen-refactor/design.md renamed to openspec/changes/archive/2026-06-06-providers-ui-3-screen-refactor/design.md

File renamed without changes.

openspec/changes/providers-ui-3-screen-refactor/proposal.md renamed to openspec/changes/archive/2026-06-06-providers-ui-3-screen-refactor/proposal.md

File renamed without changes.

openspec/changes/providers-ui-3-screen-refactor/specs/providers-ui/_metadata.md renamed to openspec/changes/archive/2026-06-06-providers-ui-3-screen-refactor/specs/providers-ui/_metadata.md

File renamed without changes.

openspec/changes/providers-ui-3-screen-refactor/specs/providers-ui/spec.md renamed to openspec/changes/archive/2026-06-06-providers-ui-3-screen-refactor/specs/providers-ui/spec.md

File renamed without changes.

openspec/changes/providers-ui-3-screen-refactor/state.yaml renamed to openspec/changes/archive/2026-06-06-providers-ui-3-screen-refactor/state.yaml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
change: providers-ui-3-screen-refactor
2-
current_phase: verify
2+
current_phase: archive
33
completed:
44
- init
55
- explore
@@ -9,5 +9,6 @@ completed:
99
- tasks
1010
- apply
1111
- verify
12-
next: archive
12+
- archive
13+
next: null
1314
updated: 2026-06-06

openspec/changes/providers-ui-3-screen-refactor/tasks.md renamed to openspec/changes/archive/2026-06-06-providers-ui-3-screen-refactor/tasks.md

File renamed without changes.

openspec/changes/providers-ui-3-screen-refactor/verification.md renamed to openspec/changes/archive/2026-06-06-providers-ui-3-screen-refactor/verification.md

File renamed without changes.
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
---
2+
name: providers-ui
3+
displayName: Providers UI
4+
version: 1.0.0
5+
status: active
6+
kind: frontend
7+
description: >
8+
Frontend UX for the Rook dashboard's AI provider management flows.
9+
Captures the 3-screen navigation model (Catalog → Details → Connection Modal),
10+
the quota placeholder page, and the EmptyState wrapper used across the dashboard.
11+
owners:
12+
- team/frontend
13+
created: 2026-06-06
14+
change: providers-ui-3-screen-refactor
15+
relatedCapabilities:
16+
- provider-connections # domain model & wire protocol
17+
- provider-connections-transport # HTTP DTOs and routing
18+
nonGoals:
19+
- Backend changes of any kind
20+
- Bulk actions on the catalog (multi-select enable/disable/delete)
21+
- Distribute Proxies (auto-rebalance priority/weight)
22+
- Static catalog of 228 providers (OmniRoute parity)
23+
- OAuth authorization redirect/initiation (form shape only)
24+
- Per-provider quota implementation (placeholder only)
25+
- Real-time connection status push (WebSocket / SSE)
26+
- Mobile-optimized layout (desktop-first)
27+
followUp:
28+
- "Real per-provider quota integration (mocked data today)"
29+
- "OAuth authorization flow for OAuth-supporting kinds"
30+
- "Bulk actions on the catalog"
31+
- "Distribute Proxies"
32+
---
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
# Providers UI Specification
2+
3+
> **Scope:** Frontend UX only. The domain model and wire protocol live in `provider-connections`; this spec covers the user-facing flows that consume those contracts.
4+
5+
## Purpose
6+
7+
Defines the Rook dashboard flows for discovering, configuring, and managing AI provider connections. Captures the 3-screen navigation model (Catalog → Details → Connection Modal), the quota placeholder, and the `EmptyState` wrapper used across the dashboard.
8+
9+
---
10+
11+
## Requirements
12+
13+
### Requirement: Providers Catalog
14+
15+
The system SHALL display a catalog view at `/providers` listing every supported `ProviderKind` as a card grouped by category (`API Key`, `OAuth`, `Local`). Each card SHALL show the display name, configured-connection count, a kind-level enable toggle, and a test-all action. The view SHALL support client-side category filtering and name search.
16+
17+
#### Scenario: Empty catalog
18+
- **WHEN** the user navigates to `/providers` with no connections configured
19+
- **THEN** the catalog shows every supported kind (`openai`, `anthropic`, `ollama`, `gemini`, `groq`) with `0 Connections`
20+
- **AND** each card shows an empty-state indicator for connections
21+
22+
#### Scenario: Catalog with connections
23+
- **WHEN** the user navigates to `/providers` with at least one connection
24+
- **THEN** each card shows its configured count (e.g., `Ollama Cloud: 3 Connections`)
25+
- **AND** the card is visually highlighted to indicate configured connections
26+
27+
#### Scenario: Filter by category
28+
- **WHEN** the user clicks a category chip (e.g., `API Key`)
29+
- **THEN** only kinds in that category are visible
30+
- **AND** the chip shows an active state
31+
- **AND** clicking the same chip again removes the filter
32+
33+
#### Scenario: Search the catalog
34+
- **WHEN** the user types in the search input
35+
- **THEN** only kinds whose name contains the search term are visible
36+
- **AND** the match is case-insensitive
37+
38+
#### Scenario: Navigate to details
39+
- **WHEN** the user clicks a kind card
40+
- **THEN** the user is navigated to `/providers/:providerKind` (e.g., `/providers/ollama`)
41+
42+
---
43+
44+
### Requirement: Provider Details
45+
46+
The system SHALL display a details view at `/providers/:providerKind` listing all connections for the specified kind. The header SHALL show the provider name, total connection count, and bulk action buttons (`Test All`, `Add`). The route SHALL validate `:providerKind` against the `ProviderKind` union.
47+
48+
#### Scenario: Details with connections
49+
- **WHEN** the user navigates to `/providers/ollama` with 3 Ollama connections
50+
- **THEN** the header shows `Ollama Cloud` and `3 Connections`
51+
- **AND** the page lists all 3 connections with name, status, model, priority, and proxy state
52+
53+
#### Scenario: Empty details state
54+
- **WHEN** the user navigates to `/providers/openai` with 0 OpenAI connections
55+
- **THEN** the header shows `OpenAI` and `0 Connections`
56+
- **AND** the page shows an empty state with a prominent `Add your first OpenAI connection` CTA
57+
58+
#### Scenario: Test all connections
59+
- **WHEN** the user clicks `Test All`
60+
- **THEN** all connections for the kind are tested sequentially
61+
- **AND** each connection's status indicator updates as its test completes
62+
63+
#### Scenario: Add from details
64+
- **WHEN** the user clicks `Add`
65+
- **THEN** the connection modal opens in create mode with `providerKind` pre-filled to the current kind
66+
67+
#### Scenario: Navigate back to catalog
68+
- **WHEN** the user clicks the back link or breadcrumb
69+
- **THEN** the user is navigated to `/providers`
70+
71+
---
72+
73+
### Requirement: Connection Modal
74+
75+
The system SHALL provide a modal dialog for creating and editing provider connections. The modal SHALL accept a `providerKind` prop and a `mode` prop (`'create' | 'edit'`) and SHALL be controlled by its parent via `v-model:open`. The modal MUST require a successful credential test before `Save` is enabled.
76+
77+
#### Scenario: Open in create mode
78+
- **WHEN** the user clicks `Add` from the catalog or details view
79+
- **THEN** the modal opens with `providerKind` pre-filled (or selectable if opened from catalog)
80+
- **AND** the form shows fields for the selected `authType` (API Key for `apikey`, OAuth fields for `oauth`)
81+
82+
#### Scenario: Test credentials
83+
- **WHEN** the user fills the form and clicks `Test`
84+
- **THEN** the modal calls `POST /api/providers/test-credentials`
85+
- **AND** displays the result (ok/error, latency)
86+
- **AND** `Save` is disabled until the result is `ok`
87+
88+
#### Scenario: Save a new connection
89+
- **WHEN** the test result is `ok` and the user clicks `Save`
90+
- **THEN** the modal calls `POST /api/providers`
91+
- **AND** the modal closes
92+
- **AND** the catalog/details view refreshes to show the new connection
93+
94+
#### Scenario: Edit existing connection
95+
- **WHEN** the modal opens in `edit` mode with a connection id
96+
- **THEN** the form is pre-populated from the existing record
97+
- **AND** saving calls `PUT /api/providers/{id}` with `expectedUpdatedAt`
98+
- **AND** the API key field is empty (stored secrets are not re-exposed)
99+
100+
#### Scenario: Cancel without saving
101+
- **WHEN** the user clicks `Cancel` or presses `Escape`
102+
- **THEN** the modal closes without saving
103+
- **AND** no mutation API call is made
104+
105+
---
106+
107+
### Requirement: Providers Quota Placeholder
108+
109+
The system SHALL display a placeholder quota view at `/providers/quota` with mocked data and a banner explaining that real per-provider quota integration is tracked in a follow-up issue.
110+
111+
#### Scenario: Navigate to quota
112+
- **WHEN** the user navigates to `/providers/quota`
113+
- **THEN** the page shows mocked quota data (tokens consumed, limits, cost)
114+
- **AND** a banner explains that per-provider quota integration is a follow-up
115+
- **AND** the page references the follow-up tracking issue
116+
117+
---
118+
119+
### Requirement: EmptyState Component
120+
121+
The system SHALL provide a reusable `EmptyState` component that wraps the shadcn-vue `Empty` primitive while preserving the existing public API (`title`, `description`, `icon` props).
122+
123+
#### Scenario: Backward-compatible callsites
124+
- **WHEN** a component uses `<EmptyState title="..." description="..." :icon="..." />`
125+
- **THEN** it renders correctly via the shadcn-vue `Empty` composition underneath
126+
- **AND** no existing callsite requires changes
127+
128+
#### Scenario: New shadcn-vue features
129+
- **WHEN** a new callsite uses shadcn-vue `Empty` slots or sub-components (e.g., `EmptyHeader`, `EmptyContent`)
130+
- **THEN** the wrapper supports them via slot passthrough or new prop names
131+
132+
---
133+
134+
### Requirement: Catalog Metadata Source
135+
136+
The catalog view SHALL derive its kind-level metadata (displayName, runtimeId, defaultBaseUrl, supportsOAuth, description, iconName) from a static `PROVIDER_KINDS` constant in `apps/rook/dashboard/src/config/providerCatalog.ts`. Configured-connection counts per kind SHALL be derived from the live list returned by `GET /api/providers`.
137+
138+
#### Scenario: Display kind metadata
139+
- **WHEN** the catalog renders a kind card
140+
- **THEN** the card shows the kind's display name and description from `PROVIDER_KINDS`
141+
- **AND** the connection count is the length of the live connections filtered by `providerKind`
142+
143+
#### Scenario: Adding a new kind
144+
- **WHEN** a developer adds an entry to `PROVIDER_KINDS`
145+
- **THEN** the new kind appears in the catalog without template changes
146+
- **AND** the route `/providers/:providerKind` resolves only for kinds in the backend `ProviderKind` enum

0 commit comments

Comments
 (0)