runFinalClose ran the transcript archive, creator DM, close log, and closure email in the same try as the close transition and channel delete, with the transcript posted *before* the commit. A failure in any of them (notably a DiscordAPIError 50001 Missing Access when posting the transcript to the archive channel) aborted the whole close: the customer saw 'ticket closed' but the DB stayed open and the channel was never deleted. Rewrite so the close transition + pendingDelete commit FIRST, each side-effect is individually best-effort via a closeStep wrapper, and scheduleTicketChannelDelete always runs. finalizeForceClose was already commit-first; wrap its remaining unguarded archiving send too.
32 KiB
32 KiB