fix: Prevent duplicate conversations in conversation list (#13713)
Agents using API channel inboxes (e.g., WhatsApp Automate) reported seeing the same conversation appear twice in their conversation list — one showing the last message preview and the other showing "No Messages". Backend investigation confirmed no duplicate conversations exist in the database, making this purely a frontend issue. The root cause is a race condition in WebSocket event delivery. When a conversation is created via the API with auto-assignment, the backend enqueues multiple ActionCable broadcast jobs (`conversation.created`, `assignee.changed`, `team.changed`) within milliseconds of each other. In production with multi-threaded Sidekiq workers, these events can arrive at the frontend out of order. If `assignee.changed` arrives before `conversation.created`, the `UPDATE_CONVERSATION` mutation pushes the conversation into the store (since it doesn't exist yet), and then `ADD_CONVERSATION` blindly pushes it again — resulting in a duplicate entry. The fix adds a uniqueness check in the `ADD_CONVERSATION` mutation to skip the push if a conversation with the same ID already exists in the store, matching the dedup pattern already used by `SET_ALL_CONVERSATION`.
This commit is contained in:
@@ -228,7 +228,10 @@ export const mutations = {
|
||||
},
|
||||
|
||||
[types.ADD_CONVERSATION](_state, conversation) {
|
||||
_state.allConversations.push(conversation);
|
||||
const exists = _state.allConversations.some(c => c.id === conversation.id);
|
||||
if (!exists) {
|
||||
_state.allConversations.push(conversation);
|
||||
}
|
||||
},
|
||||
|
||||
[types.DELETE_CONVERSATION](_state, conversationId) {
|
||||
|
||||
@@ -975,6 +975,16 @@ describe('#mutations', () => {
|
||||
mutations[types.ADD_CONVERSATION](state, conversation);
|
||||
expect(state.allConversations).toEqual([conversation]);
|
||||
});
|
||||
|
||||
it('should not add a duplicate conversation', () => {
|
||||
const conversation = { id: 1, messages: [] };
|
||||
const state = {
|
||||
allConversations: [conversation],
|
||||
};
|
||||
|
||||
mutations[types.ADD_CONVERSATION](state, { id: 1, messages: [] });
|
||||
expect(state.allConversations).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#DELETE_CONVERSATION', () => {
|
||||
|
||||
Reference in New Issue
Block a user