243 lines
5.2 KiB
Markdown
243 lines
5.2 KiB
Markdown
# API Contracts: Superset-Style UX Redesign
|
|
|
|
**Feature**: 019-superset-ux-redesign
|
|
**Date**: 2026-02-09
|
|
|
|
## Overview
|
|
|
|
This document defines the API contracts for new endpoints required by the Resource-Centric UI. All endpoints follow existing patterns in the codebase.
|
|
|
|
## New Endpoints
|
|
|
|
### 1. Dashboard Hub API
|
|
|
|
#### GET /api/dashboards
|
|
|
|
**Purpose**: Fetch list of dashboards from a specific environment for the Dashboard Hub grid.
|
|
|
|
**Query Parameters**:
|
|
| Parameter | Type | Required | Description |
|
|
|-----------|------|----------|-------------|
|
|
| env_id | string | Yes | Environment ID to fetch dashboards from |
|
|
| search | string | No | Filter by title/slug |
|
|
|
|
**Response**:
|
|
```json
|
|
{
|
|
"dashboards": [
|
|
{
|
|
"id": "uuid-string",
|
|
"title": "Sales Report",
|
|
"slug": "sales-2023",
|
|
"url": "/superset/dashboard/sales-2023",
|
|
"git_status": {
|
|
"branch": "main",
|
|
"sync_status": "OK" | "DIFF" | null
|
|
},
|
|
"last_task": {
|
|
"task_id": "task-uuid",
|
|
"status": "SUCCESS" | "RUNNING" | "ERROR" | "WAITING_INPUT" | null
|
|
}
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
**Errors**:
|
|
- `404`: Environment not found
|
|
- `503`: Superset connection error
|
|
|
|
---
|
|
|
|
### 2. Dataset Hub API
|
|
|
|
#### GET /api/datasets
|
|
|
|
**Purpose**: Fetch list of datasets from a specific environment for the Dataset Hub grid.
|
|
|
|
**Query Parameters**:
|
|
| Parameter | Type | Required | Description |
|
|
|-----------|------|----------|-------------|
|
|
| env_id | string | Yes | Environment ID to fetch datasets from |
|
|
| search | string | No | Filter by table name |
|
|
|
|
**Response**:
|
|
```json
|
|
{
|
|
"datasets": [
|
|
{
|
|
"id": "uuid-string",
|
|
"table_name": "fact_orders",
|
|
"schema": "public",
|
|
"database": "Production DB",
|
|
"mapped_fields": {
|
|
"total": 20,
|
|
"mapped": 15
|
|
},
|
|
"last_task": {
|
|
"task_id": "task-uuid",
|
|
"status": "SUCCESS" | null
|
|
}
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### 3. Activity API
|
|
|
|
#### GET /api/activity
|
|
|
|
**Purpose**: Fetch summary of active and recent tasks for the navbar indicator.
|
|
|
|
**Response**:
|
|
```json
|
|
{
|
|
"active_count": 3,
|
|
"recent_tasks": [
|
|
{
|
|
"task_id": "task-uuid",
|
|
"resource_name": "Sales Report",
|
|
"resource_type": "dashboard",
|
|
"status": "RUNNING",
|
|
"started_at": "2026-02-09T10:00:00Z"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### 4. Consolidated Settings API
|
|
|
|
#### GET /api/settings
|
|
|
|
**Purpose**: Fetch all settings categories for the consolidated settings page.
|
|
|
|
**Response**:
|
|
```json
|
|
{
|
|
"environments": [
|
|
{ "id": "1", "name": "Development", "url": "http://dev...", "status": "OK" }
|
|
],
|
|
"connections": [
|
|
{ "id": "1", "name": "Prod Clickhouse", "type": "clickhouse" }
|
|
],
|
|
"llm": {
|
|
"provider": "openai",
|
|
"model": "gpt-4",
|
|
"enabled": true
|
|
},
|
|
"logging": {
|
|
"level": "INFO",
|
|
"task_log_level": "DEBUG",
|
|
"belief_scope_enabled": false
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## WebSocket Events (Existing)
|
|
|
|
The Task Drawer subscribes to existing WebSocket events:
|
|
|
|
### task:status
|
|
```json
|
|
{
|
|
"task_id": "uuid",
|
|
"status": "RUNNING" | "SUCCESS" | "ERROR" | "WAITING_INPUT"
|
|
}
|
|
```
|
|
|
|
### task:log
|
|
```json
|
|
{
|
|
"task_id": "uuid",
|
|
"timestamp": "2026-02-09T10:00:00Z",
|
|
"level": "INFO",
|
|
"source": "plugin",
|
|
"message": "Starting migration..."
|
|
}
|
|
```
|
|
|
|
### task:input_required
|
|
```json
|
|
{
|
|
"task_id": "uuid",
|
|
"input_type": "password" | "mapping_selection",
|
|
"prompt": "Enter database password"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Module Contracts (Semantic Protocol)
|
|
|
|
### SidebarStore (frontend/src/lib/stores/sidebar.js)
|
|
|
|
```javascript
|
|
// [DEF:SidebarStore:Store]
|
|
// @TIER: STANDARD
|
|
// @PURPOSE: Manage sidebar visibility and navigation state
|
|
// @LAYER: UI
|
|
// @INVARIANT: isExpanded state is always synced with localStorage
|
|
|
|
// @UX_STATE: Idle -> Sidebar visible with current state
|
|
// @UX_STATE: Toggling -> Animation plays for 200ms
|
|
|
|
export const sidebarStore = writable({
|
|
isExpanded: true,
|
|
activeCategory: 'dashboards',
|
|
activeItem: '/dashboards',
|
|
isMobileOpen: false
|
|
});
|
|
|
|
export function toggleSidebar() { /* ... */ }
|
|
export function setActiveItem(path) { /* ... */ }
|
|
// [/DEF:SidebarStore]
|
|
```
|
|
|
|
### TaskDrawerStore (frontend/src/lib/stores/taskDrawer.js)
|
|
|
|
```javascript
|
|
// [DEF:TaskDrawerStore:Store]
|
|
// @TIER: CRITICAL
|
|
// @PURPOSE: Manage Task Drawer visibility and resource-to-task mapping
|
|
// @LAYER: UI
|
|
// @INVARIANT: resourceTaskMap always reflects current task associations
|
|
|
|
// @UX_STATE: Closed -> Drawer hidden, no active task
|
|
// @UX_STATE: Open -> Drawer visible, logs streaming
|
|
// @UX_STATE: InputRequired -> Interactive form rendered in drawer
|
|
|
|
export const taskDrawerStore = writable({
|
|
isOpen: false,
|
|
activeTaskId: null,
|
|
resourceTaskMap: {}
|
|
});
|
|
|
|
export function openDrawerForTask(taskId) { /* ... */ }
|
|
export function closeDrawer() { /* ... */ }
|
|
export function updateResourceTask(resourceId, taskId, status) { /* ... */ }
|
|
// [/DEF:TaskDrawerStore]
|
|
```
|
|
|
|
### ActivityStore (frontend/src/lib/stores/activity.js)
|
|
|
|
```javascript
|
|
// [DEF:ActivityStore:Store]
|
|
// @TIER: STANDARD
|
|
// @PURPOSE: Track active task count for navbar indicator
|
|
// @LAYER: UI
|
|
// @RELATION: DEPENDS_ON -> WebSocket connection
|
|
|
|
export const activityStore = derived(taskDrawerStore, ($drawer) => {
|
|
const activeCount = Object.values($drawer.resourceTaskMap)
|
|
.filter(t => t.status === 'RUNNING').length;
|
|
return { activeCount };
|
|
});
|
|
// [/DEF:ActivityStore]
|
|
```
|