215 lines
8.9 KiB
Markdown
215 lines
8.9 KiB
Markdown
|
|
# 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
|
||
|
|
|
||
|
|
### Share Link Operations
|
||
|
|
|
||
|
|
#### 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 ✅)
|