Skip to content

feat(collaboration): persist activity/notification history and add invitation list+respond endpoints #16460

Description

@mrveiss

Problem

#16443 wires the collaboration UI onto real backend surfaces (api/collaboration.py's REST API + websocket/presence.py's presence WebSocket), but two capabilities have no persistence or listing surface at all — accepted as live-only for #16443's first pass, tracked here as the fast-follow.

  1. Activity feed and secret-share notifications are ephemeral. impl gap: wire in the real-time collaborative-session UI (#608 phases 5-7 / #874) — 6 components + useSessionCollaboration, zero callers #16443 delivers both over the presence WebSocket's existing generic {"type": "broadcast", ...} relay (websocket/presence.py's PresenceManager.broadcast_to_session). That relay only reaches clients connected at the moment of the broadcast — nothing is written to a database. A user who reconnects, or wasn't connected when an activity happened or a secret was shared with them, sees nothing: no history, no "you missed 3 notifications while away."

  2. There is no REST endpoint to list or respond to a pending invitation. models/session_collaboration.py's SessionCollaboration model already supports this (invitations: Mapped[dict], add_invitation(), remove_invitation()), and api/collaboration.py exposes POST /{session_id}/invite (the owner's send side), but there is no GET /{session_id}/invitations (list mine) or POST /{session_id}/invitations/{id}/respond (accept/decline) endpoint. impl gap: wire in the real-time collaborative-session UI (#608 phases 5-7 / #874) — 6 components + useSessionCollaboration, zero callers #16443 therefore drops pendingInvitations/respondToInvitation from useSessionCollaboration.ts's public surface rather than shipping a fake stub — an invited user has no way to see or act on an invitation today, in any client.

Fix

  • A small persistence layer (a table, or reuse SessionCollaboration.collaboration_metadata's JSONB) for activity events and secret-share notifications, plus a GET /{session_id}/activity and/or GET /{session_id}/notifications endpoint with pagination, so a reconnecting client can backfill.
  • GET /{session_id}/invitations (current user's pending invitations across sessions, or scoped to one session) and POST /{session_id}/invitations/{invitation_id}/respond (accept/decline), wired to the model's existing add_invitation/remove_invitation methods.
  • Once these land, restore pendingInvitations/respondToInvitation to useSessionCollaboration.ts backed by the real endpoints.

Acceptance criteria

  • A client that reconnects mid-session sees activity/notifications it missed, not just live ones from that point forward
  • An invited user can see and respond to a pending invitation from at least one client
  • useSessionCollaboration.ts restores pendingInvitations/respondToInvitation backed by the new endpoints

Discovered During

#16443 (wiring the collaboration UI onto the real backend).

Activity

  1. added this to the v0.9.0 milestone on Sep 12, 2026
  2. mrveiss commented on Sep 14, 2026

    @mrveiss
    OwnerAuthor

    Closure evidence (vehicle 2f, merge 2b5a962)

    • AC1 — CollaborationEvent model + migration migrations/versions/20260912_092_collaboration_events.py persist both activity (websocket/presence.py::_persist_activity_event) and secret-share (api/collaboration.py::_record_event) events. GET /{session_id}/events (api/collaboration_events.py:74) returns them paginated (limit/before cursor, newest-first). Frontend calls it on join: useSessionCollaboration.ts::_backfillEvents, invoked at useSessionCollaboration.ts:380.
    • AC2 — GET /invitations/mine (api/collaboration_events.py:143) and POST /{session_id}/invitations/respond (api/collaboration_events.py:194) wired to SessionCollaboration.add_collaborator/remove_invitation.
    • AC3 — useSessionCollaboration.ts exports pendingInvitations (line 120/150/563) and respondToInvitation (line 140/514/572), backed by the new endpoints via apiService.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions