veza/apps/web/docs/MUTATIONS_OPTIMISTIC_UPDATES_AUDIT.md

8.9 KiB

Mutations Optimistic Updates Audit

Date: 2026-01-11
Action: 4.4.1.4 - Audit all mutations for optimistic updates
Status: Complete

Summary

This document audits all React Query mutations in the codebase to identify which mutations have optimistic updates and which are missing them.

Methodology

  • Searched for all useMutation calls in the codebase
  • Checked each mutation for:
    • onMutate handler (optimistic update)
    • createOptimisticUpdate, createArrayOptimisticUpdate, createToggleOptimisticUpdate usage
    • Manual optimistic update logic in onMutate
  • Categorized mutations by optimistic update status

Mutations WITH Optimistic Updates

1. Like/Unlike Track (LikeButton.tsx)

  • Mutations: likeMutation, unlikeMutation
  • Type: Manual onMutate with local state
  • Pattern: Updates local state (isLiked, likeCount) optimistically
  • Rollback: Manual revert in onError
  • Lines: 67-96 (like), 99-120 (unlike)

2. Follow/Unfollow Playlist (PlaylistFollowButton.tsx)

  • Mutations: followMutation, unfollowMutation
  • Type: Manual onMutate with local state
  • Pattern: Updates local state (following, followerCount) optimistically
  • Rollback: Manual revert in onError
  • Lines: 84-114 (follow), 117-145 (unfollow)

Mutations WITHOUT Optimistic Updates

Playlist Operations (usePlaylist.ts)

1. useCreatePlaylist

  • Mutation: Create playlist
  • Current: Only onSuccess invalidation
  • Recommendation: Add optimistic update to immediately show new playlist in list

2. useUpdatePlaylist

  • Mutation: Update playlist
  • Current: Only onSuccess invalidation
  • Recommendation: Add optimistic update using createOptimisticUpdate utility

3. useDeletePlaylist

  • Mutation: Delete playlist
  • Current: Only onSuccess invalidation
  • Recommendation: Add optimistic update to immediately remove from list

4. useAddTrackToPlaylist

  • Mutation: Add track to playlist
  • Current: Only onSuccess invalidation
  • Recommendation: Add optimistic update using createArrayOptimisticUpdate (operation: 'add')

5. useAddCollaborator

  • Mutation: Add collaborator to playlist
  • Current: Only onSuccess invalidation
  • Recommendation: Add optimistic update using createArrayOptimisticUpdate (operation: 'add')

6. useRemoveCollaborator

  • Mutation: Remove collaborator from playlist
  • Current: Only onSuccess invalidation
  • Recommendation: Add optimistic update using createArrayOptimisticUpdate (operation: 'remove')

7. useUpdateCollaboratorPermission

  • Mutation: Update collaborator permission
  • Current: Only onSuccess invalidation
  • Recommendation: Add optimistic update using createArrayOptimisticUpdate (operation: 'update')

8. useReorderPlaylistTracks

  • Mutation: Reorder tracks in playlist
  • Current: Only onSuccess invalidation
  • Recommendation: Add optimistic update to immediately show new order

Comment Operations

9. createCommentMutation (CommentSection.tsx)

  • Mutation: Create comment
  • Current: Only onSuccess invalidation
  • Recommendation: Add optimistic update using createArrayOptimisticUpdate (operation: 'add')

10. createReplyMutation (CommentThread.tsx)

  • Mutation: Create reply to comment
  • Current: Only onSuccess invalidation
  • Recommendation: Add optimistic update using createArrayOptimisticUpdate (operation: 'add')

11. updateCommentMutation (CommentThread.tsx)

  • Mutation: Update comment
  • Current: Only onSuccess invalidation
  • Recommendation: Add optimistic update using createArrayOptimisticUpdate (operation: 'update')

12. deleteCommentMutation (CommentThread.tsx)

  • Mutation: Delete comment
  • Current: Only onSuccess invalidation
  • Recommendation: Add optimistic update using createArrayOptimisticUpdate (operation: 'remove')

Chat Operations

13. leaveRoomMutation (ChatSidebar.tsx)

  • Mutation: Leave chat room
  • Current: Only onSuccess invalidation
  • Recommendation: Add optimistic update to immediately remove from conversation list

14. deleteRoomMutation (ChatSidebar.tsx)

  • Mutation: Delete chat room
  • Current: Only onSuccess invalidation
  • Recommendation: Add optimistic update to immediately remove from conversation list

Notification Operations

