← Admin Panel

Notifications — feed

admin panel · wireframes · notifications

What the admin reads on clicking the bell: the in-app feed — a personal slice of delivered events, read state, actions. Channels, routes and types live on the notification settings screen; the delivery mechanics live in the dispatcher.

Bell and panel → Top bar
in-app · into the feed
  1. 1 The bell with an unread count — the current admin's number of unread in-app deliveries (deliveries with read_at IS NULL). The count updates instantly over the push channel (SSE), with polling as a background top-up. The in-app channel is locked on, so the bell is always present — feed = notifications ⋈ deliveries.
  2. 2 The panel — the tail of recent events, opened from the bell on click. “Mark all read” sets read_at on all of the admin's deliveries at once; the gear leads to the settings for channels and routes (edited by Owner only).
  3. 3 Dedup — a series of same-type failures collapsed into one notification with a ×N counter, not N rows. The key and window — the dispatcher's throttling.
  4. 4 Discovery is the only actionable type: “Add to scope” straight from the feed brings the container into the source's scope (payload in notifications.meta). The event is shared across all Owners / Admins, and the action is global, so it is idempotent: the source of truth for scope is the Harvester allow-list; if the container is already in scope, a repeat does nothing and the “Add to scope” button dims for everyone. The notification itself does not store the action's state — the journal is not mutated for it. It lives only in the “Selected only” scope mode; in “Everything” mode the object is picked up on its own — then it is just info.
  5. 5 “Show all” leads to the full screen — with history, filters and marking read one by one. The panel shows only the top.
  6. This is the Admin Panel feed — for Owner / Admin, the recipients of organization alerts. A member employee has their own feed of personal notifications in the Web App (agent runs, role changes) — the same dispatcher, a different view.
Full screen — Inbox → Data model
notification inbox
achilles.local/admin/notifications/inbox /admin/notifications/inbox · Owner / Admin
Notifications feed
Search by title or source
Type Severity Unread Period 6
Today
Sync critical series ×5 7 14:02 · 5 min ago
Jira source: 5 failed runs in a row The last run failed at the extraction stage — the source has been unavailable since 13:40.
harvester · source/42 8
Mark read 9 Open source
Security critical 13:48 · 20 min ago
Password brute-force: anna@…, 12 failed sign-ins in 15 min auth · user/anna
Discovery info 12:55 · 1 h ago
New “Phoenix” project in Jira — out of the source scope
add to collection scope?
Earlier
Budget critical yesterday, 18:30
June AI spend exceeded the $500 budget
admin · budget
Mark unread 10 Open spend
System critical yesterday, 04:12
Knowledge Store backup failed knowledge_store · backup
Sync warning yesterday, 02:05
Confluence run: 8 documents in the DLQ harvester · source/17
1–20 of 156
1 2 3 8
  1. 6 The Type · Severity · Unread · Period facets — behavior consistent across all lists. “Unread” is a common default; clear it to see the history.
  2. 7 The severity chip = notifications.severity (critical · warning · info), color from the event catalog. The type on the left is the routing category (Sync · Security · Budget · System · Discovery).
  3. 8 The source is clickable — a deep link to the entity from source_ref: run, source, provider, budget. It takes you to where it gets fixed, straight from the feed.
  4. 9 “Mark read” writes read_at to the admin's own delivery — everyone has their own feed and their own read state, and others' are not touched. The event itself is append-only; it is neither edited nor deleted.
  5. 10 A read item dims (a muted card, without the accent bar) but stays in history; “Mark unread” returns it to the count. Grouping by day — Today · Earlier.
  6. What lands in the feed is personal: any type and channel — including in-app for security and sync — is switched off in one's own profile (notification_prefs); there are no personal locks. The organizational lock on those two keeps in-app on at the organization level only — it can't be silenced centrally, but it does not constrain personal choice.