Skip to content

Activity tab: real mentions + reactions feed (server feature) #91

Description

@gbasin

Follow-up from the sj-audit nav work (#89 shipped the Activity tab). The Activity tab today is an honest v1: agent events only (non-terminal sessions from the existing sessions feed), with a "Mentions & reactions are coming soon" note. This issue tracks making it a real notifications hub.

Goal

Activity surfaces, in one place: @mentions of the current user + reactions on their messages, merged with the existing agent events, newest-first, with read/unread state — on both web and mobile.

What exists today

  • Reactions are events (reaction.added / reaction.removed) in the events table; aggregation lives in surface/server/src/events.ts (reactions json_agg ~:589, net-count ~:488). A reactions feed is queryable: reactions whose target message's author = me.
  • Mentions: nothing server-side — the app only parses @agent for spawns. Mentions need a detection strategy.
  • No activity/notifications endpoint or client api method exists.

Design fork (decide before building)

Mention detection — write-time index vs read-time scan:

  • A) Write-time mentions index (recommended): on message create, parse @handle, resolve to user ids, insert into a new mentions(message_event_id, mentioned_user_id, channel_id, created_at, read_at) table. Cheap reads, clean unread state + pagination. Cost: migration + write-path hook + backfill.
  • B) Read-time scan (cheaper, weaker): scan recent channel messages for @<myhandle> on load. No migration, but O(messages)/load, no durable read-state.

Scope when built

  1. Server: GET /api/activity{ mentions[], reactions[] }, cursor pagination; reactions = events on my-authored messages; mentions per chosen strategy.
  2. Client: api.activity(...) in shared/src/api.ts.
  3. UI: merge mentions + reactions + agent events in surface/mobile/app/(app)/activity.tsx + a web equivalent; wire the Activity tab badge to the unread count.
  4. Tests: server query + web/mobile vitest.

Why deferred

Multi-layer (server + DB + 2 clients) with the architecture decision above — too big to land safely alongside the UI follow-ups. Decide A vs B first.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions