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.
From #2200 deep-review (heatmap external API)
Two P2 findings deferred from the in-flight #2200 + #2199 work.
Out of scope here (already tracked)
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.
containers. Decide between propagatingcontainersthrough the LIST endpoint vs explicitly documenting the per-doc cap that ships in feat(external-api): round-trip dashboard containers, tabs, and tile container/tab refs #2201. The internalDashboard.containersfield is queryable but the external LIST endpoint currently strips it.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.From #2200 deep-review (heatmap external API)
Two P2 findings deferred from the in-flight #2200 + #2199 work.
convertTileToExternalChart's heatmap arm returnsundefinedfor malformed/legacy stored docs and the caller falls through todefaultTileConfig, which is hardcodeddisplayType: 'line'. A GET → mutate → PUT round-trip on a corrupt heatmap silently persists the loss ofdisplayType: 'heatmap'. Sibling Number/Pie/Table arms preservedisplayTypeunder the same kind of corruption. Either substitute a heatmap-shaped default or drop the tile entirely rather than morphing it.kindis 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, becausegetHeatmapTilesWithIncompatibleSourcesre-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)
hyperdx_save_dashboard: see External Dashboards API: expose containers and tabs in MCP hyperdx_save_dashboard #2212.