- Wrap mark_outbound_accepted, accept_outbound_call, and handle_terminate in
call.with_lock so they serialize against Whatsapp::CallService (which holds
call.with_lock across the Meta API call). Without this, an ACCEPTED webhook
arriving mid-terminate could overwrite the freshly-finalized terminal status
back to in_progress and broadcast an erroneous outbound_accepted.
- Drop build_missed_inbound_call. An outbound terminate landing in the tiny
window between provider_service.initiate_call and Call.create! had no local
row, so the fallback materialised an inbound row with the same
provider_call_id and tripped the unique (provider, provider_call_id) index
on the controller's create. The "out-of-order webhook" case it protected is
rare in practice; trade that for eliminating the false-positive collision.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>