215 lines
7.2 KiB
Markdown
215 lines
7.2 KiB
Markdown
|
|
# Build Graph Dashboard
|
|
|
|
**Parent:** [DataBuild Roadmap](./roadmap.md)
|
|
|
|
**Status:** In Progress
|
|
|
|
**Implementation:** Broken into 9 incremental chunks (see [Chunk Plans](#chunk-implementation-plan))
|
|
|
|
- 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
|
|
```typescript
|
|
// Minimal stateless approach - only UI state
|
|
interface AppState {
|
|
currentPage: string;
|
|
polling: {
|
|
active: boolean;
|
|
interval: number;
|
|
tabVisible: boolean; // Page Visibility API
|
|
};
|
|
}
|
|
```
|
|
|
|
#### API Client
|
|
```typescript
|
|
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
|
|
```typescript
|
|
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
|
|
|
|
```bash
|
|
# 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
|
|
- **[Chunk 1: TypeScript Client Generation](./webapp_v1/chunk-1-client-generation.md)** - Generate typed client from OpenAPI spec
|
|
- **[Chunk 2: Hello World App](./webapp_v1/chunk-2-hello-world-app.md)** - Bazel-built TypeScript + Mithril app
|
|
- **[Chunk 3: Routing Framework](./webapp_v1/chunk-3-routing-framework.md)** - Multi-page routing and layout
|
|
|
|
### Phase 2: Core Dashboard Pages
|
|
- **[Chunk 4: Recent Activity](./webapp_v1/chunk-4-recent-activity.md)** - Dashboard home page
|
|
- **[Chunk 5: Build Status](./webapp_v1/chunk-5-build-status.md)** - Real-time build monitoring
|
|
- **[Chunk 6: Partition Pages](./webapp_v1/chunk-6-partition-pages.md)** - Partition status and history
|
|
- **[Chunk 7: Jobs Pages](./webapp_v1/chunk-7-jobs-pages.md)** - Job metrics and monitoring
|
|
|
|
### Phase 3: Advanced Features
|
|
- **[Chunk 8: Graph Analysis](./webapp_v1/chunk-8-graph-analysis.md)** - Interactive graph visualization
|
|
- **[Chunk 9: Polish](./webapp_v1/chunk-9-polish.md)** - Final styling and optimization
|
|
|
|
Each chunk delivers working functionality that can be tested independently while building toward the complete dashboard vision.
|