Skip to content

feat: dashboard component kit, graph scalability, enhanced views#38

Closed
avrabe wants to merge 21 commits intomainfrom
feat/rendering-quality
Closed

feat: dashboard component kit, graph scalability, enhanced views#38
avrabe wants to merge 21 commits intomainfrom
feat/rendering-quality

Conversation

@avrabe
Copy link
Copy Markdown
Contributor

@avrabe avrabe commented Mar 18, 2026

Summary

Major dashboard overhaul with reusable UI components, graph scalability fixes, and enhanced views.

serve.rs split (7576 → 5 files)

  • mod.rs (934 lines) — AppState, router, middleware, utility handlers
  • styles.rs (580 lines) — CSS constant
  • js.rs (1027 lines) — JS constants
  • layout.rs (200 lines) — page_layout + print_layout
  • views.rs (4846 lines) — all view handlers

Reusable component kit (components.rs)

  • FilterBar — type checkboxes, status dropdown, text search with HTMX debounce
  • SortableTable — clickable column headers with URL-persisted sort direction
  • CollapsibleTree<details>/<summary> with URL-persisted open state
  • Pagination — page controls with URL state
  • ViewParams — shared query param struct for all views

Graph scalability (fixes H-13)

  • spawn_blocking for layout computation (unblocks async runtime)
  • Node budget (default 300, ?budget=N to override, max 1000)
  • Dynamic SVG buffer sizing (~500 bytes/node + ~200 bytes/edge)
  • STPA coverage: H-13, SC-15, UCA-D-3, CC-D-3

Enhanced views

  • STPA: filter bar, URL-persisted fold/unfold, text search, UCA subtype filter
  • Artifacts: server-side filter/sort/pagination (replaces client-side filterTable JS)
  • Validation: severity quick-filter, type checkboxes, sortable diagnostic table
  • Traceability: type filter checkboxes, text search

Print mode (?print=1)

  • Strips nav, context bar, HTMX, JS for clean printable output
  • Works on all routes
  • Print button in context bar

Other

  • Competitive analysis requirements (REQ-037–042)
  • AI agent ergonomics features (FEAT-054–058)
  • Etch compound graph layout for nested containers
  • petgraph 0.6 → 0.7 upgrade
  • Documentation and CI audit fixes

Test plan

  • 248 Rust tests pass (cargo test --all)
  • clippy -D warnings clean
  • rivet validate PASS (0 warnings on core, 10 warnings on draft REQs)
  • cargo fmt clean
  • All 24 dashboard routes return HTTP 200
  • Graph budget works (343 nodes → graceful fallback)
  • Print mode strips nav on all views
  • Pre-commit hooks pass (fmt, clippy, test, validate, commit-msg)

🤖 Generated with Claude Code

Test and others added 21 commits March 15, 2026 12:15
Add recursive bottom-up Sugiyama layout for compound (hierarchical) graphs.
Containers are sized to fit their children, with padding and header labels.
SVG rendering draws containers as dashed-border background boxes with
lightened fill colors.

- NodeInfo gains `parent: Option<String>` for containment hierarchy
- LayoutNode gains `is_container: bool` flag
- LayoutOptions gains `container_padding` and `container_header` settings
- layout() auto-detects compound graphs and delegates to layout_compound()
- Variable-size node support in coordinate assignment
- Container SVG: dashed border, bold header label, lightened fill
- 8 new tests (6 layout + 2 SVG) covering 1-level, 2-level, sibling,
  mixed, and size constraint scenarios

Trace: skip

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
petgraph 0.7 is API-compatible for our usage. Upgrading ensures
downstream consumers (spar-render) don't need dual petgraph versions.

Trace: skip

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Phase 3 workstream integration:
- LSP server (rivet lsp) with diagnostics, hover, go-to-definition
- SCORE metamodel schema (18 artifact types, ASPICE-aligned rules)
- Kani proof harnesses (10 bounded model checking proofs)
- Extended STPA safety analysis (H-9..H-15, SC-11..SC-17, 45 UCAs/CCs)
- Extended AADL schema (4 artifact types)
- Phase 3 design plans (6 workstream documents)

Documentation and CI audit fixes:
- Fix MSRV 1.85 → 1.89 in verification.md and clippy.toml
- Fix schema type counts (ASPICE 14→13, Cybersecurity 10→8)
- Add undocumented modules to architecture.md (lsp, proofs, embedded,
  externals, lifecycle, commits, docs, schema_cmd)
