databuild/plans/06-build-graph-dashboard.md

7.2 KiB

Build Graph Dashboard

Parent: DataBuild Roadmap

Status: In Progress

Implementation: Broken into 9 incremental chunks (see Chunk Plans)

  • Simplicity is absolutely critical here
  • Use mithril
  • Use typescript
  • Rely on client generated from OpenAPI interface definitions

Minimal Design

Architecture

Single-page application consuming Build Graph Service HTTP endpoints with real-time updates via polling.

┌─────────────────┐    HTTP API    ┌─────────────────┐
│  Dashboard SPA  │ ◄────────────► │ Build Graph     │
│  (Mithril/TS)   │                │ Service         │
└─────────────────┘                └─────────────────┘
                                           │
                                           │
                                   ┌─────────────────┐
                                   │ Build Event Log │
                                   │ (SQLite/PG)     │
                                   └─────────────────┘

Core Pages

1. Build Request Status (/builds/{id})

Primary operational page showing real-time build progress.

UI Elements:

  • Build request header (ID, status, timestamp)
  • Job/Partition status directed graph (with status requested → scheduled → building → available/failed)
  • Per-job execution timeline with logs from build events
  • Delegation indicators (when partitions delegated to other builds)

Key Features:

  • Auto-refresh every 2 seconds when tab is active and build is running
  • Expandable job details with execution logs from build event log
  • Visual progress indication via graph

2. Partitions List Page (/partitions)

Lists recently built partitions (searchable), with a "Build" button to trigger a new partition build (or go to existing).

3. Partition Status (/partitions/{base64_ref})

Shows partition lifecycle and build history.

UI Elements:

  • Partition info (ref, current status, last updated)
  • Build history table (build requests that produced this partition)
  • "Build Now" button with force option
  • Related partitions (upstream/downstream dependencies)

URL Handling:

  • Partition refs base64-encoded in URLs to avoid parsing ambiguity
  • Client-side encode/decode for partition references

4. Recent Activity (/)

Dashboard home showing system activity.

UI Elements:

  • Recent build requests (fetched from service)
  • Active builds count
  • Recent partition builds
  • System health indicators

Stateless Design:

  • All data fetched from Build Graph Service on page load
  • No client-side caching or state persistence

5. Jobs List Page (/jobs)

Lists jobs in graph with high level metedata per job and a link to each.

6. Job Metrics (/jobs/{label})

Job performance and reliability metrics. (with job label base64 encoded)

UI Elements:

  • Success rate chart (data from build event log via service)
  • Average duration trends
  • Recent runs table (with requested partitions)

5. Graph Analysis (/analyze)

Interactive build graph visualization.

UI Elements:

  • Partition input form
  • Generated job graph (mermaid.js rendering - simple visualization, rendered in the client)
  • Execution plan table

Technical Implementation

State Management

// Minimal stateless approach - only UI state
interface AppState {
  currentPage: string;
  polling: {
    active: boolean;
    interval: number;
    tabVisible: boolean;  // Page Visibility API
  };
}

API Client

class BuildGraphClient {
  async getBuildStatus(id: string): Promise<BuildStatus>;
  async getPartitionStatus(ref: string): Promise<PartitionStatus>;
  async submitBuild(partitions: string[]): Promise<string>;
  async getJobMetrics(label: string): Promise<JobMetrics>;
  async analyzeBuild(partitions: string[]): Promise<JobGraph>;
  async getRecentActivity(): Promise<ActivitySummary>;
}

// Partition reference utilities
function encodePartitionRef(ref: string): string {
  return btoa(ref).replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '');
}

function decodePartitionRef(encoded: string): string {
  return atob(encoded.replace(/-/g, '+').replace(/_/g, '/'));
}

Routing

const routes: RouteDef[] = [
  { path: '/', component: RecentActivity },
  { path: '/builds/:id', component: BuildStatus },
  { path: '/partitions/:base64_ref', component: PartitionStatus },
  { path: '/jobs/:label', component: JobMetrics },
  { path: '/analyze', component: GraphAnalysis }
];

Styling Approach

Minimal CSS with utility classes:

  • CSS Grid for layouts
  • Tailwind + daisyui
  • Consistent spacing scale (4px base unit)
  • Monospace font for partition refs/IDs
  • Color coding for status indicators

Real-time Updates

Polling-based updates with Page Visibility API integration:

  • 2s interval when tab is active and build is running
  • 10s interval when tab is active and build is completed
  • Polling stops when tab is not visible
  • Manual refresh button always available
  • Uses document.visibilityState to detect tab focus

Bundle Size Targets

  • Initial bundle: < 50KB gzipped
  • Mithril: ~10KB
  • Custom code: ~20KB
  • CSS: ~5KB
  • OpenAPI client: ~15KB

Data Flow

All data flows from Build Graph Service:

  1. Job Logs: Stored in build event log, retrieved via service API
  2. Partition Status: Computed from build events by service
  3. Build History: Maintained in build event log
  4. Metrics: Aggregated from build events by service
  5. No Client State: Dashboard fetches fresh data on each page load

Development Workflow

# Development server
npm run dev

# Build for production
npm run build

# Type checking
npm run typecheck

# Bundled with build graph service
./scripts/build_dashboard

Chunk Implementation Plan

This dashboard implementation is broken into 9 incremental, testable chunks:

Phase 1: Foundation & Infrastructure

Phase 2: Core Dashboard Pages

Phase 3: Advanced Features

Each chunk delivers working functionality that can be tested independently while building toward the complete dashboard vision.