From 581cb768ba9dd4d9327b3a622ae15ebfa625aa73 Mon Sep 17 00:00:00 2001 From: Stuart Axelbrooke Date: Sat, 5 Jul 2025 23:42:17 -0700 Subject: [PATCH] Planning stage 3.1 --- plans/build-graph-dashboard.md | 181 ++++++++++++++++++++++++++++++++- 1 file changed, 180 insertions(+), 1 deletion(-) diff --git a/plans/build-graph-dashboard.md b/plans/build-graph-dashboard.md index 3e6fffd..ed54739 100644 --- a/plans/build-graph-dashboard.md +++ b/plans/build-graph-dashboard.md @@ -6,4 +6,183 @@ - Use typescript - Rely on client generated from protobuf interface definitions -TODO +## 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) +- 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; + async getPartitionStatus(ref: string): Promise; + async submitBuild(partitions: string[]): Promise; + async getJobMetrics(label: string): Promise; + async analyzeBuild(partitions: string[]): Promise; + async getRecentActivity(): Promise; +} + +// 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 +- Protobuf 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 +```