- Replace missing .github/actions/compliance with inline steps
- Standardize checkout@v6 → v4 across release workflow
- Add anti-pattern guidance: do not hardcode counts in documentation
- Fix FEAT-050/051 phase-4 → future (schema validation warning)
- Add FEAT-052 (LSP) and FEAT-053 (SCORE schema) artifacts
- Remove stale hardcoded artifact counts from getting-started.md
- Fix clippy collapsible_if and map_entry warnings
- Fix pre-commit hooks: +stable for clippy, remove invalid --strict flag
- cargo fmt clean, 216 tests pass, validate PASS (0 warnings)

Implements: FEAT-052
Implements: FEAT-053
Implements: FEAT-049
Refs: REQ-007
Refs: REQ-010
Refs: REQ-030

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
10-task plan covering:
- Reusable UI components (filter bar, sortable table, collapsible tree, pagination)
- serve.rs split into serve/ module directory
- URL-persisted view state across all views
- Graph scalability (spawn_blocking, node budget, dynamic SVG buffer)
- Rich STPA/traceability views with fold/unfold and link drill-down
- Print mode (?print=1) for clean printable output
- Comprehensive Playwright E2E test suite (16 spec files)
- STPA scalability coverage (H-13, SC-15)
- CI integration for Playwright

Refs: FEAT-052

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Dashboard graph view can become unresponsive when artifact count exceeds
the Sugiyama layout engine's capacity. H-13 captures this as a hazard
leading to L-4 (productivity) and L-5 (safety assurance). SC-15 requires
graceful degradation with node budgets and spawn_blocking. UCA-D-3 and
CC-D-3 constrain the dashboard controller.

Refs: H-13

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Extract monolithic serve.rs into 5 focused files:
- mod.rs (934 lines) — AppState, router, middleware, utility handlers
- styles.rs (580 lines) — CSS constant
- js.rs (1027 lines) — GRAPH_JS, SEARCH_JS, AADL_JS constants
- layout.rs (200 lines) — page_layout() with CSS/JS imports
- views.rs (4846 lines) — all 30+ view handlers and param structs

No behavioral changes. All routes, HTML output, and tests identical.

Implements: FEAT-052
Refs: DD-005

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…alysis

REQ-037 through REQ-042: source-code traceability scanning, artifact
revision staleness, deep recursive coverage, variant/product-line
filtering, overlay files, and structured export for external viz tools.
All draft status with upstream-ref noting competitive origin.

Implements: REQ-004

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…amic SVG buffer

