Class: FreightquoteVoidConfirmationWorker
- Inherits:
-
Object
- Object
- FreightquoteVoidConfirmationWorker
- Includes:
- Sidekiq::Job
- Defined in:
- app/workers/freightquote_void_confirmation_worker.rb
Overview
Scheduled 1 hour after a Shipping::Freightquote#void call to confirm
CHR actually cancelled the order. CHR's DELETE returns a requestId
(an async-job ack), not a synchronous cancel confirmation — see the
DE787078 forensic: our void at 2026-05-19 15:55 didn't reflect in
CHR's portal until 2026-05-20 12:02 (after a manual rep cleanup
prompted by an email exchange).
This worker checks two sources for a LOAD CANCELLED or ORDER CANCELED
echo of our void:
- FAST PATH — the local FreightEvent projection (populated by
Webhooks::V1::FreightquoteControllerwhen CHR pushes us a
callback). Cheap DB query; the canonical source once CHR's
Customer Integration Team has configured our webhook subscription. - FALLBACK — direct GET against CHR's /v2/events polling endpoint
viaWyShipping.freightquote_cancel_event_present?. Works
regardless of webhook configuration; uses the same OAuth bearer
we already mint for rate/label/void calls. Lets the worker do
useful work before the webhook subscription is live AND adds
defense-in-depth against missed webhook events afterwards.
Alerts only if BOTH sources say "no cancel event in the window".
Non-blocking: order/delivery flows do NOT wait on this. Same
operational pattern as the existing Canadapost / Purolator manual
void email fallback in Delivery#void_shipments — alert and move on.
Scheduled by Delivery#void_shipments after a successful FQ void.
Constant Summary collapse
- EVENT_TIME_TOLERANCE =
Tolerance for clock skew between our void timestamp and CHR's
event_time — accept events emitted up to 5 minutes before we
called DELETE. 5.minutes
- CONFIRMATION_EVENT_TYPES =
['LOAD CANCELLED', 'ORDER CANCELED'].freeze
Instance Method Summary collapse
Instance Method Details
#perform(delivery_id, freight_order_number, voided_at_iso) ⇒ Object
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'app/workers/freightquote_void_confirmation_worker.rb', line 47 def perform(delivery_id, freight_order_number, voided_at_iso) voided_at = Time.zone.parse(voided_at_iso.to_s) order_number = freight_order_number.to_i # An unparseable voided_at_iso (corrupted job arg, time-format # regression) would otherwise let confirmed? drop the event_time # filter and silently match an old cancellation from a prior # booking cycle — suppressing the alert we want. Alert immediately # in that case with explicit context. if voided_at.nil? msg = "Freightquote void confirmation could not verify (invalid voided_at_iso=#{voided_at_iso.inspect}) " \ "for DE#{delivery_id} (CHR order=#{order_number})." Rails.logger.error "[FreightquoteVoidConfirmationWorker] #{msg}" ErrorReporting.warning(msg, { delivery_id: delivery_id, chr_order_number: order_number, voided_at_iso: voided_at_iso, source: :background }.compact) return end if confirmed?(order_number, voided_at) Rails.logger.info "[FreightquoteVoidConfirmationWorker] DE#{delivery_id} order=#{order_number} void confirmed via FreightEvent" return end delivery = Delivery.find_by(id: delivery_id) msg = "Freightquote void NOT confirmed within 1 hour for DE#{delivery_id} (CHR order=#{order_number}). " \ 'CHR has not emitted LOAD CANCELLED or ORDER CANCELED — the order may still be live in their system; ' \ 'contact the CHR account team to confirm cleanup.' context = { delivery_id: delivery_id, delivery_state: delivery&.state, chr_order_number: order_number, voided_at: voided_at&.iso8601, source: :background }.compact Rails.logger.warn "[FreightquoteVoidConfirmationWorker] #{msg} #{context.to_json}" ErrorReporting.warning(msg, context) end |