- gatherTicketEvidence: company_name, ticket_notes, time_entries (all
parameterized $1 queries), and Autotask attachment metadata only
(fullPath/title/contentType, never base64 data); Autotask call wrapped in
try/catch so a failure degrades to an empty attachments array
- detectPhishingTicket: matches, hashes, checks D-04 idempotency guard
(skips re-gathering/writing when content_hash is unchanged), then upserts
one reports row via ON CONFLICT (ticket_id) DO UPDATE ... RETURNING id
- requester_contact_id binds from ticket.contact_id, created_by_contact_id
from ticket.created_by_contact_id per interfaces contract