feat(notifications): warn the manager and HR about a short-notice req… - #37
Merged
Conversation
…uest
A request filed for next Monday and one filed for next quarter arrived looking
identical. Nothing in the notification, the email or the review panel said which
was which, so the fact that mattered most for planning — how much warning the
team was given — was the one thing a decider had to work out for themselves from
two dates.
A request whose leave starts sooner than the notice period the company expects is
now flagged as short notice, to the line manager and to HR, everywhere the
decision is actually made:
- on the request's Details tab, as a warning card above the approve/decline
buttons rather than behind the Coverage tab;
- in the notification, which says so in its subject line — the one line
guaranteed to be read — and gives the day count in the message;
- in the email, whose heading doubles as the mail's subject, so it is legible
in an inbox listing while there is still time to act.
The escalation to HR and the pending-decision reminder carry it too. By the time
either fires the notice has only grown shorter, which is exactly when saying so
is worth most.
The threshold is a new admin setting, "Expected notice period", defaulting to 14
calendar days; 0 switches the warning off. Calendar days rather than working days
because "two weeks' notice" is a fortnight on the wall calendar — unlike the
escalation window, which counts the days a manager actually had to answer in.
Measured against the server's today, not the viewer's, so one request gets one
answer for the manager, for HR and for the job that mails them, instead of a
sidebar and an email that disagree by a day at a timezone boundary.
Two limits on when a warning appears, both in NoticeService:
- Only while a decision is outstanding (PENDING / ESCALATED). Afterwards short
notice is no longer an input to anything, just a standing reproach on the
record.
- Which also means never for leave that has no approval workflow. Sick leave is
recorded by HR after the fact and auto-approved types are booked straight
through (§4.1); both reach APPROVED without ever being pending. Nobody is
weighing the notice there, and nobody gives notice of falling ill.
The warning's wording lives in one place, NoticeService::sentence(), because the
same sentence is shown in the notification, in the email and (mirrored in the Vue
component) in the sidebar — one string to translate rather than three that drift
apart. It also avoids claiming leave "starts in 0 days": today and already-started
get their own phrasings, the latter reachable through an edit or a late correction.
Notifications written before this change carry neither new subject parameter, so
the notifier reads both defensively rather than failing to parse an existing row.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
…uest
A request filed for next Monday and one filed for next quarter arrived looking identical. Nothing in the notification, the email or the review panel said which was which, so the fact that mattered most for planning — how much warning the team was given — was the one thing a decider had to work out for themselves from two dates.
A request whose leave starts sooner than the notice period the company expects is now flagged as short notice, to the line manager and to HR, everywhere the decision is actually made:
The escalation to HR and the pending-decision reminder carry it too. By the time either fires the notice has only grown shorter, which is exactly when saying so is worth most.
The threshold is a new admin setting, "Expected notice period", defaulting to 14 calendar days; 0 switches the warning off. Calendar days rather than working days because "two weeks' notice" is a fortnight on the wall calendar — unlike the escalation window, which counts the days a manager actually had to answer in. Measured against the server's today, not the viewer's, so one request gets one answer for the manager, for HR and for the job that mails them, instead of a sidebar and an email that disagree by a day at a timezone boundary.
Two limits on when a warning appears, both in NoticeService:
The warning's wording lives in one place, NoticeService::sentence(), because the same sentence is shown in the notification, in the email and (mirrored in the Vue component) in the sidebar — one string to translate rather than three that drift apart. It also avoids claiming leave "starts in 0 days": today and already-started get their own phrasings, the latter reachable through an edit or a late correction.
Notifications written before this change carry neither new subject parameter, so the notifier reads both defensively rather than failing to parse an existing row.
🤖 AI (if applicable)