diff --git a/plans/build-graph-dashboard.md b/plans/build-graph-dashboard.md index 4877bc1..0f379ba 100644 --- a/plans/build-graph-dashboard.md +++ b/plans/build-graph-dashboard.md @@ -10,7 +10,7 @@ - Simplicity is absolutely critical here - Use mithril - Use typescript -- Rely on client generated from protobuf interface definitions +- Rely on client generated from OpenAPI interface definitions ## Minimal Design @@ -166,7 +166,7 @@ Polling-based updates with Page Visibility API integration: - Mithril: ~10KB - Custom code: ~20KB - CSS: ~5KB -- Protobuf client: ~15KB +- OpenAPI client: ~15KB ### Data Flow @@ -198,7 +198,7 @@ npm run typecheck 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 proto +- **[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 diff --git a/plans/webapp_v1/chunk-1-client-generation.md b/plans/webapp_v1/chunk-1-client-generation.md index 7b2308d..6554133 100644 --- a/plans/webapp_v1/chunk-1-client-generation.md +++ b/plans/webapp_v1/chunk-1-client-generation.md @@ -22,81 +22,95 @@ Generate TypeScript client code from the DataBuild protobuf definitions to provi ## Technical Approach -### Proto Analysis -Key messages to generate TypeScript for: -- `BuildEvent` and related event types -- `PartitionRef`, `JobLabel`, `GraphLabel` -- `BuildRequestStatus`, `PartitionStatus`, `JobStatus` -- `JobGraph`, `Task`, `JobConfig` -- Service request/response types +### OpenAPI-Based Generation +Generate TypeScript client from OpenAPI specification automatically derived from Build Graph Service: + +Key API endpoints to generate TypeScript client for: +- `POST /api/v1/builds` - Submit build request +- `GET /api/v1/builds/:id` - Get build status +- `DELETE /api/v1/builds/:id` - Cancel build request +- `GET /api/v1/partitions/:ref/status` - Get partition status +- `GET /api/v1/partitions/:ref/events` - Get partition events +- `POST /api/v1/analyze` - Analyze build graph ### Generated Client Structure ```typescript -// Generated types -interface PartitionRef { - str: string; +// Generated types from OpenAPI spec +interface BuildRequest { + partitions: string[]; } interface BuildStatusResponse { build_request_id: string; - status: BuildRequestStatus; + status: string; requested_partitions: string[]; created_at: number; updated_at: number; events: BuildEventSummary[]; } -// Client class +// Generated client class class BuildGraphClient { constructor(baseUrl: string); - async submitBuild(partitions: string[]): Promise<{build_request_id: string}>; + async submitBuild(request: BuildRequest): Promise<{build_request_id: string}>; async getBuildStatus(id: string): Promise; async cancelBuild(id: string): Promise<{cancelled: boolean}>; async getPartitionStatus(ref: string): Promise; async getPartitionEvents(ref: string): Promise; - async analyzeGraph(partitions: string[]): Promise<{job_graph: JobGraph}>; + async analyzeGraph(request: AnalyzeRequest): Promise; } ``` ### Bazel Integration - Create `//databuild/client:typescript` target -- Generate TypeScript files from `.proto` sources +- Generate OpenAPI spec from Build Graph Service +- Use OpenAPI Generator to create TypeScript client - Ensure hermetic build process - Output client code to `databuild/client/typescript/` ## Implementation Strategy -1. **Assess Off-the-Shelf Solutions** - - Quick evaluation of existing protobuf-to-TypeScript tools - - If complex setup required, proceed with custom implementation +1. **Add OpenAPI Generation to Service** + - Add `aide` dependency for OpenAPI spec generation + - Modify Axum service to use `aide::ApiRouter` + - Add JsonSchema derives to request/response types + - Create OpenAPI spec endpoint -2. **Custom Generator (if needed)** - - Simple Python/Rust script to parse proto and generate TypeScript - - Focus only on message types and basic field mapping - - No complex protobuf features needed +2. **OpenAPI Spec Extraction** + - Create Bazel rule to run service and extract OpenAPI spec + - Save spec as build artifact (JSON/YAML) -3. **Bazel Rules** - - Create `typescript_proto_library` rule +3. **TypeScript Client Generation** + - Add OpenAPI Generator to Bazel build system + - Create Bazel rule to generate TypeScript client from spec + - Use `typescript-fetch` generator for modern fetch-based client + +4. **Bazel Rules** + - Create `typescript_openapi_library` rule - Generate client code during build - Ensure proper dependency management ## Deliverables -- [ ] TypeScript interfaces for all relevant protobuf messages +- [ ] OpenAPI spec generation from Build Graph Service +- [ ] TypeScript interfaces for all API request/response types - [ ] Typed HTTP client for Build Graph Service endpoints -- [ ] Bazel rules for client generation +- [ ] Bazel rules for automated client generation - [ ] Documentation for using the generated client ## Success Criteria +- OpenAPI spec accurately reflects all service endpoints - Generated TypeScript compiles without errors - Client provides type safety for all API endpoints -- Bazel build integrates seamlessly +- Bazel build integrates seamlessly and generates client automatically - Ready for use in Chunk 2 (Hello World App) ## Testing +- Verify OpenAPI spec generation from service - Verify generated TypeScript compiles - Test client against running Build Graph Service -- Validate type safety with TypeScript compiler \ No newline at end of file +- Validate type safety with TypeScript compiler +- Ensure build process is hermetic and reproducible \ No newline at end of file