switch ticket replies to synchronous POST with htmx spinner#7541
Merged
Conversation
Replace the SupportTicketPendingChange outbox + post_reply_to_zendesk
Celery task + 2-second template polling with a synchronous call to
ZendeskClient.add_ticket_comment from ticket_detail. HTMX's hx-post +
the submit button's .htmx-request busy-state act as the spinner.
View changes:
- Synchronous POST to Zendesk inside a configurable timeout
(settings.ZENDESK_REPLY_TIMEOUT, default 20s)
- On success: lock the row under select_for_update(of=("self",)), then
persist zd_updated_at and append the new comment dedupe-by-id; if the
zd_status returned by Zendesk differs from the persisted value (e.g.
a PENDING/SOLVED ticket auto-reopens to OPEN), persist that too and
flag status_changed=True so the HTMX response can include an
out-of-band swap of the hero status badge
- On failure: set reply_error=True, leave the form bound so the body is
preserved for retry
- Authorization continues to be handled by accessible_to(request.user)
so staff and org-subtree members keep their existing read access
- Reply textarea shows a "Reply here to reopen this ticket." placeholder
when the ticket is in ZD_STATUS_SOLVED, via a new placeholder kwarg on
SupportTicketReplyForm.__init__
Template changes:
- ticket_replies.html: hx-post form with hx-disabled-elt; reply_error
drives the failure notice; pending/polling/sending UI removed entirely;
emits an out-of-band <div id="thread-detail--pill-cluster"
hx-swap-oob="true"> on responses where status_changed is True so the
hero badge updates without a full page reload
- ticket_detail.html: hero pill cluster carries the matching id so HTMX
has a target to swap into
ZendeskClient now accepts arbitrary kwargs and forwards them to Zenpy,
letting the view opt in to a tighter timeout without affecting other
callers.
Removed (with destructive migration 0011_delete_supportticketpendingchange):
- SupportTicketPendingChange model and DB table
- post_reply_to_zendesk Celery task
- SupportTicket.pending_change() helper and SupportTicketPendingChangeFactory
- ZENDESK_REPLY_POLL_SECONDS setting
- 17 lines of dead SCSS (.thread-post--sending, .thread-post--state)
- Stale tests (TicketReplyPostTests, TicketRepliesTemplateTests,
PostReplyToZendeskTests) replaced by TicketReplySyncTests
Accepted trade-off: a request-thread timeout does not guarantee Zendesk
did not process the comment, so a user-driven retry can rarely double-post.
_ticket_needs_sync refreshes comments on the next page load before any
retry, and the webhook ingestion path dedupes by comment id.
abbf802 to
2f5355e
Compare
akatsoulas
approved these changes
May 29, 2026
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.
mozilla/sumo#2923
mozilla/sumo#3058
mozilla/sumo#3067
I like this approach a lot better. It's simple, effective, and avoids the problems with trying to use an asynchronous task to perform the Zendesk update. I've tested it thoroughly locally (using the CSAT Zendesk test instance that Joe created for me), and it looks and works just like what we have in stage currently but without the polling and problems associated with relying on a Celery task.