Invitations that lead somewhere, profile photos that actually work, and documents that close their own onboarding tasks
This release fixes two ways a person could be left stuck at the front door. Someone invited by an administrator was chased with an email asking them to verify their address, when what they needed was to set a password — and following it stranded them for good. Separately, signing a document sent by hand left the matching onboarding task open, so employees were asked to sign the same thing twice.
Profile photos also work properly for the first time: there is a way to choose and frame one, a photo appears everywhere that person is shown rather than in a handful of places, and it updates the moment it changes instead of after a page refresh or a sign-out.
Alongside those: new organizations now start with a full set of leave types and departments rather than a blank structure, an import can invite the people it creates, departments and data import are restricted to administrators, and a signature that fails validation no longer leaves the signer unable to retry.
Invitations
- An invited employee is now chased with the right email — Two kinds of account sit in the
"email not yet verified" set and they need opposite things. Someone who registered themselves
chose their own password, so what is unproven is their address. Someone an administrator
invited is the other way round: the address was vouched for by the person who typed it, and
the password is one the system generated and never showed them.
Invitees were being sent "Please verify your email address". It does not unblock them, and following it made things worse: verifying marked the address proven, dropped them out of the follow-up schedule for good, and still left them with no password. The real invitation expired quietly in the background. They now receive their setup link again instead, with a fresh fourteen-day token. - Follow-ups are timed to when someone actually needs access — Reminders counted from the day the record was created, but administrators routinely set people up weeks before they start. That meant every reminder fired, and the invitation lapsed, before the new starter's first day. Invitations are now chased on day 3, 7 and 13 counted from a week before the start date, or from the day the account was created if that is later. The last nudge lands the day before the first link expires, so it arrives while the original is still usable.
- Former employees are never chased — Anyone whose employment end date has passed is skipped entirely, so a roster containing leavers cannot produce an email inviting them to activate an account.
Data import
- An import can invite the people it creates — Imported employees were created with no usable
password and nothing to tell them the account existed. The preview step now offers Invite
these employees to set up their accounts: ticked, each person is emailed a link to choose a
password and is followed up on the same schedule as any other invitation.
It is off by default. An import is as often a historical roster — leavers, closed leave — as it is a live workforce moving across, and emailing a former employee a link to activate an account is the one outcome nobody wants. Anyone whose employment has already ended is skipped even when the box is ticked, so the file decides rather than anyone's memory of what is in it. - Imports no longer report failure after succeeding — Every import finished by writing an audit entry with an action the database does not recognise. The records were created, then the write was rejected, so the job was marked failed and the administrator was told the import had not worked and invited to run it again.
Documents
- A document sent by hand now closes the onboarding task it satisfies — An administrator
can send a template straight from Documents → Templates, and the same document can also
be attached to an onboarding or offboarding task. Signing the one sent by hand left the task
open, so the employee was asked to sign a document they had already signed.
The machinery to close the task already existed; what was missing was the link. Only documents created by an onboarding task recorded which template they came from, so a hand-sent document was an orphan with nothing to match on. Both the one-off send and the bulk send now record it, which closes the loop in both directions: signing a hand-sent document completes the task, and a task that later needs that document reuses the one already sent instead of issuing a second copy.
A task is only ever closed by the employee it belongs to signing their own copy. Where a document carries more than one signer — an agreement counter-signed by a manager, say — the counter-signature closes nothing for the manager, who still has their own copy to sign. - A signature that fails validation can now be corrected — Submitting a signature with a required field still empty marked the assignment as signed and then rejected the submission. The document was never actually signed, the onboarding task never closed, and every retry was refused with "This document has already been signed" — leaving the signer with no way forward at all. The signature is now recorded only after the submission passes validation, so a rejected attempt leaves everything as it was and can simply be retried.
- Templates and bulk send are reachable from the upload page — "Add a document" only ever uploaded a fresh file, and the links to saved templates and bulk send existed on the documents list alone. Administrators who started from the upload page had no route onward and no sign that either feature existed, and were re-uploading files they already had as templates.
Onboarding for new organizations
- Ten leave types instead of eight, with the right icons — A new organization was missing Sick Leave (Unpaid) and Special Event Leave, and Annual Leave carried the umbrella icon that belongs to Unpaid Leave — the two had been swapped. The full set is now Annual Leave (Vacation Time), Sick Leave (Paid and Unpaid), Working from home, Special Event Leave, Maternity, Paternity, Meeting, Compassionate and Unpaid Leave. Each requires manager approval, deducts from the correct balance, and carries the privacy setting its category calls for.
- Six departments to start from — Sign-up left an organization with a single department
named after the company itself, created only so the founding user had somewhere to belong;
everything else had to be built by hand before anyone could be invited into a department.
New organizations now start with Executive, Software Development, IT Operations, Finance &
Accounting, Sales and Operations, each with its own colour. The placeholder becomes the
Executive Department rather than sitting alongside the new ones, so the founder keeps their
membership.
Seeding only ever runs on an organization's first trip through setup, and the rewrite only touches a department still untouched since sign-up — an administrator who renames it first keeps their name, code and colour.
Profile photos
- Choosing and framing a photo — There was no way to set a profile picture after the
first-run wizard, and no way to say which part of an image to use: whatever was uploaded was
centre-cropped by the browser, so a photo that was not already square was cropped by luck.
Picking a photo now opens a framing step — drag to reposition, scroll or use the slider to
zoom, and what sits inside the circle is what is saved.
Framing on a canvas also drops the orientation data that makes phone photos appear sideways, and normalises every upload to one size and format regardless of what was chosen. - Photo actions live on the profile, next to Edit Profile — Clicking the picture opens the actions directly: see the picture, choose a new one, or remove it. The same entries are in the Edit Profile menu, which is where someone looks when they want to change a colleague's photo rather than their own. An employee with no other editing rights sees only the photo entries there; the information sections stay with administrators.
- Photos open in a viewer with zoom — Opening a picture used to give a flat, fixed-size image, which is not much use for the one thing people open a photo to do. It now opens in a viewer with zoom in, zoom out, a percentage that returns to fit when clicked, drag to pan, scroll and keyboard shortcuts, and Escape to close.
- A new photo appears everywhere at once — Uploading a photo changed it on the profile page while the sidebar beside it carried on showing initials until the page was reloaded — and for anyone whose photo was set after they signed in, not even a reload helped, only signing out and back in. Each part of the app kept its own private copy of the image and none of them could tell the others that it had changed; the sidebar, separately, read the photo from a snapshot written once at sign-in and never updated. There is now one shared copy, and a photo changed anywhere is picked up in place by everything showing that person.
- Photos now show where only initials did — Around thirty places drew their own initials
circle and could never show a photo at all: the people directory and org chart, approvals,
timesheets, schedules, projects and issues, time tracking, the team map, reports and client
activity. They now all render the same component.
Four of those could not show a photo even when asked to, because the data behind them left the photo out; those queries now include it. Two more were worse than empty: the Time and Leave report tabs passed a storage path straight to the browser as an image address, so every person with a photo rendered as a broken image, and the initials fallback never ran because the path looked like a valid value.
Permissions
- Departments are administrator-only — Creating a department and running organization setup had no role check at all, so any employee could add departments or re-run setup and rewrite the leave year, default allowance and timezone. Both now require an administrator or executive. Reading the department list is unchanged, since everyone needs it for filters.
- A department head can rename the department they lead — Previously they could not correct even the name of their own team. They can now change its name, description and colour. The code, the active state and the head assignment stay with administrators, because those decide the department's identity and who controls it rather than how it reads.
- Data import is administrator-only, and hidden from everyone else — Creating an import job already required an administrator, but nothing else in the pipeline did. With a job left part-finished, any employee could run it, roll it back or delete it — and running one writes employee and department records. The row-level error report was readable too, which quotes the uploaded file and therefore colleagues' details. Every import endpoint now requires an administrator or executive. The settings entry was already hidden, but the page itself had no guard, so a typed URL rendered the whole import interface.
Security
- Values are escaped before they reach an email — Email bodies are assembled as text, and names were being placed into them without escaping. A name containing a link would have rendered as a working link inside a message carrying our branding and sent from our domain, sitting above the genuine button. Every value interpolated into an email is now escaped; ordinary names are unaffected.
- Invitations sent by an import are held to the plan's user allowance — Inviting turns one upload into one email per row from our own sending domain, so the number that can be sent is bounded rather than left to the size of the file.
Fixes
- Calendar tooltips are no longer cut off — Hovering a day near the right-hand edge of the dashboard calendar showed a tooltip clipped by the card, so the leave type and status were unreadable exactly where the grid is busiest. Tooltips now stay within the window wherever the day sits, and still point at the day they describe.