Bug: Action flow email and SMS still send after job is cancelled

Objective

  • Stop action flow emails and SMS from sending on a cancelled inspection/job after cancellation, except where product explicitly configures job_cancelled teardown communications.
  • Prevent customer confusion and duplicate outreach when a job is no longer active (reported sends on multiple dates after a May 8 cancellation).

Background

  • When an inspection status becomes cancelled, the system is intended to halt routine lifecycle automations:
  • removeAllScheduled(inspectionId) removes delayed BullMQ flow jobs matching *-inspection_{id}.
  • flowEventTriggerer('job_cancelled', …) runs cancellation-specific flow actions only.
  • queueFlowOnJobDisable sets FlowOnJob.active = false after a 5 second delay so job_cancelled actions can still query flows.
  • Reported behavior: job cancelled May 8, but action-flow email/SMS still fired May 9, 10, 11, 12, 16, 23, and 30 — consistent with time-based reminders / follow_up (or other delayed actions) not being fully cancelled, not a same-day duplicate send.
  • At send time, handleEventTriggerdByBull.ts blocks actions when FlowOnJob is inactive except job_cancelled, but does not check whether the inspection/quote status === 'cancelled' before rendering email or SMS.
  • reminders / follow_up are skipped only when status is unconfirmed, not cancelled.
  • payment_created is triggered from inspectionStream.ts on payment changes without a cancelled guard (unlike services_updated / job_rescheduled, which require confirmed).

Scope

Backend — cancel handling

  • Cancel detection and cleanup live in attik-backend/src/events/streamHandlers/inspectionStream.ts when status transitions to cancelled.
  • attik-backend/src/util/functions/actionFlows/removeAllScheduled.ts — Redis SCAN + remove delayed jobs by pattern; decision needed whether all job id formats are covered (flow_* and scheduled-flow_* prefixes from flowEventTriggerer.ts and handleScheduledFlowEvent.ts).
  • attik-backend/src/events/bullmq/flowOnJobDisableWorker.tsJOB_DELAY_MS = 5000 before FlowOnJob.active is false; race window for non–job_cancelled sends.

Backend — send gate

  • attik-backend/src/util/functions/actionFlows/handleEventTriggerdByBull.ts — final gate before renderEmailFromTemplate / renderSmsFromTemplate; add cancelled-job filtering (decision needed: allowlist only job_cancelled vs all actionType values).
  • attik-backend/src/util/functions/actionFlows/flowEventTriggerer.ts — queues delayed actions; should not enqueue routine lifecycle actions for cancelled jobs.
  • attik-backend/src/routes/inspection.tsPOST /:id/cancel sets status, canceledBy, canceledAt (canonical cancel path).

Backend — triggers to audit

  • inspectionStream.tspayment_created on hasPaymentsChange without status check.
  • chargeUpdateResolveAndTrigger.ts — skips non-confirmed inspections for charge events; confirm cancelled is excluded.
  • handleFlowStart.ts / handleScheduledFlowEvent.ts — time-based scheduling relative to inspection datetime; ensure cancel cleanup removes scheduled-flow_* jobs and nothing reschedules them while cancelled.
  • handleRescheduleTimeUpdates.ts — reschedules time-based jobs on datetime change; decision needed whether this can run on cancelled inspections.

Out of scope

  • Activity feed vs Booking Details cancel display (separate concern).
  • Whether job_cancelled flows should send email/SMS (product configuration; only non-teardown sends are in scope).

References

  • attik-backend/src/util/functions/actionFlows/ACTIVITY_SYSTEM_README.md (related systems; action flow worker in attik-backend/src/events/bullmq/flowWorker.ts)
  • attik-frontend/src/app/tools/action-flow/[flow_id]/data/eventCategories.ts (job_cancelled, follow_up, reminders, payment_created event ids)

Please authenticate to join the conversation.

Upvoters
Status

Planned

Board
🏠

Main App

Date

2 days ago

Author

Linear

Subscribe to post

Get notified by email when there are changes.