# ADR: Web UI and API Tech Stack **Status**: Proposed **Date**: 2026-06-26 **Updated**: 2026-06-28 **Authors**: ICT Team **Technical Area**: Web Frontend, REST API, Developer Tooling **Related**: [OpenAPI Spec](../../api/v1/openapi-template-builder.yaml), [UI Prototype](../../web/prototype/template-builder.html) --- ## Summary This ADR defines the technology stack for the ICT web-based template builder UI and its backing REST API. The interactive prototype at `web/prototype/template-builder.html` serves as the design reference — the production implementation will replicate its three-tab layout (Basic, Advanced, Build Image) using the stack defined here. --- ## Context ### Problem Statement ICT needs a web interface that lets users compose image templates for different industry verticals and custom configurations. The UI must: 1. Provide a guided **Basic** flow where users pick a targeted vertical (Robotics, Physical AI, Agentic AI, Health, Fed Aero, Industrial IoT, Retail Edge, or Generic), SKU, platform (PTL/WCL/ARL/NVL), and OS — with vertical-specific defaults auto-applied 2. Provide an **Advanced** tab for power users to customize image type (RAW/ISO/QCOW), package repositories, packages, and disk/partition layout — with a live YAML preview 3. Provide a **Build Image** tab that streams build logs via SSE and lists output artifacts (Image + SBOM) 4. Be served from a single Go binary (one deployment artifact) ### Architecture Principles - **Separate UI intent from ICT execution** — UI captures user intent in product language; backend translates to ICT templates - **No YAML in Basic** — Basic tab uses product-level concepts only (verticals, SKUs, platforms) - **YAML in Advanced** — power users get live YAML preview and export capability - **Basic → Advanced sync** — switching from Basic to Advanced pre-populates all selections automatically ### Reference Prototype The file `web/prototype/template-builder.html` demonstrates the exact views and interactions: | Tab | Production Component | Key Interactions | |-----|---------------------|------------------| | **Basic** | `` | Targeted Vertical dropdown (Generic + 7 verticals), SKU dropdown (vertical-specific), Platform dropdown (PTL/WCL/ARL/NVL), OS dropdown with "-- Select Operating System --" placeholder, "Review Image Configuration" checkbox expanding summary table (Image, Vertical, SKU, Platform, OS, Image Type, Disk, Packages). Any config change auto-unchecks review. | | **Advanced** | `` | Step wizard. MVP-1 steps: Target (same as Basic + Image Type/Name), Packages (repos + search/add), Disk (size/partitions), Review (summary + Validate + Export YAML + Build). Live YAML preview panel on right. More steps may be added later. | | **Build Image** | `` | Streaming log viewer (SSE) with "Build Status" title, artifacts table (Image + SBOM with copy-path icon) | ### Constraints - **Single binary deployment**: The compiled React frontend (static HTML/JS/CSS from `web/dist/`) is embedded into the Go binary via `embed.FS` and served by the same process that serves the API. Shipping and running ICT means shipping and running one executable — no separate web server, container, or Node.js runtime is required at deploy time. - **Existing Go stack**: reuse what ICT already depends on — `net/http`, `cobra`, `jsonschema/v5`, `zap`, `yaml.v3`. - **Team expertise**: Go-primary team, moderate frontend experience. - **Corporate proxy**: SSE (not WebSocket) for real-time streaming. --- ## Decision ### Architecture Diagram ![Tech Stack Architecture](assets/web-ui-tech-stack.svg) ### Data Flow Diagram ![Template Builder Data Flow](assets/web-ui-data-flow.svg) ### Sequence Diagram — Basic flow Basic is a pure lookup: selections → matched template → build. No YAML editing, no client-side template model. ```mermaid sequenceDiagram autonumber actor U as User (Browser) participant SPA as React SPA participant API as API (internal/api) participant M as manifest + image-templates/ participant ICT as ICT binary (os/exec) Note over U,ICT: Load options SPA->>API: GET /manifest API->>M: load manifest (all combinations + labels) M-->>API: full manifest API-->>SPA: JSON → populate dropdowns (cascade locally) U->>SPA: select vertical / SKU / platform / OS Note over U,ICT: Review (optional) U->>SPA: check "Review Image Configuration" SPA->>API: POST /templates/compose {selections} API->>M: lookup template by combination M-->>API: matched template YAML API-->>SPA: summary (image, packages, disk, …) Note over U,ICT: Build U->>SPA: clicks Build Image SPA->>API: POST /builds {compose} API->>M: resolve matched template file API->>ICT: os/exec image-composer-tool build