fix(voice): lock webhook transitions and skip unknown terminates
- 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>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
c5236ec67e
commit
dfdadc470d
@@ -114,6 +114,21 @@ describe Whatsapp::IncomingCallService do
|
||||
end
|
||||
end
|
||||
|
||||
describe 'terminate with no local row yet' do
|
||||
it 'logs and skips instead of materialising an inbound missed-call row' do
|
||||
allow(inbox.channel).to receive(:voice_enabled?).and_return(true)
|
||||
allow(Rails.logger).to receive(:warn)
|
||||
allow(ActionCable.server).to receive(:broadcast)
|
||||
|
||||
params = call_payload(event: 'terminate', duration: 0, terminate_reason: 'no_answer')
|
||||
|
||||
expect { described_class.new(inbox: inbox, params: params).perform }
|
||||
.not_to change(Call, :count)
|
||||
expect(Rails.logger).to have_received(:warn).with(/Terminate for unknown call/)
|
||||
expect(ActionCable.server).not_to have_received(:broadcast)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'outbound connect with no local row yet' do
|
||||
it 'does not mint an inbound call when sdp_type is answer' do
|
||||
allow(inbox.channel).to receive(:voice_enabled?).and_return(true)
|
||||
|
||||
Reference in New Issue
Block a user