hyperdxio / hyperdxio/hyperdx

External dashboards API: deferred follow-ups from #2200 + #2201 deep-reviews

Open
#2,236 0 comments 0 reactions 1 assignee View on GitHub

@alex-fedotyev is already working on this.

Since May 7, 2026.

api enhancement p2
Dominant language
TypeScript
Stars
9.9k
Forks
471
Avg merge
2d 4h
Merged PRs (30d)
117

Description

Tracking the deferred follow-ups from the deep-review on #2201 (containers + tabs) and #2200 (heatmap external API).

From plan-06b9fd33 (containers + tabs, post-#2201 merge)

These were intentionally deferred during #2201 because they reshape behavior in ways that need a separate decision.

  • LIST projection includes containers, P1 payload risk at scale. Origin: deep-review on #2201, 2026-05-06 (cite packages/api/src/routers/external-api/v2/dashboards.ts:1398): "LIST endpoint now selects containers for every dashboard. Worst case ≈310KB × 200 dashboards = ~62MB JSON per LIST → drop containers from EXTERNAL_DASHBOARD_PROJECTION and require GET-by-id to read it (or paginate LIST)." The merged code on main still has containers: 1 in EXTERNAL_DASHBOARD_PROJECTION (used by both Dashboard.find and Dashboard.findOne); live verification on 2026-05-12 confirms LIST returns containers on a small dataset, but small-data behavior doesn't resolve a payload-size P1. Decide: (a) drop containers from the projection and require GET-by-id; (b) keep on LIST, add pagination and a documented per-dashboard cap; (c) conditional projection at a response-size threshold. Earlier wording on this bullet said "LIST currently strips it"; that was my own error and contradicts merged code.
  • containers: [] round-trip. Today an empty containers array on PUT is preserved as-is on read; should an explicit empty array be rejected at validation, or treated equivalent to absent? Either is defensible; pick one and pin it with a regression test.
  • Optimistic concurrency on PUT. The dashboard PUT endpoint accepts last-writer-wins. If two clients edit the same dashboard the second write silently overwrites the first. Bigger than #2201's scope but worth tracking.

From #2200 deep-review (heatmap external API)

Two P2 findings deferred from the in-flight #2200 + #2199 work.

  • Heatmap GET on a malformed Mongo doc silently rewrites to line. convertTileToExternalChart's heatmap arm returns undefined for malformed/legacy stored docs and the caller falls through to defaultTileConfig, which is hardcoded displayType: 'line'. A GET → mutate → PUT round-trip on a corrupt heatmap silently persists the loss of displayType: 'heatmap'. Sibling Number/Pie/Table arms preserve displayType under the same kind of corruption. Either substitute a heatmap-shaped default or drop the tile entirely rather than morphing it.
  • Source-kind change wedge. A source whose kind is later changed from Trace to another kind (the v1 source-update endpoint allows this with no dashboard-tile check) wedges every subsequent dashboard PUT, even when editing an unrelated tile, because getHeatmapTilesWithIncompatibleSources re-runs over the round-tripped tiles on every write. Either block source-kind changes when a heatmap tile references the source, or scope the PUT-time check to tiles that actually changed in this request.

Out of scope here (already tracked)

  • Containers/tabs in MCP hyperdx_save_dashboard: see #2212.
  • MCP gate + prompt for heatmap: see #2199 (currently draft, lands after #2200).

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.