Skip to content

feat(overview): give analysts an Overview that says whether the product is working - #2555

Merged
Makisuo merged 10 commits into
observer/read-only-pagesfrom
observer/home
Nov 13, 2026
Merged

Makisuo merged 10 commits into
observer/read-only-pagesfrom
observer/home

Conversation

@Makisuo

@Makisuo Makisuo commented Nov 13, 2026 •

Copy link
Copy Markdown
Collaborator

Seventh and top layer of the Analyst role, on top of #2552. An analyst opening Overview got the engineers' page: a service health table, latency charts and a setup checklist. They now get a page that answers whether the product is working.

What changed

  • A verdict in one sentence. "Everything is working." or what is wrong, with numbers ("2 incidents open. 1 check failing."), and one line under it with the counts behind it.
  • Four panels, each with up to five rows that link to the real page and a footer link to the full list: open incidents, uptime checks, SLOs, and the top errors of the last 24 hours.
  • Honest on missing data. Each read has its own slot. If one fails, the verdict says that part could not be checked instead of counting it as healthy, and the rest still shows.
  • Nothing set up. The page says what is missing and that an engineer on the team can set it up. No setup controls, no sample data.
  • Two things an analyst can do next, as quiet links under the panels: build a dashboard, and get the weekly summary by email.
  • No new endpoints or queries. It reuses the reads the alerts and errors pages make.
  • How the page knows the viewer. The root passes audience in the page context, from the same role the shell reads, so the sidebar and the page always agree. A role that arrives after the page started is handled by a mount on the analyst view.
  • Investigations. An analyst follows an investigation: the diagnosis, evidence and thread, without Resolve, Run again or the follow-up composer, which the API refuses them.
  • Kit. pageTitle gains a wrap option, since a verdict sentence must wrap on a phone. The SLO "burning" rule moved to the shared module so the hub and this page use one.
  • Lab. /lab/analyst-home?state=clear|attention|empty|loading|failed.

Operators get the unchanged Overview.

Screenshots

All clear Needs attention
Nothing set up A read failed
Loading Light theme Phone

Before this layer an analyst saw the engineers' Overview here.

Verified

  • apps/web: the overview, lab, shell, dashboards, settings kit and root update tests, 665 passed; the investigations tests, 76 passed, with a scene test pairing an analyst and a member on one diagnosis. Scene tests cover all clear, incidents open with a check failing (the verdict names them and rows link to the right pages), nothing set up, one read failing, and an operator still getting the existing page. A root test covers audience following the viewer's role.
  • @maple/web typecheck, the CI lint config on every changed file, the UI class pattern check and the kit index.
  • /lab/analyst-home driven in a headless browser for the screenshots.
  • Preview run as a real analyst on a3f0e44: every check passed, results and trace readings are in the latest comment below. An earlier run found that the root view did not pass audience to the page's view; fixed in d9f7baed55 with a root scene test.

Known weak spots

  • The preview has no live sync, so open incidents with real data were only exercised from fixtures. The timeout path ("Couldn't check incidents") was exercised live.
  • With live sync down, the verdict is a skeleton for 10 seconds on every visit.
  • The Overview counts open issues, the Errors page counts raw error events, so the two can read differently ("No open errors" beside "37 error events").
  • With every kind of problem at once the verdict is four short sentences, three lines on a phone.
  • Error titles are raw exception text, which is not friendly to a non-technical reader.
  • A role changing from analyst to operator while the page stays open leaves it on skeletons until the next navigation.
  • The Incidents page also drops its New rule button for an analyst.
  • /alerts/create opens for an analyst by typed URL; nothing links there and the API refuses the save.
  • The auth provider refuses an analyst the org member list, so on-call names on the alerts pages read "Member" for them.
  • A tool approval card in an investigation thread still shows its Approve button to an analyst; the API refuses it.

…uct is working

An observer opening Overview got the engineers' page: a service health table, latency charts and a setup checklist. They now get a verdict in one sentence (Everything is working, or what is open and failing, with the counts behind it), then open incidents, uptime, SLOs and the top errors of the last 24 hours, each linking to its page, and a link to the weekly email summary.

The page reuses the reads the alerts and errors pages make. Each has its own slot, so one failing read is named in the verdict instead of being counted as healthy, and where nothing is set up the page says an engineer can do it.

