Repository navigation
Live chat transfer (escalated.admin.chat.transfer) and chat.transferred - #146
Merged
Merged
Conversation
Ports escalated-laravel ChatController::transfer and
ChatSessionService::transferChat as POST agent/chat/{session}/transfer,
named escalated.admin.chat.transfer, and emits chat.transferred to
webhooks and workflows.
The page posts escalated.admin.chat.transfer from the browser session,
which the stateless API chain ignores, so the name now points at
POST /escalated/agent/chat/{session}/transfer, as End Chat does.
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Ports escalated-laravel's live chat transfer (
ChatController::transfer,ChatSessionService::transferChat), so this package can emitchat.transferred(ADR 2026-10-21 event vocabulary), as escalated-go #167 and escalated-phoenix #176 did.What
POST /escalated/api/agent/chat/{sessionId}/transfer, behind the agent check like the rest of the agent chat API.POST /escalated/agent/chat/{session}/transferfrom the agent's browser session (agent gate + CSRF, like End Chat in Serve escalated.admin.chat.end from the agent UI session #145), registered inUiRoutesasescalated.admin.chat.transfer(Laravel's name), so the sharedAgent/TicketShowtransfer menu, which passeschat_session_id, reaches it. Both share one handler.{agent_id, department_id}(either or both); the sharedChatActionBarbody{type, id}is accepted too.acceptedAtcleared) and chat routing runs again for the new department. Same semantics as Laravel; the ticket is updated directly (as Laravel does), and a re-route goes throughaccept.TicketAccess.canAssign); a refusal rolls back. 404 unknown session. Response{"message": "Chat transferred.", "session": {...}}.ChatEvent.Type.TRANSFERREDwithgetTransfer(); webhook data addsfrom_agent_id,to_agent_id,to_department_id(no widget token).EventNames.EMITTEDnow includeschat.transferred, so the webhook form and workflow builder offer it.Tests
ChatTransferTestthrough MockMvc and the real context: route name, agent transfer (webhook data + workflow run), department transfer with re-routing, department transfer with no agent (waiting), both, ChatActionBar body, refusals (anonymous, no target, blank target, unknown/non-integer department, unknown agent, non-staff, inactive agent, unknown session, ended chat) with no event sent. All 8 red before, green after.AgentChatTransferUiTestcovers the named UI route from a browser session (CSRF, non-agent, 422/404). Full suite + checkstyle green on H2, PostgreSQL 17 and MySQL 8.4.