TicketmateIssuesCache::refresh() was unconditionally rebuilding
ticketmate_url as $base . '/admin/tickets/' . id, throwing away the
URL TicketMate returns from /api/v1/issues. As of TM Phase F, that
URL is a signed magic-link for portal-enabled requesters that auto-
logs them straight into /portal/tickets/{id}. Overwriting it broke
the customer-portal flow — clicking "Open in TicketMate" landed on
a staff /admin login screen.
Now: prefer $r['ticketmate_url'] if present, fall back to the
admin URL only when missing (older TicketMate versions, or staff
tickets without a portal-enabled requester).
Bust the cache (Refresh from TicketMate header action) after
upgrading to pick up the new URLs immediately.