The root passes the viewer's audience to pages in the page context, from the same role the shell reads, so the two always agree. Operators get the unchanged Overview.
@coderabbitai

coderabbitai Bot commented Nov 13, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 17 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used all 4 included reviews currently available.

Learn how review limits work.

Review configuration:

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 8c77ef5d-54a2-43b3-92d5-e96c07ba6904
Commits

Reviewing files that changed from the base of the PR and between ebf5352 and a3f0e44.

Files selected for processing: 34

  • apps/web/src/lab/analyst-home-fixture.ts
  • apps/web/src/lab/entries/analyst-home.ts
  • apps/web/src/lab/registry.ts
  • apps/web/src/lab/shell-frame.ts
  • apps/web/src/lab/shell-lab.ts
  • apps/web/src/lab/shell-states-lab.ts
  • apps/web/src/page/alerts/hub/analyst.scene.test.ts
  • apps/web/src/page/alerts/hub/view-slos.ts
  • apps/web/src/page/alerts/hub/view.ts
  • apps/web/src/page/alerts/shared/slo-derive.ts
  • apps/web/src/page/contract.ts
  • apps/web/src/page/investigations/conversation/view.ts
  • apps/web/src/page/investigations/detail/investigation.scene.test.ts
  • apps/web/src/page/investigations/detail/view.ts
  • apps/web/src/page/overview/analyst/analyst.scene.test.ts
  • apps/web/src/page/overview/analyst/command.ts
  • apps/web/src/page/overview/analyst/derive.ts
  • apps/web/src/page/overview/analyst/message.ts
  • apps/web/src/page/overview/analyst/model.ts
  • apps/web/src/page/overview/analyst/subscription.ts
  • apps/web/src/page/overview/analyst/update.ts
  • apps/web/src/page/overview/analyst/view.ts
  • apps/web/src/page/overview/index.ts
  • apps/web/src/page/overview/message.ts
  • apps/web/src/page/overview/model.ts
  • apps/web/src/page/overview/subscription.ts
  • apps/web/src/page/overview/update.ts
  • apps/web/src/page/overview/view.ts
  • apps/web/src/shell/index.ts
  • apps/web/src/update.audience.test.ts
  • apps/web/src/update.ts
  • apps/web/src/view.ts
  • packages/views/src/ui/page-layout.styles.ts
  • packages/views/src/ui/page-layout.ts
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

@Makisuo Makisuo added the preview:web Deploy a Workers-only PR preview (no ingest/Electric); see docs/pr-previews.md label Nov 13, 2026
@Makisuo
Makisuo deployed to pr-preview November 13, 2026 02:23 — with GitHub Actions Active
@Makisuo
Makisuo deployed to preview-tinybird November 13, 2026 02:23 — with GitHub Actions Active
@maple-review-bot

This comment has been minimized.

@maple-review-bot maple-review-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 inline notes from Maple's review. The score and summary are in the review comment above.

@github-actions

github-actions Bot commented Nov 13, 2026 •

Copy link
Copy Markdown
Contributor

🍁 Maple PR preview

Note

Preview resources were removed when this pull request closed.

Final commit a3f0e44 · View workflow run

@Makisuo
Makisuo deployed to pr-preview November 13, 2026 02:29 — with GitHub Actions Active
…r an observer

Checks that are all paused or yet to report no longer pass as everything working: the verdict says uptime could not be checked. An empty error list is called a clean day only when the app is known to send data. The incidents failure note no longer promises a Reload that does not re-read incidents, the event count keeps its noun for screen readers on a narrow page, and the engineers' live rows are not read while an observer's page is drawn.
The root view rebuilds the page context field by field and left audience out, so a page's update knew the viewer was an observer while its view did not: a real observer got the engineers' Overview on skeletons, with the observer page's reads running behind it. The lab passes the context whole, which is why only the preview run showed it. A root scene test now draws the Overview for an observer and for an admin.

The Incidents page also drops its New rule button for an observer.
@Makisuo
Makisuo deployed to preview-tinybird November 13, 2026 03:11 — with GitHub Actions Active
@Makisuo
Makisuo deployed to pr-preview November 13, 2026 03:11 — with GitHub Actions Active
@Makisuo

Makisuo commented Nov 13, 2026

Copy link
Copy Markdown
Collaborator Author

Preview run as a real observer (deploy of d734f24)

Signed in to the web preview as a throwaway user holding org:observer in the Preview org, and as the shared admin reviewer for control.

