Skip to content

feat(errors): one triage hub, and an issue page that says where the error is - #538

Merged
Makisuo merged 2 commits into
mainfrom
feat/errors-triage-hub-and-issue-detail
Aug 19, 2026
Merged

feat(errors): one triage hub, and an issue page that says where the error is#538
Makisuo merged 2 commits into
mainfrom
feat/errors-triage-hub-and-issue-detail

Conversation

@Makisuo

@Makisuo Makisuo commented Aug 19, 2026

Copy link
Copy Markdown
Collaborator

Why

/errors grouped error events by fingerprint and knew nothing about triage. /errors/issues listed the same fingerprints out of Postgres and knew nothing about volume. The investigation lived on a third route.

They were always the same objects — the warehouse groups by FingerprintHash, and error_issues is keyed on that same hash — so no single view could answer a triage question on its own, and the detail page you landed on read like a different product from the list you came from.

The list

One list, joined on the fingerprint. A row is an ErrorSignal: the issue row as the spine (it covers every fingerprint and carries the triage facts), warehouse volume and trend joined on, and one status slot resolved by precedence — open incident › live investigation › workflow state — replacing the four badge systems a row used to carry.

  • Volume-ranked lists run warehouse-first; the other sorts run issue-first, because Postgres already orders them and the warehouse only knows about the window.
  • The four KPI cards became one inline stat line. They took the top third of the page to say what fits on one line and pushed the list below the fold.
  • Row sparklines are one static <svg> each, not a chart runtime — fifty rows would otherwise mean fifty of them.
  • /errors/issues redirects, carrying its old workflowState tab across to the equivalent view.

The detail page

  • Header. Five badges, a primary button and an overflow menu sat flat in one actions row, so nothing had precedence. Identity chips move into the title stack; the status collapses to the same chip the list uses; the actions slot keeps one labelled action and one menu.
  • It never said where the error was. topFrame and fingerprintHash were on the wire and drawn nowhere — the only thing that ever read them was the investigation snapshot, so the page that exists to answer what broke and where briefed the agent with a stack frame it never showed you. Both are now the block under the title, and the exception message is promoted out of muted caption into the page's primary text.
  • It had no time range. The endpoint takes start_time / end_time / bucket_seconds / sample_limit; the page called it with {} and then labelled a number "Events (window)" for a window nobody chose — reached from a list that does have a picker. Wired now: the chart, the samples and the count move together.
  • Seven equal-weight sections in one stack become Overview / Occurrences / Activity, tabbed through ?tab=.
  • Fix history was thrown away. regressionCount, lastRegressedAt, lastResolvedAt, resolvedVersions and snoozeUntil were decoded on every load and shown nowhere, so the page could not answer the question the workflow exists for: did the fix hold.

Also in here

  • errorsSpark — bucketed counts for many fingerprints at once, pivoted server-side, plus an errorLabels sidebar facet.
  • The occurrence chart is bars, tinted by severity. The series is a count per discrete bucket, and the old filled area interpolated straight through buckets with no errors, so silence read as steady traffic.
  • One panel vocabulary across the page, the rail stops re-declaring the width and border PageLayout.RightSidebar already applies, and the activity timeline's ml-16/-left-16 magic-number pair is a real grid gutter.
  • /errors/$errorType is deleted — unreachable since the list rewrite — along with the two atoms and the one query it was the last consumer of. getErrorDetailTraces stays; the dashboard builder still exposes it as a widget data source.

Verification

  • bun typecheck clean; oxlint --quiet clean.
  • @maple/web 195 files / 1727 tests green; @maple/query-engine and @maple/api green.
  • Browser-verified against the local stack: the header chip, the time picker driving chart + samples + count together, the culprit block above the fold, ?tab= surviving reload, an alert-kind issue correctly losing its Occurrences tab, the rail, the breadcrumb, <lg layout and light mode.

Pre-existing failure, not from this branch: packages/domain openapi.test.ts and openapi-ios.test.ts fail on the two mobile_devices/{token}/live_activities/{incident_id} paths. mobile-devices.ts is untouched here and those endpoints landed in 27b62bc067 without the committed-paths assertion being updated.


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

…rror is

`/errors` grouped error events by fingerprint and knew nothing about triage;
`/errors/issues` listed the same fingerprints from Postgres and knew nothing
about volume; the investigation lived on a third route. They were always the
same objects — the warehouse groups by FingerprintHash and `error_issues` is
keyed on that same hash — so no single view could answer a triage question.

They are now one list. A row is an `ErrorSignal`: the issue row as the spine,
warehouse volume and trend joined on the hash, and one status slot resolved by
precedence (open incident › live investigation › workflow state) in place of the
four badge systems a row used to carry. `/errors/issues` redirects, carrying its
old `workflowState` tab across to the equivalent view.

The detail page never got that treatment and read as a different product:

- Five badges, a primary button and an overflow menu sat flat in one actions
  row. Identity chips move into the title stack and the status collapses to the
  same one chip the list uses, leaving one labelled action plus one menu.
- `topFrame` and `fingerprintHash` were on the wire and drawn nowhere — only the
  investigation snapshot ever read them, so the page that exists to answer "what
  broke and where" never named a line of code. Both are now the block under the
  title, and the exception message is promoted out of muted caption.
- The endpoint takes start_time/end_time/bucket_seconds/sample_limit and the
  page called it with `{}`, so the chart and the samples described a window
  nobody chose, reached from a list that has a time picker. It is wired now.
- Seven equal-weight sections in one stack become Overview / Occurrences /
  Activity, tabbed through `?tab=`.
- regressionCount, lastRegressedAt, lastResolvedAt, resolvedVersions and
  snoozeUntil were decoded every load and shown nowhere, so the page could not
  answer the question the workflow exists for: did the fix hold.

Also: `errorsSpark` (bucketed counts for many fingerprints, pivoted server-side)
and an `errorLabels` facet; the occurrence chart becomes bars, tinted by
severity, because the series is a count per discrete bucket and the old filled
area interpolated straight through silence; and `/errors/$errorType` is deleted
along with the two atoms and the one query it was the last consumer of.
The errors triage hub added a fingerprint_hash filter, an errors spark
query, and a version facet; the Live Activity commit added two routes.
Each has a committed artifact that has to move with it, and none did:

- the pruned iOS OpenAPI document (quality shard),
- the v2 path and iOS operation freeze lists,
- the verbatim SQL catalog baseline — the diff is exactly the new spark
  query and the version facet, nothing else.

Also drops the dead code the hub left behind (kind-badge, the
single-fingerprint errors timeseries query superseded by the spark
query, two unused re-exports) and a knip entry pattern for a
packages/domain/scripts directory that does not exist.
@Makisuo
Makisuo merged commit 0432f69 into main Aug 19, 2026
29 of 31 checks passed
@Makisuo
Makisuo deleted the feat/errors-triage-hub-and-issue-detail branch August 19, 2026 12:33
@Makisuo
Makisuo deployed to pr-preview August 19, 2026 12:33 — with GitHub Actions Active
@github-actions

Copy link
Copy Markdown

🍁 Maple PR preview

Note

Preview resources were removed when this pull request closed.

Final commit 2224e23 · View workflow run

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