From 662922cd75a97cc791d83bf605abdf152fa5ce97 Mon Sep 17 00:00:00 2001 From: Muhsin <12408980+muhsin-k@users.noreply.github.com> Date: Fri, 3 Jul 2026 13:18:12 +0400 Subject: [PATCH] fix(conversations): add id tiebreaker to message thread seed so CSAT survey renders The dashboard seeds the message thread from the conversation payload and then paginates backward by id (before: messages[0].id). The seed was ordered by created_at only, so on an auto-resolve burst where the input_csat survey shares the exact same second as trailing activity messages, a lower-id activity could win the tie and become the seed. Backward pagination then never loads the higher-id survey, so the CSAT bubble is missing from the conversation even though the rating exists and is counted in reports. Order the seed by created_at DESC, id DESC: the seed stays the chronologically latest message (no change for delayed-webhook rows), and same-second ties resolve to the highest id so the survey is always reachable. --- .../partials/_conversation.json.jbuilder | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/app/views/api/v1/conversations/partials/_conversation.json.jbuilder b/app/views/api/v1/conversations/partials/_conversation.json.jbuilder index 5fdd4ecee..3f75374a1 100644 --- a/app/views/api/v1/conversations/partials/_conversation.json.jbuilder +++ b/app/views/api/v1/conversations/partials/_conversation.json.jbuilder @@ -27,13 +27,18 @@ json.meta do end json.id conversation.display_id -if conversation.messages.where(account_id: conversation.account_id).last.blank? +# The dashboard seeds the message thread from this array and then paginates BACKWARD +# by id (before: messages[0].id). Keep the seed as the chronologically latest message, +# but add an id tiebreaker: without it, same-second siblings (e.g. the input_csat survey +# created alongside activity messages during an auto-resolve burst) could resolve to a +# lower-id activity, and backward pagination would then never load the higher-id survey. +last_message = conversation.messages.where(account_id: conversation.account_id) + .includes([{ attachments: [{ file_attachment: [:blob] }] }]) + .reorder(created_at: :desc, id: :desc).first +if last_message.blank? json.messages [] else - json.messages [ - conversation.messages.where(account_id: conversation.account_id) - .includes([{ attachments: [{ file_attachment: [:blob] }] }]).last.try(:push_event_data) - ] + json.messages [last_message.try(:push_event_data)] end json.account_id conversation.account_id