The staff rota engine: publish the schedule once, and be able to prove it
Availability collected before the deadline, rest-time and contract-hour breaches caught before you send it, and a dated record of every schedule you published
- Your own notice deadline written down before you build anything: five working days for variable part-time rosters in Belgium unless a generally binding sectoral agreement shortens it, 72 hours for a New York City retail employer with 20 or more staff, otherwise whatever your contracts and work rules already promise
- A machine that stays on and is reachable over HTTPS, because staff enter their availability from their own phones
- Contract hours, required skills or certificates and maximum consecutive days per person, current on the day you build the table and re-verified every time a contract changes
- A real minimum-staffing rule per hour of the week: how many people, and which skills must be among them, or the coverage check has nothing to test against
- Agreement with your team on how weekends and public holidays are shared, before any of it is encoded
- A privacy notice covering what the rota system stores about staff and how long it is kept, and an availability form with no field for the reason
Version history
Verdict first: the planner is not the valuable part. Any spreadsheet can draw a week. What a spreadsheet cannot do is stop you sending a rota with an illegal gap in it, and it cannot prove what you published and when. Those two things are the build. If you have fewer than five staff on fixed hours, skip this and keep your spreadsheet. Between roughly five and twenty-five people on shifts, this is a weekend that removes a recurring argument.
The architecture
the same flow as text
[ you ] → contract hours, skills, minimum staffing per hour
▼
[ Grist — one table, on your own box ]
├─ deadline reminder, then a chase to whoever has not answered
└─ you draft the week here, by hand, the way you always have
▼
[ n8n — the check, before anything leaves the building ]
├─ less than 11 h between two shifts → named, with both shifts
├─ no 35 h break in the week → named
├─ rolling 48 h average, contract hours over or under
├─ an hour with nobody, or nobody holding the required skill
└─ publishing later than your own notice deadline
▼ clean, or you fix it and run it again
[ publish, once ]
├─ a dated PDF, filed and never edited
├─ a calendar feed per person, subscribed on their phone
└─ one message to the team, timestamped
Every change after publication writes a new dated version. Nothing overwrites.
Three parts, and the middle one is the product. A table anyone can edit, a check that runs between drafting and sending, and a publish step that leaves a record it cannot quietly change. You still decide who works Saturday. The machine collects, checks, sends and remembers.
The problem
The rota costs a small business two separate things, and only one of them is time. The time is the chasing: who is away in week 34, who swapped with whom, and the six messages that arrive after you send it. The other cost is that in the EU the moment you publish a schedule is a regulated moment, and most small teams cannot say what they published or when they published it.
What the rules actually ask for. Directive 2003/88/EC sets three numbers you have to plan against: 11 consecutive hours of rest in every 24 (Article 3), 24 uninterrupted hours plus that 11 in every seven-day period (Article 5), and a 48-hour average per seven days including overtime (Article 6b), averaged over a reference period of up to four months (Article 16b, longer by derogation or collective agreement). Directive (EU) 2019/1152 adds the part people miss: where the work pattern is mostly unpredictable, staff must be told the reference hours and days they can be asked to work and given a reasonable minimum notice, and if either is missing they may refuse the shift with no adverse consequences. It applies from an average of more than three hours a week over four weeks, so almost everyone with a weekend student is inside it.
In Belgium the notice period is a hard number. For part-timers on a variable schedule, the individual rosters must be communicated in a written, dated notice at least five working days in advance. A generally binding sectoral collective agreement can shorten that, but never below one working day. The notice, or a copy, has to sit where the work rules are consulted for as long as the roster is in force, and be kept for a year after it stops being in force. That is a document retention rule, and it is the reason a rota that only ever existed in a group chat is a problem.
In the US the same idea arrives as predictive scheduling, mostly aimed at chains. Oregon requires a written schedule 14 calendar days ahead and pays a premium for employer-made changes, but only for retail, hospitality and food employers with 500 or more workers worldwide. Seattle's ordinance also starts at 500. The one that reaches a genuinely small business is New York City: its Fair Workweek Law covers any retail business with 20 or more employees across all its NYC stores under common ownership, counting part-time and seasonal. Those employers must give the schedule 72 hours before the first shift, may not use on-call shifts, may not cancel or cut a shift by more than 15 minutes inside 72 hours, and must hand over any past schedule from the last three years within 14 days of a worker asking. First violation, $500.
What you would otherwise rent. Planday lists from £2,99 per user per month with a five-user minimum. Papershift's own booking page runs $4, $6 and $9 per employee per month excluding VAT. Shiftbase's tiers start around €30 a month including six employees and around €72 including twelve, plus €4 to €6 per employee above that. Per-location tools sit higher: an April 2026 comparison of restaurant tools puts Combo at about €60 a month per location and Skello at about €79. At ten staff that is roughly €350 to €900 a year against €60 to €180 for the box below. Be honest about that gap: a few hundred euro a year is a reason, not a compelling one. The compelling one is that the check and the archive are yours, and neither is a feature you can buy back cheaply once a dispute starts. List prices move, so verify before you quote them.
Tool choices — and why
Setup outline
1. Write down your own notice deadline first, before you touch any software. Belgium: five working days unless a sectoral agreement in your joint committee says otherwise. NYC retail at 20 or more staff: 72 hours. Elsewhere: whatever your contracts and work rules already promise. Everything below is built backwards from that date.
2. Build the staff table in Grist: name, contract hours per week, skills or certificates that gate a shift, maximum consecutive days, and any fixed unavailability. This table is the one that goes stale, so put a review date on it now.
3. Add the availability form and a deadline two days before you draft. Ask when someone cannot work. Do not ask why. What you will see when it works: a table that fills itself in over the week instead of arriving as messages.
4. Wire the chase in n8n: at the deadline, a single message to whoever has not answered, and a summary to you. One chase, not three.
5. Draft the week by hand in the rota table. You are not automating this part yet, and possibly ever.
6. Build the check as one workflow that reads the draft and returns a list, not a verdict: rest under 11 hours between consecutive shifts, no 35-hour break in the seven-day period, rolling 48-hour average against your reference period, hours over or under contract per person, hours with nobody rostered, hours with nobody holding a required skill, and whether the publish date is inside your notice deadline. Every finding names the person and the two shifts that caused it. What you will see when it works: a green line, or a list you can act on in two minutes.
7. Build the publish step: render a dated PDF and file it read-only, write one calendar file per person to a secret URL, send one notification. Then test the reverse: pull last month's PDF out of the archive and check it is the version people actually worked.
8. Add the change log. Any edit after publication produces a new dated version and a message naming what moved and how much notice the affected person got. Run the whole thing in parallel with your current method for four weeks before you rely on it.
Pitfalls — the real ones
Verified repos
Grist — Apache-2.0, 11.441 stars, pushed 11/08/2026
n8n — Sustainable Use Licence (fair-code, free for internal business use), 200.261 stars, pushed 11/08/2026
Timefold Solver — Apache-2.0, 1.669 stars, pushed 01/06/2026
Timefold Quickstarts (employee-scheduling) — Apache-2.0, 554 stars, pushed 12/06/2026
NocoDB — 64.498 stars, pushed 11/08/2026
Radicale — GPL-3.0, 4.895 stars, pushed 08/08/2026
ntfy — Apache-2.0, 33.401 stars, pushed 11/08/2026
Frappe HR — GPL-3.0, 8.553 stars, pushed 11/08/2026