Skip to content

History / Merging Tickets Developer Guide

Revisions

  • Splitting tickets pair + undo on both merge and split (#914–#916) New: Splitting-Tickets + Splitting-Tickets-Developer-Guide, same format as the other pairs — colour-keyed file table, the reasoning, and the traps. The dev guide leads on why split is NOT the mirror of merge: a merge protects a reference the customer already holds (pointer + inbound redirect), a split mints one nobody has ever seen (no pointer, no redirect, both tickets live, linked `related` not `duplicate_of`). That table is the thing worth reading. Also written up where they will be read: - the empty-ticket guard, and why the preview and the split share one function - the thread renders NEWEST-FIRST, so every string says "newer" not "after" - the control was hover-only and nobody could find it; a control nobody can find is a missing feature, not a subtle one - splitPlural() exists because "1 message(s)" reads as a bug Merge pages updated for undo, including the contrast that matters: undo-split REFUSES on any activity (the new ticket was brand new), unmerge deliberately does NOT (the survivor is the live ticket and collects replies within the hour). Plus what unmerge records and why the source's previous status must be stored rather than inferred. Every file, function and column named in the tables verified to exist; every internal link resolves. Linked from the sidebar under Tickets and from Tickets.md.

    @edmozley edmozley committed Jul 21, 2026
  • Merging tickets: analyst page + developer guide (#912) Merging-Tickets.md — doing a merge, what happens to the reference and why that matters, the AI briefing, the two settings and their trade-offs (including the search trade-off on HTML-only), whether the HTML attachments are safe to open, and the honest edges (can't be undone, 20 max, same company, no split yet). Merging-Tickets-Developer-Guide.md — colour-keyed file table, then the four decisions: - the SDREF in every past notification is why a merged ticket is never deleted, and why the pointer is a column and not a status name - what moves vs what stays, with the test that decides it ("does this row describe the conversation, or what happened to THIS ticket?") - access checked for every ticket before a single row moves; loadTicket made public rather than copying the scope rule; one transaction - the snapshot is safe because of THREE things, and the one that matters most is Content-Disposition: attachment — it never renders on the app's origin Includes both bugs found on live data after shipping, written up where they will be read: tickets.tenant_id NULL means the DEFAULT company (comparing raw values refused ordinary merges), and only Anthropic streams tokens so an AI progress indicator must never depend on tokens arriving. Every file, function, constant and CSS class named in the tables verified to exist; every internal link resolves. Linked from the sidebar under Tickets and from Tickets.md.

    @edmozley edmozley committed Jul 21, 2026