Handoff: CreatorTrack realtime + notifications round, BUILT (awaiting review/merge)¶
Date: 2026-07-06. Branch feat/realtime-notifications (worktree ~/forge-suite-wt/feat/realtime-notifications, DB clone ct_feat_realtime_notifications, dev preview http://100.97.43.104:3062). 11 commits on top of main d11144f; combined tsc --noEmit clean; worktree clean; NOT merged, NOT deployed.
What shipped (3 parallel workers, one worktree)¶
Realtime (Worker B)
- useWorkspaceChanges active poll 6s -> 3s (cursor endpoint 10-17ms).
- Settings->General missing new workspace: WorkspaceSwitcher "+" never dispatched WORKSPACE_UPDATED_EVENT; fixed + refetch on modal open + on cursor advance.
- Live-update wiring: CRM + Sales CRM clients wired; lib/changes.ts cursor now covers crm.* tables. Tasks/calendar/pages already live.
Notifications + invites (Worker A)
- Invite consent: existing accounts get pending invite + bell notification with Accept/Decline (app/api/invites/[inviteId]/{accept,decline}); no more auto-add. Email-invite flow for no-account emails unchanged.
- Notification center: NotificationsBell rewritten; category chips (invite/reminder/mention/assignment/system), actor, read state, full history (limit 200).
- Assignment notifications from lib/tasks.ts; @mention typeahead (MentionAutocomplete.tsx in BlockList.tsx) fires mention notifications via block routes.
- ~3s unread-count poll (lib/hooks/useNotificationsPoll.ts, separate from changes cursor).
- Migrations: invite-consent + category schema; RLS fix so a recipient sees their own notification row pre-membership (20260706T235835).
Polish (Worker C)
- "Someone edited": root cause = core.users self-only RLS nulling cross-user joins; fixed via lib/actor-names.ts (roster SECURITY DEFINER resolver) in activity/page-views/snapshots. Write path was always correct.
- App page header icon now uses the sidebar's appGlyph (read-only), so top-of-app and sidebar match.
Follow-up round (Worker D, 3 more commits, now 14 ahead of main)¶
- Actor avatars:
*_avatarpayload keys stamped at dispatch; NotificationsBell renders real photo with initials fallback. Migration20260707T002030addso_invited_by_avatartocore.claim_workspace_invites(additive). - Live updates: goals + intake wired (
app.intake_*added to changes cursor). Skipped with rationale: social (own 6s poll already), agents (cross-workspace list, no single-workspace cursor fits), business (ERPNext passthrough, no local table), finance (identity-scoped, no workspace_id), campaigns (fully server-rendered; would need a client wrapper, flagged as future work). - Poll merge REJECTED, kept two pollers: notifications are user-scoped/cross-workspace and the bell is global; changes cursor is workspace-scoped and per-page. Rationale documented inline in
useNotificationsPoll.ts.
Review notes¶
- Mention typeahead and avatar rendering not exercised in a real browser with a second account (API/DB-verified only). Single-word
@Michaelmatching only. - Worker reports:
forge/comms/results/realtime-notifications-worker-a.md,creatortrack-polish-worker-c.md.
URL: https://mkdocs.justinsforge.com/memory/handoffs/creatortrack-realtime-notifications-built-2026-07-06/