Skip to content

v4.13 — Notification History

Once you acknowledge a notification it used to vanish for good — now there's a dedicated place to look back.

Summary

Before this milestone, Objectuve's notification tray (NotificationsPanel.vue) cleared an item the moment a user acknowledged it — by design, to keep the tray itself short and current. That created a real gap: once acknowledged, a notification was gone with no way to revisit it, even though the underlying UserNotification record persisted server-side the whole time.

This milestone gave users a dedicated Notification History page at /notifications — a full, date-grouped record of everything the app has told them, acknowledged or not. It shipped in two phases: a data layer (a new paginated GraphQL query and composable, plus a fix for a latent bug where the tray's delete button was silently wired to the acknowledge mutation instead of the real delete) and a UI layer (an extracted, dual-mode notification row component, the history page itself, and a link from the tray). The tray's clear-on-acknowledge behavior was deliberately left untouched — the history page is a separate, additive surface, not a replacement.

Goal

Give users a dedicated Notification History page at /notifications where they can review their full notification history — both acknowledged and unacknowledged — after the tray has cleared acked items. The page is date-grouped (New / Today / This Week / Earlier), renders per-kind icons + read/unread state like the tray, and offers per-item mark-read and delete actions, mirroring the attached Facebook / LinkedIn references. The notification tray keeps its clear-on-acknowledgement behavior and gains a "See all notifications" link to the page.

Scope — What Shipped

  • New backend GraphQL query notificationHistory(limit, offset) returning { items, totalCount, hasMore } (rails_api/app/graphql/types/query_type.rb, resolver app/graphql/resolvers/notification_queries.rb, interaction app/interactions/social/build_notification_history.rb, type app/graphql/types/notification_history_type.rb) — ownership-guarded to the current user, additive and separate from the tray's existing user.notifications(limit:) field.
  • New frontend useNotificationHistory.ts composable and NOTIFICATION_HISTORY_QUERY GraphQL constant, mirroring the offset-pagination pattern already used by useUnifiedFeed.ts.
  • Fixed a latent bug: useNotifications.ts's deleteNotification was wired to the acknowledge mutation instead of the real delete mutation — it now calls the actual delete mutation.
  • New standalone view ionic_frontend/src/views/NotificationHistory.vue at route /notifications, with date-grouped sections (New / Today / This Week / Earlier), an All/Unread filter, per-item mark-read and delete, and pull-to-refresh.
  • Extracted NotificationItem.vue (components/ui/) from the tray's previously-inline row markup, supporting both compact tray mode and full history mode; NotificationsPanel.vue now consumes it directly, with no visual tray regression.
  • A "See all notifications" link added to the tray's footer, pointing to /notifications.
  • Storybook stories for both NotificationItem and NotificationHistory.

Phases

PhaseNameStatusPlansHighlights
1Notification history data layerShipped1New paginated notificationHistory query + useNotificationHistory composable; fixed the deleteNotification mutation-wiring bug
2Notification history UI + docsShipped1Extracted NotificationItem, built the /notifications page, wired the tray's "See all notifications" link

Key Decisions

  • Standalone page at /notifications, deliberately not folded into /feed — confirmed by Josh at kickoff. The unified feed (/feed) is a differently-shaped, blended activity stream (ally activity, community posts, own progress) that already ingests notifications as one source among several; folding full notification history into it would bury it and lose acknowledge/delete semantics specific to notifications. Both of the Facebook/LinkedIn references used to scope this feature are dedicated notification pages, not blended feeds.
  • No migration or model change neededUserNotification already persisted every acknowledged record (acknowledged is a boolean flip; deletion is a separate hard-destroy mutation), so the full history already existed in the database. The only backend work was a new, additive read query — the existing tray query was never reshaped.
  • Fix the deleteNotification bugfix in the same milestone, not as a separate ticket — the history page's delete action would have inherited the same latent bug (silently acknowledging instead of deleting) had it not been caught and fixed in Phase 1, alongside the composable that both the tray and the new page depend on.
  • NotificationItem extracted as a dual-mode component, not duplicated — rather than building a separate history-specific row component, the tray's inline markup was extracted into one component that serves both the compact tray and the full-detail history page, so the tray's visual behavior stayed byte-for-byte unchanged.

Requirements Coverage

5.5 / 6 deliverables satisfied (quoted from the MILESTONE-AUDIT) — all five implementation deliverables shipped clean; the sixth, NOTIF-DOCS-1 (GraphQL reference docs + CHANGELOG entry), only partially landed. This page and its accompanying audit are the retroactive completion of that documentation deliverable's milestone-close half; the narrower GraphQL-reference-regeneration and CHANGELOG-backfill work remains open as a follow-up (see the audit's Tech Debt section).

CategoryCountStatus
NOTIF-API / NOTIF-UISPEC (Phase 1 backend + design)2Satisfied
NOTIF-DATA (Phase 1 frontend + bugfix)1Satisfied
NOTIF-ITEM / NOTIF-PAGE (Phase 2 UI)2Satisfied
NOTIF-DOCS (Phase 2 docs)1Partial — see Tech Debt

Full detail: v4.13-notification-history-MILESTONE-AUDIT.md on GitHub.

Outcomes

Users can now open /notifications from the tray's "See all notifications" link and see their complete notification history, grouped by New / Today / This Week / Earlier, filterable to unread-only, with the ability to mark individual items read or delete them — none of which was possible once the tray cleared an acknowledged item. The tray itself is unaffected: its clear-on-acknowledge behavior, its per-kind icon treatment, and its existing acknowledge mutation all continue to work exactly as before, now via the shared NotificationItem component instead of inline markup. The previously-latent deleteNotification bug (delete silently behaving like acknowledge) no longer affects either surface.

Tech Debt

  • (Phase 2, NOTIF-DOCS-1) The notificationHistory GraphQL query and NotificationHistoryType were never added to docs/architecture/graphql/queries.md / types.md, and no CHANGELOG.md entry exists for either shipping PR (#1740, #1899). This milestone's narrative and audit close the milestone-tracking gap; the GraphQL-reference regeneration and CHANGELOG backfill remain open as a follow-up.
  • (Standing, pre-existing) docs/development/notification-surfaces.md's "Known fragmentation / hub direction" section still frames a unified /notifications view as a future, out-of-scope idea — that view has shipped since 2026-07-30. Flagged for a doc-fix follow-up, not corrected in this close.
  • 97285ec0e — [Codi] feat(notifications): add paginated history query + composable (OBJ-1689) (#1740)
  • 58a4b65ec — [Codi] feat(notifications): build /notifications history page (v4.13 Phase 2) (#1899)

Last updated: 2026-08-04

Loading…