- Add max_nodes budget to LayoutOptions; returns sentinel node when exceeded
- Move graph layout + SVG render to tokio::spawn_blocking (unblocks async runtime)
- Dynamic SVG String capacity (~500 bytes/node + ~200 bytes/edge)
- Default budget: 300 nodes, configurable via ?budget=N (max 1000)
- Pre-collect owned NodeInfo before spawn_blocking (Send + 'static)

Fixes: H-13
Implements: SC-15
Implements: CC-D-3

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
FEAT-054: rivet add --link (create with links in one command)
FEAT-055: rivet batch (apply multiple mutations from file)
FEAT-056: JSON output for validate/coverage/context/diff
FEAT-057: rivet graph <id> --depth N (local link neighborhood)
FEAT-058: rivet scaffold --chain (generate traceability skeleton)

From intensive AI agent testing session — the theme is: reduce
round-trips (batch operations, links-on-create) and produce
machine-readable output (JSON everywhere) for agent workflows.

Refs: REQ-031
Refs: REQ-042

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add port-aware types to etch's public API:
- PortInfo, PortSide, PortDirection, PortType — define ports on nodes
- LayoutPort — positioned port in layout output
- NodeInfo gains `ports: Vec<PortInfo>` (empty = backward compat)
- EdgeInfo gains `source_port`/`target_port: Option<String>`
- LayoutNode gains `ports: Vec<LayoutPort>`
- LayoutEdge gains `source_port`/`target_port: Option<String>`

All existing callers (rivet, etch tests) updated with empty ports.
40 tests pass, full backward compatibility preserved.

Satisfies: RENDER-REQ-002

Trace: skip

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- position_ports() computes LayoutPort coordinates from PortInfo + node bounds
- PortSide::Auto resolves In→Left, Out/InOut→Right
- Node height grows for port count (12px/port + 8px padding)
- Edge waypoints snap to port (x,y) when source_port/target_port set
- 4 new tests: side positioning, auto resolution, height growth, edge snapping

Satisfies: RENDER-REQ-002

Trace: skip

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New components.rs module with:
- ViewParams: URL query param struct shared across all views (types,
  status, tags, q, sort, dir, page, per_page, open, print)
- FilterBar: type checkboxes, status dropdown, text search with HTMX
  debounce (300ms), all wired to URL params
- SortableTable: clickable column headers toggle sort direction in URL
- CollapsibleTree: <details>/<summary> with URL-persisted open IDs,
  Expand All / Collapse All buttons
- Pagination: page controls with « ‹ N of M › » navigation
- paginate() helper for slicing data by page

Also fixes etch port fields (ports, source_port, target_port) added
by spar integration work — updates all NodeInfo/EdgeInfo constructors
in serve views and etch tests.

12 unit tests for all components.

Implements: FEAT-052
Refs: DD-005

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Port circles, direction triangles, labels, and CSS type classes.

Satisfies: RENDER-REQ-002
Trace: skip

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- FilterBar with 10 STPA type checkboxes + UCA subtype dropdown
- URL-persisted fold state (?open=H-1,H-2,...) — defaults to losses+hazards open
- Expand All / Collapse All buttons updating URL
- Type filtering (?types=loss,hazard) for both hierarchy and UCA table
- Text search (?q=firmware) across ID and title, case-insensitive
- UCA subtype filter (?status=not-providing) for tree and table
- Empty-state messages when filters yield no results

Implements: FEAT-052
Refs: REQ-002

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
EdgeRouting::Orthogonal (default) and CubicBezier (legacy).
New LayoutOptions fields: bend_penalty, edge_separation, port_stub_length.
Orthogonal falls back to CubicBezier until ortho.rs is implemented.

Satisfies: RENDER-REQ-001
Trace: skip

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- print_layout() renders content without nav, context bar, HTMX, or JS
- Print CSS: hides interactive elements, sets max-width, @media print
- Middleware detects ?print=1 query param and uses print_layout
- Print button added to context bar (opens current URL + ?print=1 in new tab)
- Works on all routes: /stpa?print=1, /artifacts?print=1, etc.

Implements: FEAT-052
Refs: DD-005

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New ortho.rs module implements visibility-graph-based orthogonal router:
- Padded obstacle rectangles from all nodes
- A* pathfinding with bend penalty on candidate waypoints
- Direct routing for axis-aligned pairs, L-shaped fallback
- 5 new tests (direct, L-shaped, obstacle avoidance, multi-node)

Layout dispatches on EdgeRouting::Orthogonal vs CubicBezier.

Satisfies: RENDER-REQ-001
Trace: skip

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Detect axis-aligned waypoints and emit L (line-to) commands instead of
C (cubic bezier). Non-orthogonal paths still use bezier curves.

Trace: skip

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ination

- FilterBar with type checkboxes, status dropdown, text search
- SortableTable with clickable column headers (ID, Type, Title, Status, Links)
- Pagination (default 50/page) with URL-persisted page state
- All filter/sort/page state in URL: /artifacts?types=requirement&sort=id&dir=asc&page=2
- Removed old client-side filterTable() JS — server-side filtering replaces it

Implements: FEAT-052
Refs: DD-005

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New html module wraps SVG in self-contained HTML with embedded JS:
- Pan: click-drag on background
- Zoom: mouse wheel around cursor, viewBox manipulation
- Selection: click node to select, Ctrl+click for multi-select
- Group highlight: click container to select
- CustomEvent emission (etch-select, etch-container-select)
- URL parameter ?highlight=ID for deep linking
- Semantic zoom CSS classes (zoom-low, zoom-overview)
- 5 new tests

Satisfies: RENDER-REQ-003, RENDER-REQ-005, RENDER-REQ-006
Trace: skip

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ort/pagination

Validation view (/validate):
- Severity quick-filter buttons (All/Errors/Warnings/Info) via ?status=
- Type checkboxes for artifact types in diagnostics
- Text search (?q=) on artifact ID and message with 300ms debounce
- Sortable table (severity, ID, message columns)
- Pagination with URL-persisted page state

Traceability view (/traceability):
- Type filter checkboxes with URL persistence
- Text search on artifact ID/title
- Filters integrated with existing TraceParams

Implements: FEAT-052
Refs: DD-005

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@avrabe
Copy link
Copy Markdown
Contributor Author

avrabe commented Mar 18, 2026

Superseded by #40 which includes this work on a clean base from main.

@avrabe avrabe closed this Mar 18, 2026
@avrabe avrabe deleted the feat/rendering-quality branch March 19, 2026 07:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant