DEV Community

Miran
Miran

Posted on

Before I Debug an “Overdue” Shift, I Check Whether It’s Still Unconfirmed

A stale response deadline can survive after a cleaner replies, so an aging report needs an exit condition before it needs better time math.

Three cleaning shift cards on a magnetic scheduling rail show an active unconfirmed timer, a stopped timer after confirmation, and a Pending Cover shift routed to cover review instead of another reminder
An August 7 shift has a response deadline of August 6 at 5:00 PM.

Today is August 7.

That looks overdue.

There is one problem: the cleaner already confirmed.

If I calculate “time pending” from the deadline alone, I can produce a perfectly accurate duration for a record that should no longer be pending at all.

That was the failure case I kept in mind while structuring a manual pending-response report for cleaning shifts.

The report does not currently calculate aging automatically. That is intentional. Before automating the clock, I wanted the conditions for entering and leaving the follow-up list to be understandable.

Check membership before calculating age

A naive aging rule is easy to imagine:

pending_time = now - response_deadline
Enter fullscreen mode Exit fullscreen mode

For an unresolved shift, that may be useful.

For a resolved shift, it is meaningless.

The first check therefore cannot be the timestamp. It has to be whether the row still represents unresolved work.

A cleaner who has explicitly confirmed should no longer be treated like someone who has not replied, even if the original deadline is still present in the record.

The example report makes that difference visible:

Current status: Confirmed
Response deadline: Aug 6, 5:00 PM
Time pending: Reply received
Next action: No response follow-up needed
Enter fullscreen mode Exit fullscreen mode

The old deadline is still useful history.

It just no longer owns the next action.

If I eventually automate this kind of report, I would want the eligibility test to happen before any aging calculation.

Something conceptually closer to:

if current_status != "Unconfirmed":
    stop_aging_this_row
Enter fullscreen mode Exit fullscreen mode

That is a design rule, not production code.

A timestamp can stay valid after its job ends

This is the part that can make debugging confusing.

The response deadline is not wrong.

The assignment-sent timestamp is not wrong.

The last reminder timestamp may not be wrong either.

They describe things that actually happened.

What changes is whether those timestamps should still drive follow-up.

That is why deleting or overwriting old timing fields would not solve the problem. I still want to know that the assignment went out on August 6, that a reminder was sent later that day, and that the original deadline was 5:00 PM.

The row becomes easier to debug when historical timestamps and current action are allowed to coexist.

A stale deadline is only a bug if the application still treats it as an active instruction.

The pending shift response report template keeps Current status, Last reminder, Response deadline, Time pending, Follow-up owner, and Next action visible as separate columns.

That separation is useful because I can inspect the decision instead of guessing it from one date.

Pending Cover needs a different branch

There is another row that should not fall through the same aging rule.

A cleaner says they cannot make the shift.

The shift is now Pending Cover while an Owner or Admin reviews a Cover Request.

The old confirmation deadline may already have passed, but another “please confirm your shift” reminder would be the wrong action.

The unresolved work has changed.

For an Unconfirmed shift:

next action → check for reply or follow up with assigned cleaner
Enter fullscreen mode Exit fullscreen mode

For a Pending Cover shift:

next action → review the Cover Request
Enter fullscreen mode Exit fullscreen mode

Those rows may both look unfinished in a dashboard.

They are unfinished for different reasons.

If I were debugging a reminder that fired against the Pending Cover row, I would not start with email delivery or the scheduler. I would first ask whether the reminder selector ignored the current shift status.

That narrows the investigation quickly.

“24 hours old” is not the same as urgent

The report also avoids defining one universal 24-, 48-, or 72-hour aging rule.

That matters because a cleaning shift has another clock: the start time.

An unconfirmed shift that starts in two hours may deserve attention before a record that has technically been pending longer but belongs to a job later in the week.

So there are at least two useful timing questions:

How long has this response been unresolved?
Enter fullscreen mode Exit fullscreen mode

and:

How much time remains before the shift starts?
Enter fullscreen mode Exit fullscreen mode

Those are not interchangeable.

The manual report recommends sorting by response deadline or time-to-shift so an Owner or Admin can decide what actually needs attention first.

For a shift that is getting close, the fallback is also more direct: use the team's existing contact method rather than assuming another email is enough.

That makes the debugging model less elegant, but more realistic.

A long elapsed duration is a useful clue.

It is not automatically the highest-priority failure.

Automate after the exit conditions are boring

The current template deliberately stays manual. It does not calculate aging, send reminders, escalate a row, or reassign work automatically.

I like that boundary for an early version because it exposes the decisions that automation would eventually need to reproduce.

Before I add a timer, I need to know:

  • when an Unconfirmed row starts aging;
  • what explicit confirmation does to that timer;
  • what a Cannot make it response changes;
  • when Pending Cover stops being a confirmation-follow-up problem;
  • which action belongs to an Owner or Admin next.

Once those exit conditions are boring, the time calculation is the easy part.

Without them, better timestamp math just produces more precise false positives.

Top comments (0)