Part 5 of 7 · Job status notifier series ~7 min read

How a quiet stage gets chased

The notifier is judged less by the updates it sends when things move than by what it does when they don’t. This post is about the daily sweep: how it finds a job that has been stuck in one stage too long, sends the customer an honest holding note rather than leaving them guessing, and nudges the shop — without ever nagging or texting at midnight.

Key takeaways

  • A daily sweep runs on EventBridge Scheduler and checks how long each open job has sat in its current stage.
  • Each stage has its own dwell threshold in settings — “awaiting parts” is allowed longer than “ready to collect”.
  • A job past its threshold gets two things: an honest holding note to the customer and a nudge to the shop.
  • The sweep de-duplicates, so a stuck job is chased once, not every day — it never turns into a nag.
  • It respects quiet hours and never invents progress; a holding note says the truth, that the job is still at this stage.

The updates that don’t fire themselves

Everything so far reacts to movement: a job changes stage, a message goes out. But the moments that actually lose a customer’s trust are the ones where nothing moves. A part is back-ordered and the job sits in awaiting parts for a week. A repair is finished but nobody texts, so it waits in ready while the customer assumes it isn’t done. A job quietly falls behind a busy bench and is simply forgotten. None of these produce a stage change, so none of them would ever trigger a message — which is exactly why a customer is left guessing. The sweep exists to catch the absence of movement.

How the sweep finds a stuck job

Once a day, on an EventBridge Scheduler rule timed for early morning, jsnr-sweep wakes up and walks the open jobs. For each one it works out how long the job has been sitting in its current stage — the time since the last entry in jsnr-stage-history. Then it compares that dwell time against the threshold for that stage, read from the shop settings. The thresholds differ by stage on purpose: a day in diagnosing might be fine, two days in in progress normal, but more than a few hours in ready means a finished job nobody’s collected and the customer probably hasn’t been told. Awaiting parts gets the longest leash, because everyone understands a supplier delay — but even that has a limit, beyond which silence becomes neglect.

A job under its threshold is left alone; the sweep is meant to be quiet, not chatty. A job over its threshold is a stuck job, and that’s where the sweep acts.

What chasing actually does

A stuck job gets chased in two directions at once. Outward, the customer gets an honest holding note — routed through the same composer and sender as any other message, so it lands in the shop’s voice on the customer’s channel. The wording is built on the one true fact available: the job is still at this stage, and here’s what that means. “Hi Maya — a quick update: your repair is still waiting on a part from our supplier. We haven’t forgotten it, and we’ll text you the moment it’s back in. Thanks for your patience.” It promises nothing it can’t keep, and it never pretends the job moved — the composer’s rule against inventing a stage holds here just as it does on a real move.

Inward, the shop gets a nudge — a short digest of every job over threshold, so the bench can act before the customer has to chase. That’s often the more valuable half: the holding note buys patience, but the nudge is what actually gets the part chased or the finished job handed over. The customer-facing message keeps goodwill; the internal one fixes the cause.

The guard that makes this safe to run daily is dedupe. Left naive, the sweep would re-send the same holding note every morning a job stayed stuck — turning a thoughtful update into a daily nag that trains the customer to ignore you. So the sweep records, in the notifications log, that it has already chased a given job at a given stage, and won’t chase the same job-and-stage again until either the job moves or a much longer re-chase interval passes. A stuck job is acknowledged once, not every day. And like every other message, a holding note that would land inside quiet hours is held until morning — a stalled job is never urgent enough to justify a 3am text.

The daily sweep: measure dwell time, compare to the per-stage threshold, chase what’s stuck Inside a dotted AWS account container. On the left, an EventBridge Scheduler box “daily, early morning” triggers a box “jsnr-sweep”. The sweep reads two stores, drawn as cylinders: “jsnr-stage-history” for the time since each job’s last move, and shop settings for the per-stage dwell threshold. These feed a decision box “dwell over threshold?”. A “no” arrow goes to “leave alone”. A “yes” arrow goes to a dedupe check box “already chased this job at this stage?”; if yes, it routes to “skip, no nag”. If not yet chased, it splits into two arrows: one to “holding note to customer” which passes into the composer and sender (with quiet hours honoured), and one to “nudge to the shop”. A note reads: the sweep catches the absence of movement; it chases a stuck job once, honestly, and never in quiet hours. AWS account Scheduler daily, early jsnr-sweep walk open jobs stage-history + thresholds over threshold? per-stage dwell leave alone no already chased? this job, this stage yes skip — no nag yes holding note to customer nudge to the shop not yet The sweep catches the absence of movement — it chases a stuck job once, honestly, and never in quiet hours.
Fig 5. The daily sweep measures how long each job has sat in its stage, compares that against the per-stage threshold, and for anything stuck — and not already chased — sends an honest holding note to the customer and a nudge to the shop.

Why this half earns its keep

The reactive half of the system — a move, a message — is the part that’s easy to demo. The sweep is the part that earns the goodwill. Customers rarely remember the routine “in progress” text; they vividly remember the time a shop went silent on them for a week, and the time a different shop got ahead of the problem with “just so you know, we’re still waiting on your part.” The first becomes a one-star review; the second becomes a regular. A stalled job is going to happen — suppliers are late, benches get busy — and the difference between a complaint and a shrug is almost always whether the customer heard about it before they had to ask.

And because the sweep reuses the same composer, sender, quiet-hours, and dedupe machinery as everything else, it adds this whole safety net for the cost of one scheduled function and a handful of thresholds in a doc. The shop tunes how patient or proactive it wants to be by editing numbers, not code.

Design rules that shaped the sweep

  • Catch the absence of movement. The sweep watches for jobs that aren’t moving, which is what reactive updates miss.
  • Thresholds per stage. “Awaiting parts” gets a long leash; “ready” gets a short one.
  • Chase both ways. A holding note keeps the customer’s trust; a nudge to the shop fixes the cause.
  • Once, not daily. Dedupe per job-and-stage turns a useful update into something other than a nag.
  • Same guards as everything else. Honest wording, no invented progress, and quiet hours always apply.
All posts