15. markAsReadMutation (NotificationMenu.tsx, NotificationsPage.tsx)

  • Mutation: Mark notification as read
  • Current: Only onSuccess invalidation
  • Recommendation: Add optimistic update using createArrayOptimisticUpdate (operation: 'update')

16. markAllAsReadMutation (NotificationMenu.tsx, NotificationsPage.tsx)

  • Mutation: Mark all notifications as read
  • Current: Only onSuccess invalidation
  • Recommendation: Add optimistic update to immediately update all notifications

17. createShareMutation (ShareLinkManager.tsx)

  • Mutation: Create share link
  • Current: Only onSuccess invalidation
  • Recommendation: Add optimistic update to immediately show share link

18. revokeShareMutation (ShareLinkManager.tsx)

  • Mutation: Revoke share link
  • Current: Only onSuccess invalidation
  • Recommendation: Add optimistic update to immediately remove share link

Auth Operations

19. useLogin (useLogin.ts)

  • Mutation: Login
  • Current: No optimistic update (correct - auth state should not be optimistic)
  • Recommendation: No optimistic update needed (security-sensitive)

20. useRegister (useRegister.ts)

  • Mutation: Register
  • Current: No optimistic update (correct - auth state should not be optimistic)
  • Recommendation: No optimistic update needed (security-sensitive)

Statistics

  • Total Mutations Found: 20+
  • With Optimistic Updates: 4 (20%) - LikeButton, PlaylistFollowButton
  • With Partial Optimistic Updates: 2 (10%) - ShareLinkManager (local state in onSuccess)
  • Without Optimistic Updates: 14+ (70%)
  • Should Not Have Optimistic Updates: 2 (auth operations)

Patterns Identified

Pattern 1: Manual Local State Optimistic Updates

  • Used in: LikeButton, PlaylistFollowButton
  • Approach: Update local component state in onMutate, revert in onError
  • Pros: Simple, works for isolated component state
  • Cons: Doesn't update React Query cache, requires manual rollback

Pattern 2: React Query Cache Invalidation Only

  • Used in: Most mutations
  • Approach: Only invalidate queries on success, wait for refetch
  • Pros: Simple, ensures data consistency
  • Cons: No immediate feedback, requires network round-trip

Pattern 3: Utility-Based Optimistic Updates (Available but Unused)

  • Available: createOptimisticUpdate, createArrayOptimisticUpdate, createToggleOptimisticUpdate
  • Used in: None currently
  • Approach: Use utility functions for consistent optimistic updates
  • Pros: Consistent pattern, automatic rollback, updates React Query cache
  • Cons: Requires setup

Recommendations

High Priority (User-Facing Operations)

  1. Playlist operations (useCreatePlaylist, useUpdatePlaylist, useDeletePlaylist)
  2. Track operations (useAddTrackToPlaylist)
  3. Comment operations (create, update, delete)
  4. Follow/Like operations (already have optimistic updates )

Medium Priority (Frequent Operations)

  1. Collaborator operations (add, remove, update)
  2. Notification operations (mark as read)
  3. Share link operations (create, revoke)

Low Priority (Less Frequent)

  1. Chat operations (leave room, delete room)
  2. Reorder operations (reorder playlist tracks)

Next Steps

  1. Action 4.4.1.4: Audit complete - Documented all mutations
  2. Action 4.4.1.5: Add optimistic updates to mutations missing them (prioritize high-priority operations)
  3. Action 4.4.1.2: Migrate manual optimistic updates to use utility functions (LikeButton, PlaylistFollowButton)

Files Audited

  • apps/web/src/features/playlists/hooks/usePlaylist.ts - 9 mutations
  • apps/web/src/features/tracks/components/LikeButton.tsx - 2 mutations (with optimistic )
  • apps/web/src/features/playlists/components/PlaylistFollowButton.tsx - 2 mutations (with optimistic )
  • apps/web/src/features/tracks/components/CommentSection.tsx - 1 mutation
  • apps/web/src/features/tracks/components/CommentThread.tsx - 3 mutations
  • apps/web/src/features/chat/components/ChatSidebar.tsx - 2 mutations
  • apps/web/src/components/notifications/NotificationMenu.tsx - 2 mutations
  • apps/web/src/features/notifications/pages/NotificationsPage.tsx - 2 mutations
  • apps/web/src/components/share/ShareLinkManager.tsx - 2 mutations
  • apps/web/src/features/auth/hooks/useLogin.ts - 1 mutation (no optimistic needed )
  • apps/web/src/features/auth/hooks/useRegister.ts - 1 mutation (no optimistic needed )