Check Result
Session roles are ["org:observer"] pass
Observer sidebar, no Sources, Settings or Connect pass
Observer Overview fail: the engineers' Overview, stuck on skeletons
Dashboards: no Create, Import, Duplicate, Delete, Edit or Share pass
Errors list readable pass (the org has no issues, so the issue page was not tested)
Palette: no Traces, Settings or Connect; finds Web analytics and Incidents pass
A direct link to /traces opens pass
GET /v2/dashboards 200, POST /v2/traces/search 200 pass
POST, PATCH, DELETE /v2/dashboards, and POST to alert rules, uptime monitors, SLOs and status pages: 403 insufficient_permissions pass
Internal issue comment: 403 ReadOnlyRoleError pass (made-up issue id, so only the role gate)
Admin control: full sidebar, engineers' Overview, Create dashboard pass

The Overview failure is fixed in d9f7baed55. The root view rebuilt the page context field by field and left audience out, so the page's update knew the viewer was an observer and its view did not. The lab hands the context over whole, which is why only this run showed it. A root scene test now covers it. The same commit removes the New rule button the run found on an observer's Incidents page. A re-run on the new deploy follows.

Also seen, not fixed in this stack: Web analytics, Replays and Users show setup prompts written for engineers; the Incidents page's breadcrumb still says Alerts; /settings, /sources and /services open from a typed URL (the API refuses every change there).

Sidebar (and the Overview bug) Dashboards
Palette Admin control

@maple-review-bot

This comment has been minimized.

@Makisuo
Makisuo deployed to pr-preview November 13, 2026 03:13 — with GitHub Actions Active
@Makisuo

Makisuo commented Nov 13, 2026

Copy link
Copy Markdown
Collaborator Author

Preview re-run as a real observer (deploy of d9f7bae): all checks pass

Check Result
Observer Overview: verdict heading, four panels, weekly summary link pass
Overview reads: uptime monitors, SLOs, SLO statuses, error issues, errors by type, all 200, none of the engineers' reads pass
Incidents page has no New rule button pass
Admin control: engineers' Overview with data, New rule present pass
Phone width (390 px): no overflow, nothing clipped pass
Weekly summary link opens email preferences, and an observer can turn the digest off and on (200) pass

This preview has no live sync, so the incident read times out after 10 seconds. The page handles it as designed: the heading is a skeleton until then, then reads "No problems found, but incidents couldn't be checked." and the panel says "Couldn't check incidents".

Overview Incidents
Phone Email preferences

Traces from the preview (deployment.environment = pr-2555, service maple-api)

p95 over the test window, for the requests an observer's Overview makes. They run in parallel.

Request p95
POST /internal/query-engine/errors-by-type 632 ms
GET /v2/error_issues 375 ms
GET /v2/slos 359 ms
  • These are the reads the Errors and SLO pages already make; nothing new was added, and no serial waterfall.
  • The read-only gate adds no I/O. It checks the role and an annotation in the auth layer, with no span of its own.
  • The observer's refused writes do not show as errors, as intended: the 403 is registered as an anticipated error. The only errors recorded for the API in the window are two DigestNotConfiguredError (501) from pressing Preview on the digest, because the preview has no email delivery configured.

Still open from the run, not fixed in this stack: the Overview says "No open errors in the last 24 hours" while the Errors page counts 37 error events with no issues; the email preferences switches show on before anything is saved; the org switcher offers "Create organization" to an observer; the Incidents breadcrumb still says Alerts.

# Conflicts:
#	apps/web/src/lab/shell-states-lab.ts
#	packages/domain/src/policy/roles.ts
…its controls

An analyst reads the diagnosis, evidence and thread. The status actions and the follow-up composer are left out for them, since the API refuses both.
@Makisuo
Makisuo deployed to preview-tinybird November 13, 2026 11:34 — with GitHub Actions Active
@Makisuo Makisuo changed the title feat(overview): give observers an Overview that says whether the product is working feat(overview): give analysts an Overview that says whether the product is working Nov 13, 2026
@maple-review-bot

maple-review-bot Bot commented Nov 13, 2026 •

Copy link
Copy Markdown

Maple review

🟢 Confidence 10/10 · safe to merge. Verdict derivation is unit-pinned and every read state (clear, attention, empty, loading, failed+retry) has a scene test; only the tail of the new scene test went unread.
no findings · tests covered · risk medium

