- P0 IDOR: escape LIKE wildcards in build_scope_domain + normalise emails (email_normalize) on both write and scope sides, so a self-set email of '%' can no longer match every ticket in a deployment (+2 regression tests).
- Convert XML-RPC ProtocolError (central 502/503/429) to _RemoteError instead of a raw 500.
- _resolve_author: log + post as service account on failure instead of silently impersonating the ticket customer.
- _mark_seen now best-effort (runs after the remote post) so a bookkeeping failure can't report a successful reply as failed (no duplicate replies).
- Attachment loop catches network errors + reports failed count (no duplicate-ticket trap); dialog surfaces failures.
- console.error in JS catches for diagnosability.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Remote message_post escapes a plain str body (expects Markup, which can't cross XML-RPC). Without body_is_html=True the customer's reply rendered literal <p>/<br> tags.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
submit() now sends partner_email/partner_name/x_fc_client_label. New jsonrpc endpoints my_tickets/ticket_detail/ticket_reply/unread_count, all auth=user with server-side scoping (build_scope_domain), internal-note filtering, and graceful remote-failure handling.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>