Files
ss-tools/specs/019-superset-ux-redesign/contracts/api.md
2026-02-09 12:35:27 +03:00

5.2 KiB

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:

{
  "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:

{
  "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:

{
  "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:

{
  "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

{
  "task_id": "uuid",
  "status": "RUNNING" | "SUCCESS" | "ERROR" | "WAITING_INPUT"
}

task:log

{
  "task_id": "uuid",
  "timestamp": "2026-02-09T10:00:00Z",
  "level": "INFO",
  "source": "plugin",
  "message": "Starting migration..."
}

task:input_required

{
  "task_id": "uuid",
  "input_type": "password" | "mapping_selection",
  "prompt": "Enter database password"
}

Module Contracts (Semantic Protocol)

SidebarStore (frontend/src/lib/stores/sidebar.js)

// [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)

// [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)

// [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]