An analyst now gets a verdict page on Overview: one sentence with the counts behind it, four linked panels and a failure slot per read, gated on the audience the shell already reads. Web-only and contained; safe to merge.

  • verdictOf derives clear, attention, empty, loading and per-read-failed states from three slots
  • initWith/revive require context.audience; a late-arriving role mounts and starts the reads
  • pageTitle gains wrap, and the SLO burning rule moves to alerts/shared/slo-derive.ts
  • Alerts hub and investigation detail drop their write controls for an analyst

a3f0e44 · What was checked, coverage and telemetry details are on the Maple / review check. Reply "won't fix" to dismiss a finding, or mention @maple-review-bot to ask about one.

@Makisuo
Makisuo deployed to preview-tinybird November 13, 2026 11:46 — with GitHub Actions Active
@Makisuo
Makisuo deployed to pr-preview November 13, 2026 11:47 — with GitHub Actions Active
@Makisuo
Makisuo deployed to pr-preview November 13, 2026 11:49 — with GitHub Actions Active
@Makisuo

Makisuo commented Nov 13, 2026

Copy link
Copy Markdown
Collaborator Author

Preview run as an analyst (a3f0e44, 2026-11-13 11:51 to 12:11 UTC)

Run by a separate tester in a headless browser, signed in as a throwaway user holding org:analyst in the Preview org, with the admin reviewer as control.

Check Result
Session carries org:analyst; analyst sidebar, no Services, Sources, Settings or Connect Pass
Overview: verdict, four panels, "Build a dashboard" and the weekly summary link Pass
Dashboards as an analyst: create, add a funnel widget, rename, public share link, restore a version, delete Pass, all 200
A public share link opens with no session and renders the funnel widget Pass
Still refused: new SLO, alert rule, uptime monitor, status page, API key, issue transition and claim Pass, all 403 with the analyst message, nothing created
Investigation chat: history 200, follow-up 403, stop 403 Pass (route probed with a made-up session id)
No "New rule" on Incidents, no selection on Errors, /traces opens by URL Pass
Admin control: engineers' Overview, full sidebar, role picker lists Analyst, Member, Engineer, Admin Pass
Phone width (390 px): no horizontal scroll on Overview and Dashboards Pass
Console and network: no page error, no 5xx Pass

Not exercised on this preview

  • Creating and editing a dashboard through the UI. A web-only preview has no live sync, so the dashboard pages disable editing for every role, admin included. The six writes above were sent from the signed-in page instead; sharing was done through the real Share dialog. The dashboard pages are unchanged from main in this stack.
  • An investigation's detail page as an analyst: the Preview org has no investigation. A scene test covers it.

Found on the run, not fixed here

  • /alerts/create opens for an analyst by typed URL and shows the rule form. Nothing links there and the API refuses the save.
  • For an analyst the auth provider refuses the org member list (403), which the alerts pages use to name who is on call. The page falls back to "Member". Giving the role the provider's "read members" permission would fix it.

Traces (environment pr-2555, service maple-api, same window)

  • No trace with an error. The analyst's 403s are not recorded as errors.
  • Dashboard writes: PATCH 35 to 234 ms, PUT share 23 ms, DELETE 18 to 167 ms. Of 40 sampled POSTs the median is about 85 ms.
  • Slowest request: 2.25 s, the tester's history read of a chat session that did not exist, a cold start of that session's object.

@Makisuo
Makisuo added this pull request to stack #2556 November 13, 2026 12:45
@Makisuo
Makisuo merged commit 4f0c7f4 into main Nov 13, 2026
32 of 48 checks passed
@Makisuo
Makisuo deployed to pr-preview November 13, 2026 12:56 — with GitHub Actions Active
@Makisuo
Makisuo deployed to preview-tinybird November 13, 2026 12:56 — with GitHub Actions Active
@Makisuo
Makisuo deleted the observer/home branch November 13, 2026 12:56

This branch was successfully deployed

2 active deployments
preview-tinybird — a3f0e445 Deployed Nov 13, 2026 by Makisuo via branch #1405
pr-preview — a3f0e445 Deployed Nov 13, 2026 by Makisuo via deploy-pr-preview #11828
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

preview:web Deploy a Workers-only PR preview (no ingest/Electric); see docs/pr-previews.md

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant