A notification can be sent successfully while the actual product task is still completely unresolved.

A notification record says Sent.
The cleaner still hasn't confirmed the shift.
Those two facts can exist at the same time, which is why I stopped using email delivery as a shortcut for product progress.
I ran into this while working on the notification side of a small shift-confirmation tool. Email is useful for getting an assignment back in front of someone, but the provider-facing result and the user-facing result are not the same thing.
For this product, the action I actually care about is much later in the chain: the cleaner explicitly confirms the shift or says they cannot make it.
Everything before that needs more careful wording.
Three outcomes were more useful than success and failure
For the visible email record, I ended up keeping three results distinct:
Sent
Failed
Skipped
Sent means the system attempted to send the message.
Failed means that send attempt failed.
Skipped means there was no send attempt for that record, so someone should look at the associated shift and decide what to do next.
That sounds like a small labeling decision, but collapsing them into something like Success / Error would make troubleshooting harder.
A failed attempt and a skipped attempt can both result in no useful email reaching the cleaner, but they do not describe the same event.
They should not automatically lead to the same next action.
“Sent” needed a deliberately narrow meaning
The tempting interpretation of Sent is:
Sent
→ delivered
→ seen
→ cleaner knows about shift
I can't actually prove most of that.
The application can record its own send attempt. It cannot look inside the recipient's mailbox and confirm that the message landed in the primary inbox. I'm also not using email-open tracking as a substitute for an explicit shift response.
A cleaner might find the message in Spam, Junk, or Promotions. They might search for it later. They might never see it.
So the notification record has to stop making claims at the boundary of what the product can observe.
That led me to keep the troubleshooting language equally narrow in the shift notification email troubleshooting guide: start with the email record, check the recipient address, then look at the mailbox side separately.
I would rather have a status that sounds less impressive and remains accurate.
Retry wasn't something I wanted to hide behind automation
Another question was what should happen after Failed.
Automatically trying again sounds convenient, but it can also hide the thing that actually needs attention.
If the Team Member email address is wrong, another attempt does not fix the address.
If the record was skipped because of the surrounding shift conditions, another send may not even be the appropriate action.
For the current version, the safer sequence is manual:
- Check the Team Member email address.
- Open the matching email record.
- Identify whether it says
Sent,Failed, orSkipped. - Decide whether another reminder makes sense.
That keeps the retry decision close to the reason the previous attempt did not produce the expected result.
It also means the product does not need to pretend it has a complete email-deliverability engine.
For an urgent shift, I don't want an owner staring at a notification record and repeatedly pressing send while the start time gets closer. The team's existing direct contact method is a better fallback when the assignment needs an answer immediately.
The shift response stays separate
The important separation is not really between three email statuses.
It is between the notification record and the shift response.
These are different events:
Notification: Sent
Shift response: Unconfirmed
That combination is valid.
So is:
Notification: Failed
Shift response: Confirmed
The cleaner could have confirmed through the product after seeing the assignment another way. The email result should not overwrite what is known about the shift itself.
This is why I don't want a successful notification event to move a shift into a confirmed state.
Confirmation requires the cleaner's explicit response.
Email can prompt that response. It cannot stand in for it.
Keep the integration boundary visible
External services make it easy to inherit their vocabulary.
If an email service says something succeeded, it is tempting to carry that word all the way into the product and treat the user task as successful too.
I've found it more useful to ask a narrower question:
What did my application actually observe?
For an email record, that might only be an attempted send.
For the cleaning shift, the meaningful event is still the cleaner pressing Confirm or saying they cannot make it.
Keeping those two records separate gives the interface fewer opportunities to claim that something happened when it didn't.
Sent can stay Sent.
The shift can stay unconfirmed until a person actually answers.
Top comments (0)