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.
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.