Roster
Roster (sidebar → Operate → Roster) is the posting sheet for your whole operation: site guards, reaction units and control-room seats. It plans who should stand which post on which rotation, watches the day unfold (book-ons, no-shows, relief), runs check calls, offers open shifts to the qualified pool in rounds, and classifies the month for payroll.
Roster is an optional module — it appears only when CleverCam has enabled it for your control room. Everything on the page requires a management capability (the same audience as Response), and its warnings — hour caps, PSIRA grades, rest gaps — inform, never block: the manager always owns the sheet.
The roster also runs itself: a 5-minute heartbeat keeps the day-of window materialised on each control room's own date, widens offer waves whose deadline lapsed, matches WhatsApp replies to offers, flags no-shows and sends the control-room members a push when someone misses their book-on grace or two consecutive check calls. Nothing depends on having the page open.
Those heartbeat alerts go to every team member with CleverCommand access, and they arrive on CleverResponder — the app they are signed in to on the phone, not the customer-facing CleverAlert app. Somebody who is not signed in to CleverResponder is not told; if the room works the desk in a browser and nobody carries the app, watch Roster → Attendance rather than waiting to be told.
The seven tabs
The tabs run in the order the work happens, book-ended the way every other CleverOps page is:
| Tab | The question it answers | What it owns |
|---|---|---|
| Overview | Where do things stand? | Stat cards that open the tab that does the work, warnings, the set-up checklist |
| Posts | What must be covered? | Every post and its cover lines — sites, popup sites, units, desks |
| People | Who can we post? | The rosterable team, what each person stands, their hours and PSIRA state |
| Roster | Who stands where, when? | The posting board, placements, absences, fills and offers |
| Attendance | Who actually stood? | Today's exceptions, check calls, the evidence ledger, and the month-end reading for payroll |
| Reports | How did the cycle go? | Posted vs asked, wrong class, overtime, no-shows, shifts shown, contract vs delivered |
| Config | How does this company run? | Shift types, shift patterns, the pay cycle, rates, the numbers every other tab reads |
Branches
A control room with more than one branch gets a Branch picker in the page header — All branches by default, then each branch with how many posts it holds, and No branch for the posts that sit in none. A room with one branch never sees it.
Pick one and the whole page is that branch: the posts, the board, the coverage and officer figures, Attendance's lanes, Month end and every report. A line under the header says so and counts what you are seeing ("8 of 13 posts"), because a short board that does not explain itself reads as lost data. An empty branch says that too, rather than showing nothing at all. People are never filtered — a guard does not belong to a branch, and the same body may stand posts in two.
A post is in a branch three ways, in this order: the Branch field on its own sheet; failing that, for a unit post, the vehicle's branch; failing that, for a site post, the branch its site's dispatch area belongs to — and only when that area sits in exactly one branch, because an area may belong to several and a guess is worse than a blank. Add a post while a branch is showing and it starts in that branch.
The branches themselves are the regions you set up under Areas → Regions — the
same ones dispatch and coverage use. The choice rides the URL (?branch=), so a branch view is a
link you can send.
Until a control room has cover lines, rosterable people, a placement and a shift somebody stood, a slim set-up strip sits under the header on the four working tabs — Posts → People → Roster → Attendance — showing which of the four is done. It disappears for good once all four are.
Old links keep working: ?tab=board, ?tab=demand, ?tab=today, ?tab=offers, ?tab=pay and the
rest land on the tab that holds that work now.
Overview
The landing tab and a router, not a workplace. Every card is one click into the tab that owns the work:
- Coverage · next 7 days → Roster. Required shifts staffed, as a percentage.
- Gaps today → Attendance, where Fill lives.
- Open offers → Attendance.
- No-shows · 7 days → Attendance.
- Contracted book → Posts: how many officers your cover lines demand, shown two ways — no overtime (weekly contracted hours divided by 48 ordinary hours) and the industry 4+2 convention (a primary officer works 4 shifts a week and a reliever carries 2). Which one the headline uses is set under Config → General.
A warnings card lists double-bookings, placements that can no longer put anybody on a post, people trending past their ordinary week, PSIRA certificates lapsed or lapsing, grade mismatches against cover lines, and placements ending without a successor. Clicking a warning that names a person opens their record.
Until the four set-up steps exist, the Overview leads with a Set up the roster card — the same four steps as the strip, each with its own button.
Posts
Every post the room covers — sites, popup sites, units and desks — on one page, one line per post, grouped by those four kinds, and how much of each the plan actually covers.
A site's guard posts and cover lines can also be captured on the site record itself, under Sites → (a site) → Guarding, alongside the rest of that site's setup. It is the same data, written by the same code: a post created there appears on the roster straight away, and the cover-line sheet is the very same sheet. See Site Details → Guarding.
The toolbar's category switch — All · Sites · Popup sites · Units · Desks, each with its count — and the search box narrow the list. The stat tiles above it read the whole book: Posts, Shifts this week (stood / asked, with the open count), Officers needed (no overtime, with the 4+2 convention beneath), Contracted hours and the Wage floor at NBCPSS minimums — every site priced at its own wage area (Config → Rates & allowances → Site wage areas), else the room's.
Every cover line is read two ways: what it asks for, and how many of those shifts somebody stands in the board's loaded week (the toolbar names the week; page the Roster tab and Posts follows). People on leave, marked absent, no-show or released don't count as cover — the same rule as the board's cells — so the two never disagree.
- The row is the post: its name; its lines as chips —
D 06:00–18:00 · 1× C armed,N 18:00–06:00 · 2×(hover for the days, check calls, grace and dates; days read compactly — daily, Mo–Fr, Sa Su +PH — future-dated lines say from, ended ones ended and dim) — click a chip to edit that line, + to add one; the week's coverage bar with n open / covered; who is standing on it (the first two names, then +n); the officers its hours need; and Open ›. The shortest-covered posts sort to the top of every section — the list doubles as the hiring queue. A post with no lines reads no lines — free-form on the board, and the posts still waiting for a line — nothing asked, nobody standing — fold into one free-form strip per section, each name a chip that opens the post. - Click the row for the post's sheet: the lines by window (two lines on one 06:00–18:00 window are one shift, and the cover on it is one number — the band header says so), Standing on this post (chips open the person's record; + Assign opens the crew sheet), for a site the Headcount and wage floor box (both conventions; the floor at the site's own area) and Preferred & banned at (site), and Scenarios — save these lines as a reusable scenario, or apply one here. The sheet's header carries Board ↗ (the Roster tab filtered on this post), Edit post, + Assign and + Add line. Edits to a line apply from a day onward by default (the line splits; history stays).
- The cover-line sheet starts from one of this company's shift types — Day, Night, a working day, an 8-hour turn, or 24 hours (day + night), which writes two lines — and everything below stays editable: headcount, the job class the client buys (People → Config keeps the list; picking one brings its paperwork with it), what the line requires — PSIRA · at least Grade B, firearm competency · handgun or shotgun, first aid, a driver's licence code, or any kind the company added under Settings → Reminders — days, check calls (a new line starts on the room's default cadence), late grace, effective window, source, and (on site posts, where the billing lines are visible to you) Billed under. Who the client needs sits on the same sheet: a gender or an EE category — lawful only as an inherent requirement of the job (Employment Equity Act s6(2)(b)), so the sheet insists on the reason, recorded with who set it — or a language, the safer form of what a client usually means. Fill and offers filter on all of it and say why someone was left out. Typing your own times moves the chip to Custom. The late-grace field shows the room's default from Config; the line may differ. A window over 12 hours draws a BCEA s9 warning — informing, never blocking.
- The wage floor is the NBCPSS minimum wages in force for the week shown — a floor, not a price: premiums, provident fund, levies and overheads sit on top. Preferred & banned is per site: banned is the one red flag the Fill flows enforce, preferred people go in an offer's first round. Scenarios written back onto a post get the room's late grace and the matching shift type, the same as lines written by hand.
- Popup sites are sites with an ad-hoc line. + Popup site is the short-notice job in one sheet: it creates a real site (flagged temporary with an end date), its guard post and ad-hoc line, and optionally builds the shift offer in the same step. They sit in their own section so short-notice work never hides between the contracts.
- Units and Desks carry the same demand lines — crew or operators per window; the board counts crewed vehicles and desk sessions against them. + Unit post and + Seats post only exist when the control room has units (Response → Units) or workstations (Control room → Workstations) — a guarding-only company never sees them.
People
Everyone the roster may place, in one list — the board is read per post; this is where the team is read. The tab lists the rosterable people of the control room, one line each:
- Person — name (click it to open their record), PSIRA grade, employment kind (permanent / casual) where the staff profile says so, and a no profile tag when nobody has captured a staff profile for them yet.
- Status — assigned (standing at least one post on a pattern, with a count when more than one), spare (no standing placement and not on leave — the reliever bench), or on leave with the date it ends.
- Standing on — the posts they hold, each with its pattern; click a post to edit that placement.
- This week — planned hours (amber past their ordinary week, red past their ceiling — the job class's rule set, moved by a signed agreement).
- PSIRA — number and expiry, amber inside the PSIRA kind's warning window, red once lapsed.
- Phone — from the staff profile.
- Assign puts them on a post + pattern (opens the crew sheet with them already ticked); the ⋯ menu opens their record or the board around them, records an absence, edits any of their placements, or jumps to their profile under People.
Filter chips slice the list — Rosterable / Assigned / Spare / On leave / Requests / Warnings — each with its count, and the search box matches names, phone numbers and PSIRA numbers. A link above the list counts the people who are not rosterable and takes you to People.
Who is rosterable
The roster may only place people who are rosterable. By default that is everyone with control-room access, everyone with reaction (CleverResponder) access, and everyone classified as a guard on their staff profile — technicians, sales and office staff are not. A manager can override it per person on the staff profile under People → (person) → Person → Rosterable: Default, Yes (the owner who also stands shifts, the technician who does standby) or No (the operator who must never be rostered). The roster's lists, bench counts, Fill and offer pools, roster links and the set-up step all follow the same rule; the People page shows a Rosterable tag on each row it applies to.
The rail lists the patterns in use with how many people stand each. Patterns are created, edited and retired under Config → Shift patterns; the crew sheet can also create one inline. Under it, Bench at a glance counts the rosterable people, the assigned, the spare, who is on leave now, requests waiting and how many have no staff profile.
The person record
Click any person — a name on the People tab, a warning on Overview, Open profile in the
Roster's person drawer — and their record opens over the page (the address bar carries
?person=<id>, so it can be linked and survives a refresh). It is the place to read one person
the way the Roster reads a week:
- Hero — name; what they are doing right now (On post now · site, Due on post, On leave · to date, Next · day time, or Spare); PSIRA grade; working-group tags (Control room, Reaction, Guard permanent / casual); PSIRA lapsed / lapsing and no-profile flags. Actions: Assign (the crew sheet, with them ticked), Record absence, Open on board (the week around them), and a ⋯ menu with the roster link (create & copy / revoke), edit any placement, and edit the profile under People.
- Readiness rail — what makes them deployable, in the order it is usually sorted out: Profile captured → PSIRA valid (grade and expiry under it) → Armed (only shown when a firearm competency is on file) → On a pattern (since when) → Stood a shift (first date) → Roster link (issued; how many times opened). The first thing missing is ringed.
- A banner under the hero calls out a lapsed PSIRA, a running absence, a week that is double-booked (which comes first — a clash means a post has nobody, which outranks somebody being near their ceiling), or a week over the MCA ceiling.
- Context rail — Contact (tap-to-call phone, home suburb, transport mode); Credentials (PSIRA number and expiry, grade, firearm competency, and the written working-time agreements on file — add or remove them here); Standing on (each live placement with its pattern and start, Edit on each, + Assign); Site preferences (preferred / banned, set per site on Posts).
- Overview tab — Recent work over a 4-week or 13-week window, straight off the posting ledger (what was stood, not what was planned): shifts stood with hours and the weekly average; no-shows and their rate against expected shifts; check calls answered %; late book-ons (after the grace window) with how they booked on (self-post / control room / auto); nights · Sundays · public holidays; and stepped in — relief fills stood for someone else. Then Most worked posts (top three, with share — the familiarity Fill and offer round 1 rank on), This week on the MCA meter, Recent absence with sick / leave / requested-off counts, and Coming up · next 14 days (postings through tomorrow, the plan after that) — or, when nothing is rostered ahead, an Assign prompt. Shifts we can show counts how many of the shifts they stood carry evidence, and how many closed on assumption alone.
- Shifts tab — every posting on record for the last 90 days: date, post (with relief and ad-hoc tags), times with a night marker, state (rostered / confirmed / on post / completed / no-show / released), how they booked on and how late, and check calls answered out of due.
- Absence tab — every absence on record (annual leave counted in days, sick in shifts, one-shift taps shown as such), each marked past / now / ahead, plus the list of no-shows in the last 90 days.
Roster
Three readings of the same span on a Grid / By post / By person toggle, over a Week / Fortnight / Cycle span (Cycle appears when Config → General pages by a pay cycle; the board opens on the span set under Config → Attendance rules), with ‹ › paging and Today.
The grid
The default reading, and the one Attendance reads too: one site (or the whole book), one span, people as rows, days as columns, a letter per day. The letters are this company's shift types from Config (D, N, W…); an absence kind's letter sits on a hatched pill (L, S, I…); a released shift is struck through; ✗ is a no-show; · is a day with nothing. Above each post's people, one header row per shift band says rostered / needed for every day (green, amber, red) and an Open row carries the red n open pills — click one for the Fill panel. Click a letter for the person drawer, a name for their record; a ! badge marks a double-booking. A legend under the grid names the letters on screen. Learned once, used twice.
By post
The posting board — posts as rows, days as columns — in up to four groups: Units — reaction, Control room, Sites — contractual and Popup / emergency (a site whose demand lines are all ad-hoc — the shape the popup quick-create writes). A group only appears when the control room has that kind of thing: units created under Response, workstations created under Control room, a popup job running. Sites always show. Everything is created from one + Add cover ▾ menu in the toolbar — Cover on a site, Popup / temporary site, and Unit post / Seats post where the room has units or desks.
The first two groups fill themselves: every unit (Response → Units, on or off duty — a unit being off shift is exactly why it needs a crew rostered) and every active workstation (Control room → Workstations) always has a row on the board. The row is created together with the unit or desk itself, so the board can never disagree with those registers: a new unit or desk is on the roster immediately, and a renamed one follows its new name. A deleted unit or a retired workstation leaves the board (a retired workstation's lines and history stay on record). These rows can't be deactivated from the board; the register owns them. You can still add more on top — a second post on the same unit, or headcount pool posts for the control room alongside the per-desk rows.
The sheet reads like a spreadsheet with frozen panes: the day header and the post/shift columns stay put while the grid scrolls. Today's column is highlighted, public holidays are marked in the header, and each day header carries a red n open counter — the week's holes in one glance. The Week / Fortnight / Cycle span applies here too (a 4-on-4-off cycle is 8 days long and fortnight rest rules read on a fortnight; a pay cycle shows the whole cycle); weeks start on the day set under Config → General. The filter box narrows the sheet to matching posts and sites (or people, in By-person view). Keyboard: / focuses the filter, [ and ] page the view back and forward, t jumps back to the span holding today.
Each post splits into one shift band sub-row per demand window — two 12-hour lines make a day and a night row, three 8-hour lines make three rows — with the band's hours and how many people stand the post per shift (1×, 2×, 3×…) on the left. Cells show who stands each band as one-line chips: red open markers where a line is short, blue offer markers where a shift offer is running (click one to open it), short tags for no-show / leave / sick, and a small amber or red warning dot when the person's grade is below the line's minimum or their PSIRA has lapsed — hover the chip for the full reason. Warnings inform, never block.
- Click a post name and the side rail becomes a post panel: every shift line (window, headcount, grade, armed, days, effective window) with an edit button, an Add cover row, Rename and Deactivate (history stays). Rows standing in for a live unit or desk have no Deactivate — the panel says to retire the unit or workstation in its own register instead.
- The post's Presence & no-show card (on the post's edit sheet): how guards book on and book off here (app, WhatsApp, roster link), what counts as present (assumed · attested · corroborated · proven), the fence and what happens outside it (record · tell the control room · refuse), and three actions — after grace with nobody booked on (leave it for a person · nag · mark no-show and open the gap · mark no-show and send offer round 1), after the end with nobody booked off (assume completed · nag · hold the hours for approval), booked off early (open the rest as a gap · nag · record only). Every field starts on the room's default from Config → Attendance rules; anything set on the post reads as post override.
- Add cover starts from a shift type, not a blank form — the same chips as on Posts. The panel also says why a post is missing a band — a post with no line running past 18:00 reads "day-only — it has no night band".
- Editing a shift line applies from a day onward by default: the current line is end-dated the day before and the new values start on the chosen day, so past weeks — and their pay math — keep what actually stood. Pick Everywhere to deliberately rewrite history, or End line from that day to retire cover without deleting it.
- Click a chip to open the person drawer: hours on post against the MCA meter (their ordinary week and its overtime cap — overlapping shifts counted once, with any double-booked hours called out separately), PSIRA number and expiry, firearm competency, phone, transport mode, site preferences, upcoming shifts, the person's Assignments (with edit buttons), and the written working-time agreements on file (overtime, averaging, compressed week — the agreements the legal hour caps flex on). Time off is recorded from here too, and the person's private Roster link is copied or revoked here — see Roster links. Open profile at the top of the drawer opens the person's full record.
- The drawer also shows the selected shift the chip was clicked on, with one-tap Requested absent and Sick for just that shift: the person's chip turns to a leave marker, the slot opens for filling, and the day-of sheet stops expecting them (no false no-show). Undo puts them back. Someone on leave, marked absent, no-show or cancelled never counts as covering a slot — the gap shows next to their chip.
- Longer / other leave… opens the absence sheet for anything bigger than one shift — see below.
- The drawer also opens the Double-booked panel when the selected shift clashes with another — see When one person is on two posts at once.
- Alt-click a chip to edit the underlying assignment.
- Click an open marker and the side rail becomes a Fill panel for that slot, with the three answers in escalating order: Fill ranks qualified, free candidates (same ranking as Attendance) and one click assigns a one-day fill (logged as a posting), then offers to tell that person; Create an offer instead raises a shift offer for the slot; or open the standing assignment form for the long-term answer. Why not the others? lists everyone the Fill left out with the one reason — the paperwork, the leave, the ban or the line's requirement.
- Switch By post / By person to pivot the same span around people. Person rows carry a weekly hours pill (amber past the person's ordinary week, red past their overtime ceiling — their job class's rule set, 48 h NBCPSS or 45 h BCEA, with a signed agreement moving the ceiling), a n× clash pill when they are on two posts at once, the same warning chips, and leave / sick markers on booked-off days. By-person opens on Rostered — people with an assignment or a shift in the span; switch to Everyone (the count of extra people is on the button) to list every rosterable person, spares and relievers included, each tagged spare. A row under the rostered people offers the same switch.
- A cell with nobody planned and no line asking for anyone shows a dashed —. Click it to open the crew sheet already on that post and day — the way to crew a unit or desk row straight from the board.
Placements — the standing assignments — combine a person + post + pattern + start date. Patterns are reusable per control room: a rotating cycle (for example 2 days, 2 nights, 2 off on 12-hour shifts, anchored to the placement's start date) or a fixed week (the "weekdays 07:00–17:00" guard). Existing patterns are listed, edited and retired under Config → Shift patterns.
When one person is on two posts at once
Nothing stops you putting the same guard on two posts over the same hours — a handover or a training shadow is a real reason to. What the board will not do is pretend it is two people.
The same person on the same post twice is a different thing and is treated differently — see Assigned twice to one post below.
A guard standing two posts at once is counted once. The post that keeps them is the one they were committed to first; the other reads as open, because that is what it is — a site with nobody on it. Every count follows from that: the day's n open figure, the coverage percentage, the Posts sheet and the Attendance console.
- Both chips turn red and carry a clash tag, on both posts, so it is visible from whichever row you happen to be reading. The post that is not counted is hatched.
- The gap it opens draws clash, not open — a different hole needing a different first move. Clicking it goes to the decision, not to Fill.
- A Clash filter pill in the toolbar, with a count, narrows the sheet to both ends of every double-booking in the span.
- Click either chip and the drawer shows a Double-booked panel: each post, which one is counted, which one reads open, and Release against each. Release frees the person from that post for that day only — the slot opens for filling and the day-of sheet stops expecting them. The standing assignment is untouched. It is not recorded as leave: the guard is working, just not there. If the two posts clash every cycle, end one of the standing assignments instead (Edit assignment… in the same drawer).
- The assignment sheet warns before the row is written, naming the other post and how many days in the loaded span would clash. Saving is still allowed — warnings inform, never block.
- Hours are wall-clock. Two 12-hour shifts on the same night are 12 hours on post, not 24. The MCA meter and the weekly hours pill count the time once and report the double-booked hours separately, so a clash never disguises itself as an overtime problem.
- The Attendance console names it on the open slot, because at 02:00 the fix may be a swap rather than a call to the bench — the body exists, it is just on the way somewhere else.
- Month end flags the disputed hours (see Month end).
Assigned twice to one post
Two standing assignments can put the same guard on the same post over the same hours. That has no innocent reading: the post reads as crewed for two, one body arrives, and the shortfall is invisible because both chips look like people.
The board counts them once, exactly as it does across two posts, so the post shows as short. The difference is the advice. The chip reads twice rather than clash, and the drawer says there is nothing to choose — it offers Open… on each assignment (removing one is the fix) rather than Release, which would clear a single day and leave every other day of the cycle wrong. If the post genuinely needs two people, that is a headcount on the shift line, not the same person entered twice.
Creating one is refused outright. The assignment sheet marks anyone who already stands that post on that pattern as already here and will not let you tick them; if something other than the app tries it — an import, a script — the database refuses the write and says who already stands what. Everything softer stays a warning: two different posts is a clash to resolve, never a block.
When an assignment outlives its post or its person
An assignment can end up pointing at nothing. Both cases used to be silent, and both left a post quietly uncovered:
- The post was retired. The post leaves the board, but the assignment stays. The roster no longer plans those shifts — before, it kept planning them, and the control room kept being told to expect a guard at a post that no longer existed, with check calls and no-show chases to match.
- The person has left. A Last day on their record is what records this. From the day after, the roster stops planning them and Fill stops offering them; shifts on or before that day stay on record exactly as they happened. In the assignment sheet they still appear, marked left with the date and not tickable — hiding them just makes it look like the search is broken. Clear the date if it was entered in error.
Either way the leftover assignment is named, not hidden: it is struck through in the person's Assignments list with the reason, and listed in the Overview warnings. End it, bring the post back, or reassign the post to somebody else.
Assigning several people at once
+ Add assignment (page header, a board cell, or Assign on the People tab) takes a whole crew in one sheet: tick everyone who will stand the post on the pattern — the list shows each person's grade and whether they already stand a post or are spare — then pick the post, the pattern and the start date. One save writes one placement per person.
On a rotating cycle, Stagger start dates round the cycle (on by default when more than one person is ticked) spreads their anchors evenly round the cycle — two people on a 6-day 2/2/2 cycle start three days apart — so the post is never left uncovered between them. Untick it and everybody starts together (a crew that works and rests as one). The sheet previews the first week on the board per person before anything is saved. Editing an existing placement is still one person at a time.
Recording an absence
Record absence (page header, the person drawer, or Longer / other leave… on a selected shift) covers everything from one shift to a month of annual leave in one sheet: the person, the kind (annual leave, sick, injury on duty, family responsibility, parental, study, training, unpaid, requested absent, suspension, AWOL, other), and either this shift only or a range of days. A manager's entry is the approval; Requested records an ask that somebody must still answer — nothing on the board moves until it is approved.
The sheet then shows what the absence actually costs and releases, counted in the unit that kind of leave is legally measured in:
- Annual leave is counted in consecutive calendar days (the MCA cycle entitlement runs in days — every day in the block counts, rostered or not), with the rostered shifts it frees up shown alongside.
- Sick leave is counted in shifts — the MCA measures the sick cycle as the days the person would normally have worked, which for a 12-hour officer is shifts, not calendar days.
Either way the sheet lists every rostered shift inside the range, with post and times, read from the person's real pattern. On a rotating 12-hour roster those numbers differ sharply: a fortnight off a 2-on-2-off cycle is ten shifts, not fourteen days. If a public holiday falls inside annual leave on a day the person would have worked, the sheet flags that an extra day is owed back.
Every decision is made once, on the server. Approving — from the sheet, a board chip, the People tab or the person's record — releases every rostered shift the absence covers, not only the one that was clicked: each becomes an open slot for filling, and the control room stops expecting that person (no false no-show). Shifts that already ran are left exactly as they happened. Cancelling an approved absence gives the released shifts back from today onward; the row itself stays on record as cancelled, because "was he ever marked sick that week?" is exactly the question a hearing asks. An absence over days the person wasn't rostered is still recorded, and they won't be offered work while it runs.
Attendance
Who actually stood. Three views, as a toggle at the top — Today (the day-of console), Timeline (who stood each unit and desk over a shift window) and Month end (the payroll reading):
Today
The day-of console — exception-based by design. Postings materialise automatically a day ahead on the control room's own date; whatever nobody flags completes as planned when the shift ends (automatic attendance), so you record the exceptions, not the routine.
- No book-on — a posting past its grace window goes red, with Mark posted, No-show and Fill. The grace is the cover line's; a posting with no line (a relief or an offer fill) uses the control room's default from Config → General.
- Book-off watch — every rail that books a guard on books him off: the roster link's Book me off, a WhatsApp off post / af diens reply or pin, the control room's Book off, a desk sign-out on CleverCommand. A shift that ended with nobody booked off is listed when its post's policy asks (nag, or hold the hours) with Book off and, where held, Release hours; a shift somebody left early shows the minutes short and the rest of it as a gap with Fill. A post whose policy says record only stays quiet.
- Left post — a shift running now whose guard's phone has reported from outside the fence for the room's number of pings in a row (Config → Fill & display, three by default; the check-in page pings on posts whose presence level is corroborated or proven). The lane shows since when, how far out, and Call with the phone on file; Back on post writes the clearing event, Record occurrence… and Fill are the usual rails. The next ping inside the fence clears it by itself. Empty, it says Nobody's phone has left its fence.
- Evidence on any lane folds out the shift's ledger: the last presence ping (inside, or n m outside), then every event newest first — book-ons and book-offs with their source, check calls, occurrences, a crew session on a unit (On the unit), a shift claimed from the open-shifts board, corrections.
- Record occurrence… on any shift — absent, late, desertion, sleeping, under the influence, failed check calls, uniform, left early (People → Config keeps the list) — writes an append-only event on the posting's ledger, which is what a hearing asks for.
- Unmatched book-ons — WhatsApp words that read like a book-on or book-off but matched no live shift: a number not on any profile, or a message outside any shift window. Put the number on the person's record under People and it matches from the next message.
- Fill ranks qualified replacements from the rosterable pool: hard-filtered on the line's credential requirements (paperwork on file that falls short; never paperwork that was simply not captured), its EE requirements, availability, site bans and leave; then scored on site familiarity, preference, weekly-hour headroom (no-overtime fills rank higher), rest gap and no-show history — every reason shown as a chip. Assigning a replacement logs a substitution: the original stays on record as a no-show and a new posting stands the post.
- Open cover lines (nobody assigned) appear with the same Fill flow, or hand over to an offer.
- Check calls due (the next 30 minutes by default — Config → Attendance rules): generated from each line's cadence, or the room's default cadence (for example hourly through the night), each logged OK or No answer with one click. Every outcome writes the evidence ledger — an answered check call corroborates the shift, an unanswered one is recorded and never raises the grade — and the room's number of consecutive unanswered checks (Config → Attendance rules; two by default) raise a red escalation card: the heartbeat creates a real Guard welfare event on the site (a manual, unverified event, so it lands on the event board for the operator without triggering sirens or red automation), plus a push to the control-room members: call the guard, then the site keyholder, then dispatch the nearest unit.
- Offers out — open shifts offered in rounds with deadlines: round 1 goes to the site's preferred and familiar people, round 2 to the qualified pool, round 3 to everyone qualified. Every round is pre-filtered the same way as Fill. Rounds last as long as Config → Attendance rules says (10 minutes for round 1, 45 after, three rounds by default); when a round's deadline lapses the offer widens automatically and the heartbeat sends the next round itself. A post whose after-grace action is mark no-show and send offer round 1 raises and sends its own offer when nobody books on. Send goes to CleverResponder and nowhere else: it reaches the people signed in to the responder app on their phone. Everybody else — no responder app, or signed out of it — is marked call them with their phone number, and the toast after a send says how many of each. There is no WhatsApp or SMS behind this button; the message that goes to a phone number is the roster-change notice further down, which is sent from the day sheet one person at a time. WhatsApp replies (Accept shift / Not available) are matched back automatically within a few minutes: an accept creates the posting and counts toward the slots, first accept wins, and the offer closes when the slots fill. Add a person the filter left out queues them on the current round — they arrive queued, not sent, so send the round to reach them, or press Accept if they already said yes on the phone.
- Armed postings carry a Firearm column: issue a company firearm to the posted officer (writes the FCA-required register row — who, which firearm, when out) and Return it at shift end. The picker starts on the firearm the officer is custodian of, and Equipment → Firearms shows who has each one out right now. One open issue per firearm; unreturned firearms show as NOT RETURNED on the posting register export.
- Requests — what the guards have asked for from their own links: Give away ("I can't make Saturday") or Swap, with the reason they gave. Nothing has moved: they are still on the shift until you answer. Approve and open it on a give-away cancels the shift and puts it on the open-shifts board, where any qualified guard can take it; on a swap, Find a swap… lists the shifts it could trade with — the ones that would leave somebody standing two shifts at once are shown last and cannot be picked — and choosing one exchanges the two people in a single step. Decline with a note, and the guard sees that on his link. Every decision is written on both shifts' ledgers.
- Next pickups — where the room runs transport, the day's pickup stops off the roster's routes. Marking a stop Missed flags those postings as at-risk — the earliest possible no-show warning, long before the site would notice. Night work legally requires transport to and from the workplace to be available, so night postings deserve a transport answer.
- Clock imports (folded away) — a biometric or turnstile clock's export, matched to people and shifts. Choose the file (CSV, TSV, TXT, XLS or XLSX — the reader finds the employee / ID number, the date and time, and an in/out column by their headings, and says which it picked) and name the device; the preview shows the first rows; Import n rows turns each clocking into a biometric book-on or book-off on the shift it falls in (in/out inferred from the half of the shift when the file has no column) and lists what it could not match — no reference, bad time, unknown person, no shift then, already recorded. People are matched on the Employee / clock number on their record (or ID number). Recent imports keeps every file with its counts. Clocks can push straight in — see Config → Clock push key.
- On post (folded away, the routine) lists who is booked on with their evidence grade, a Book off for a live shift (an attestation, like Mark posted), and Mark OT on an unrostered shift — the overtime flag the payroll CSV carries.
Raising an offer
An offer is raised from a hole, not from a list of its own: Fill → Create an offer instead on any open slot, or the popup-site sheet. The sheet shows Who it reaches live — the three round counts for the post, line, date and window as typed — so a line nobody qualifies for says so before the offer exists, and says why (an armed line with no firearm competency on file, a grade nobody free holds, or simply everyone posted, off or banned). Finish with Create only and send the round later, or Create & send first wave — the sheet's own word for round 1 — which sends the first populated round at once.
Each offer on the console names its post, day and window, how many of its slots are filled, starts in 2h 10m (red once the shift has already started), the round it is on and how many were sent, accepted and declined. Who (n) folds out the responses: every person targeted, the round they sit in, the phone number on file (tap to dial), and how they answered — the Accept / Decline buttons there are the phone-call fallback for a reply that never came by WhatsApp. Send / Resend is disabled while the current round is empty, so a round never sends to nobody, and Widen moves to the next one. Cancel offer asks first: the slot goes back to open, and people it has already been sent to are not told automatically. A closed offer keeps its state on the console — filled, lapsed or cancelled.
Attendance assurance
Automatic attendance closes a shift when its end time passes. That keeps the board clean, but it is an assumption — nobody reported a no-show, so the system assumed the guard was there. Absence of a no-show is not evidence of presence.
Every posting therefore carries an assurance grade next to it, derived from an append-only evidence ledger rather than set by hand:
| Grade | What it rests on |
|---|---|
| Proven | The site itself vouched for the guard — site hardware, or a biometric book-on. Independent of his own phone. |
| Corroborated | An independent sign of presence: a book-on inside the site fence, a scanned patrol checkpoint, or an answered check call. |
| Attested | A person vouched for him — typically the control room pressing Mark posted. Defensible, but hearsay. |
| Assumed | Nothing was captured. The shift ended and the system closed it. |
| Disputed | Someone has challenged the posting. It outranks every other grade until resolved. |
Assumed is drawn quietly, as a dashed outline rather than an alarm — on most books it is still the common case, and colouring it red would only train people to ignore it.
Two rules keep the grade honest: evidence is never edited or deleted (a correction is another event, so a dispute months later replays exactly what was known at the time), and nobody can promote a posting by hand — marking a guard on records an attestation; only real corroboration or site-hardware proof raises the grade above that.
Book-offs are graded like their book-on twins — a pin inside the fence at the end of the shift is corroboration, a WhatsApp off post is attested — and an operator's CleverCommand desk sign-in books them on and off their desk posting as corroboration.
Guards can also book themselves on and off, where the post allows it — from CleverResponder, from the roster link on their phone, or by WhatsApp reply. Which rails a post accepts, for booking on and for booking off, is set on the post's Presence & no-show card (the post's edit sheet, or Sites → (a site) → Guarding). A book-on inside the post's fence is corroboration; one from somewhere else is recorded with the distance — and the post can choose to tell the control room, or to refuse it outright. On WhatsApp the two can arrive separately: a guard who replies "on post" is recorded on his word alone, and a later location pin upgrades the same shift to corroboration. The person record carries the same idea as Shifts we can show.
This cycle · stood
Under the console, the Roster grid in actual mode for the same span and site: every stood cell carries its evidence glyph — ● shown (a fence, a check call or site hardware), ◐ attested, ○ assumed, ✗ no-show — with left early and held marks, days ahead dimmed, and a stood · shown total per person. It is how "shifts we can show" reads across a whole site rather than one person at a time.
Timeline
Who was actually on each unit and each desk over a 24-hour window, one lane per unit or desk, one bar per person — so a changeover reads as one bar ending where the next begins. This is the record that ties a person to a vehicle: the bar on a unit lane says who was crewed on it (and therefore who drove it) from when to when.
- The window. Pick the start date and the start time; the timeline always shows 24 hours from there. The start-time list leads with the room's own shift boundaries (the start times of its unit and desk cover lines — 06:00 and 18:00 at most rooms), then every other hour. Now resets to the last completed shift plus the one running, so the most recent changeover sits in the middle of the picture rather than on an edge. ‹ › step a day at a time. Times are the control room's own clock, 24-hour.
- The bars are the actual stints: a unit lane draws the crew rows CleverCommand's Units board,
the CleverResponder Start shift and the roster bridge wrote (
Unitsunder Response); a desk lane draws CleverCommand desk sign-ins, with one person's back-to-back sessions folded into a single bar the way the desk numbers fold them. A bar still running ends at the red now line with a dashed edge; an amber edge means the person is past the unit's expected shift end. Click a name to open the person's record. Hover for the exact times, how they came on (app, control room, roster, desk) and the driver flag. - Changeovers are the dots along the top edge of a lane, one wherever somebody came on. On a unit lane the dot says whether the vehicle checklist was done: solid green when the person coming on submitted a shift-start or take-over check within the half hour before to ninety minutes after, amber when that check reported a fault, a dashed grey ring when no check was found. A desk dot simply marks the desk changing hands. A square dot means the newcomer came on while the previous person was still on.
- Gaps — nobody on — draw hatched. A stretch shorter than five minutes between one person leaving and the next arriving is a handover, not a gap, and is not drawn.
- The plan is the thin blue strip along the bottom of a lane: the roster's posting on that unit's or desk's post. It is context, never the record — where a room crews from CleverCommand the strip and the bar may name different people, and the bar is what happened.
- The tiles above the lanes count the window: lanes with someone on now, changeovers, unit changeovers without a vehicle check, and the unmanned hours across the lanes that were in use (a unit nobody used or rostered in the window does not add 24 hours of "unmanned").
Vehicle checks are only visible to people who may manage the fleet or the control room; anybody else sees the changeover dots in neutral grey and the tile is hidden, rather than being told nobody checked.
Month end
The month's classification preview, straight off the posting ledger: per person — shifts, total hours, ordinary vs overtime (split at each person's ordinary week — 48 hours NBCPSS or 45 BCEA, their job class's rule set in force that week; overtime at the gazette's factor, the cap moved by a signed written agreement on file), training days (a paid training absence counts as working days off post, not leave), night shifts (at least half between 18:00–06:00), Sunday and public-holiday hours (a shift belongs to the day holding its greater portion — the MCA straddle rule), and armed shifts. The night and special allowance amounts shown are the NBCPSS gazette figures in force for the month being classified, in this control room's area — a March 2025 month reads that year's figure, not today's.
A Disputed column flags hours where one person's own postings overlap each other — they cannot have stood both posts, so either the roster was wrong or one of the two never happened. The header carries the month's total. Those hours are still counted in the totals above and in the export: the fix is to correct the roster, because quietly subtracting them would hide a site that had nobody on it. See When one person is on two posts at once.
Two exports:
- Payroll CSV — one row per person with the classified hours and allowance counts, the person's class and pay basis, the classes of the lines stood and the room's pay by choice (Config → General), ad-hoc overtime shifts, training hours and hours held — ready as wage inputs for SimplePay or Sage. Rates and rand amounts stay in payroll; this is the classification layer that ends pay disputes. Two extra columns carry the disputed hours and the posts they clash against, so payroll sees them before the run rather than after.
- Posting register CSV — one row per posting with the evidence grade, book-on and book-off (who and when), both classes, held hours and check-call counts: the attendance register and posting sheet PSIRA inspectors are entitled to see (keep 3 years).
Shifts whose hours a post's policy held (the shift ended with nobody booked off) are listed under the table with Release hours — once a supervisor confirms the shift was stood, it counts like any other.
The money. The same table carries rand amounts once the room has rates (Config → Rates & allowances): per person a Rate (own, class or legacy, with the basis — per shift, per hour, monthly), Base, OT premium, Allowances and Total, with a grand total row. A person without a rate anywhere is counted and shown as hours only; the strip under the heading says which hours basis the room runs — Roster hours (the planned hours) or Clock hours (from the first book-on to the book-off, late forgiven up to the threshold in Config → Hours & pay basis) — and a shift longer than the room's long-shift line is counted under the name. Everything is dated: a March month re-run in June prices at March's rates, factors and gazette figures. The Payroll CSV carries the same columns as plain decimals, and a TOTAL row.
Pay period. The card at the top of the tab closes the month in two steps: Approve period snapshots the totals (a reviewed reading — from here on a change to a shift in the period goes through a correction); Lock period hands them to payroll and never reopens. While approved, Changed since approval lists every person whose hours or money moved, with Approve again and Un-approve. A locked month shows the totals payroll received — Locked — these are the totals payroll received; live rows may differ — and the live table beneath is labelled as such. The Approved / Locked pill says who did it by name (your own reads as you), so payroll can see who signed the month off.
Corrections. Open periods are edited on the board and Attendance as usual; these rails are for approved and locked periods. Correct a shift… changes a shift's person, times, state, overtime, held hours, book-off or notes with a reason (required) and writes a correction event on the shift's ledger: in an approved period the change is applied; in a locked one it is carried — logged, not applied — and appears under Carried from earlier periods on the next month, where Settle in this export (ticked by default) takes it into that month's lock and its Adjustments from earlier periods block in the CSV. Add a missed shift… records a shift that was stood but never rostered, the same way.
Ad-hoc to bill. A shift the client should pay for over and above the contract — a popup, a relief nobody was rostered for, an extra body asked for on the night — is flagged Billable with a price, on the shift itself, by the person who knows it happened. The wage it cost is shown beside the price. Build the month's extras then gathers those shifts into one pending extra per site ("Ad-hoc guarding — 3 shifts, August 2026"); running it again changes nothing, and a shift already on an extra is left where it is. If two people build the same month at the same moment, the later build stops with nothing gathered — build the month again. Pending extras go onto the customer's next invoice by themselves when the monthly billing run comes round — nobody raises anything — and the invoice line says where it came from. The customer is the site's, when that customer belongs to your control room. On a site you share with another control room, each room builds and bills its own extras from its own shifts; if the site is on the other room's customer, your extra carries no customer and the monthly run does not bill it (nor list it as left out). Dismiss takes one off the table (a goodwill call) and puts its shifts back in the pool. Once an extra is on an invoice it is closed: the shift cannot be re-priced or un-flagged, so the invoice can always be explained from the roster.
Employment equity. The EEA2 workforce profile and EEA4 income differentials downloads give the figures those forms ask for by occupational level (each job class's EE level, People → Config), from the gender, EE category, foreign-national and disability fields on the person record and the annual remuneration a rate implies — with the counts of people not captured or with no rate on file stated rather than hidden. They are the figures, not the forms themselves.
Reports
One tab, six cards, one period picker — This month / Last month / Custom (or This cycle / Last cycle when the room pays on a day of the month). Every card has a tile strip, a table with a total row, and CSV. They read the same postings and the same money as Month end, so the two never disagree.
- Posted vs asked — per post: the hours every cover line asked for across the period, the hours stood, coverage and the missing hours.
- Wrong class — shifts stood by someone whose job class is not the line's, or whose PSIRA grade is below the line's minimum, with the reason on each row.
- Overtime — per person: hours over their ordinary week (per ISO week, at their rule set's figure), weeks over the ceiling, shifts flagged OT by the control room, and the OT premium.
- No-shows — by person or by post, with the rate toned at the room's thresholds (Config → Fill & display).
- Shifts shown — per person: rostered, stood, and the stood shifts by evidence grade — how much of the month the room can prove.
- Contract vs delivered — per site: what the guarding subscription bills a month (Site → Guarding, normalised from its cycle) against what the roster actually stood — the wage it cost, the shifts, the shifts flagged billable, and your control room's own ad-hoc pending and invoiced on top (on a site you share, the other room's extras are not in it) — with the difference between contract and delivered. Contract is the subscription amount, not the invoices raised. When the site carries more than one active subscription, the contract is the largest by monthly value, and the cycle beside it is that subscription's. Without billing rights the money columns read —.
Telling people their roster changed
Every ad-hoc fill — on the Roster's Fill panel or the Attendance console — is followed by a Tell them their roster changed prompt. It is a prompt, not an automatic send: the roster change has already saved by the time it appears, and closing it with Don't send changes nothing on the sheet.
The prompt shows exactly who is about to be messaged and the phone number on file for each, plus an optional extra line (up to 90 characters) for instructions like "report to the main gate, not the boom". When a relief fill displaced somebody, both people are listed — the one taking the post and the one whose shift is now a no-show on the record.
Each person is reached in this order: CleverResponder push if they are signed in to the responder app — most guards never have been, so this rung is the exception rather than the rule; SMS if push didn't land and there is a phone number on their staff profile; otherwise call them — they still appear in the result list, marked so you know somebody has to phone. After sending, the same list comes back showing which rung actually reached each person, and why anyone who was missed was missed. The message names the next shift (day, times and post) and carries the person's own roster link.
Roster messages never go to the CleverAlert app, even for somebody who has both on the same handset: a shift belongs in the app the officer works it in.
Reminding people before the shift
Off by default, in Config → Attendance rules:
- Remind the guard before the shift (minutes) — blank means nobody is reminded. Set it to how long before the start the message should go: an hour is enough to get moving, the evening before is enough to arrange a swap.
- If the app didn't reach them — leave it on the app only, or let it fall through to WhatsApp or an SMS. The paid rung is off by default because a shift change at a big room is one message per guard.
A reminder goes out once per shift, to anyone who has not already booked on, and never after the shift has started — a late reminder is a nag, and the heartbeat already owns nags. It reaches CleverResponder first; on a post that takes portal book-ons the message carries a tap-through that opens the book-on page, and everyone else gets their own roster link.
Cancelled shifts, no-shows and anybody who has already booked on are skipped, so turning this on does not message people about work they are already doing.
What the guard sees in CleverResponder
My shifts, from the off-shift screen or by tapping any roster notification, shows what is still ahead of them: each shift with its day, times and post, any open shifts they qualify for, and their own paperwork if something is about to expire. It reads the same roster the portal link serves, so the two can never disagree.
It is a place to look, not to act: booking on and claiming a shift stay on the portal link and the WhatsApp reply, which are the rails that also work for the guards with no app at all.
This is for ad-hoc changes only and is capped at 12 people per send. There is deliberately no "notify everybody" button for a newly published roster — hand out roster links for that instead.
Roster links (the team portal)
Every rosterable person can have a private web link that opens their own roster with no login and no app. Open the person drawer on the Roster tab, and under Roster link:
- Copy link creates the link (or returns the existing one) and copies it to your clipboard. The same link is what the change notice above sends, so a person only ever has one — it keeps working and doesn't expire per message. Its expiry rolls forward each time it is used or re-copied.
- Revoke kills it immediately. Do this when somebody leaves. Nothing revokes it automatically, and a live link keeps naming the client sites they used to stand.
What the person sees when they open it — the Roster tab, and a Certificates tab when they are on a compliance track.
The Roster tab. A calendar strip covering this week and the weeks ahead (three in all by default — Config → Fill & display → portal weeks) — every day marked Day, Night or Off, with today outlined. This is the default view on purpose: a list of shifts alone can't tell you whether a missing Wednesday is a day off or an oversight. The strip always runs Monday in the first column, Sunday in the last, so it reads the same way every day of the year — which is why the days already gone in the current week are still shown, dimmed rather than dropped. Under it, each upcoming working day in full: times, the post (site · post name), whether the shift was Added ad-hoc, and its state (rostered, confirmed, on post, completed, not stood). At the top, his own paperwork inside its warn window — PSIRA registration expires on 15 Sep (23 days) — read from the People-level compliance record; and the control-room phone number to call if something looks wrong. The same link's check-in page books him on and, once on, off (Book me off); an early book-off tells the control room the rest of the shift is open, and a post that only accepts book-ons from inside its fence refuses one from further away and says so.
Open shifts you can take. Above the calendar, the link lists the room's open shift offers the person may claim — the same gate the offer rounds apply (rosterable, free at that time, not on leave, not banned at that site, holding the line's grade and paperwork), with You were asked on the ones a round already reached him. Take this shift puts the posting on his roster at once (first claim wins; the offer closes when its slots fill) and tells him plainly when it cannot — You already have a shift at that time, Someone else took it first, This post needs a grade or paperwork the office does not have on record for you. A claimed shift is marked Claimed on the roster link on Attendance.
Presence while the shift runs. On a post whose presence level is corroborated or proven (the post's own card, or the room's default), the check-in page asks the guard to keep it open: it sends a position every five minutes and the control room measures it against the fence — the page never learns where the site is. The room's number of pings in a row outside the fence (Config → Fill & display, three by default) raises Left post on Attendance → Today and a push to the control room; the next ping inside clears it. The page tells the guard what its last check said, and when the control room has been told.
"I can't make this one." On a shift that has not started and he has not booked on for, the link offers Can't make this one? — Give it away or Swap it, with a reason the control room sees. It is an ask, not a change: the shift keeps its place on his roster and reads "Waiting for the control room" until somebody answers, and he can Withdraw it. An approved give-away goes to the open-shifts board; an approved swap exchanges him with the person the control room picked; a decline says so on the link. Everything happens on Attendance → Requests.
The supervisor's half of the same link. Where a person's job class is a supervising one (People → Config → Job classes — Site supervisor, or any class a room adds whose key says supervisor), their link also carries Your site today: everybody rostered at the site they are standing, with whether each has booked on, booked off, or not turned up. One action — He is on post — records the supervisor's word that somebody is there. It is the weakest grade of evidence there is (below a check call, above nothing), it works only today, only at the site they are on, never for their own shift and never twice. They cannot book anybody off, mark a no-show, or see pay. A person who does not supervise sees none of it.
What it deliberately does not show: pay or hours-worked figures, anybody else's name or shifts, site addresses, PSIRA or certificate numbers, ID numbers, or the certificate documents you hold. The link is a shared secret carried over SMS, so it is scoped to what the person needs to turn up in the right place at the right time, keep their own paperwork current, and nothing further.
How long a link lives is the room's (Config → Fill & display → roster link days, 90 by default); every reissue rolls the expiry forward.
The Certificates tab
The second tab appears only when the person is on a compliance track — a control room that doesn't use tracks never sees it, and neither does an office worker with nothing on their record. A red dot on the tab means something of theirs has lapsed or is inside its warning window.
Each item is one card: what it is, a status word (Out of date, Expiring, In date, Not on file), and the date in a sentence — "Expires 15 September 2026 — 24 days left." The certificate number is never shown, only the item and its dates.
Under each card is Send it in: the issue date, the expiry, a photo of the certificate and an optional note. The expiry fills itself in from the item's validity period, the same figure your own screen suggests. They can send a photo from their phone camera, and once sent only your control room can open it — the link cannot read it back.
Nothing a person sends changes their compliance record. It queues for somebody here to accept — see Sent in by staff. Until you accept it the matrix is unchanged and the item stays amber or red. That is deliberate: the link is a bearer secret that gets forwarded, and a forwarded link must never be able to certify anybody as compliant.
PSIRA has no Send button. It reads "Your control room checks this against the PSIRA register itself, so there's nothing for you to send" — because the register is the truth there, and a photographed certificate must not be able to move a verified registration. The same applies to any item you have already verified. Everything else — first aid, medicals, inductions, licences — is theirs to send.
Sending a second time replaces their pending submission rather than queueing two, so a better photo simply supersedes the blurry one. If you decline something, the reason you type is shown back to them on this tab, so they know to send another rather than assuming it went through.
Config
The boring core, as data — the last tab, the way Billing keeps its reference data in a last Config tab. Everything ships seeded, so a new control room rosters a month without opening it. Sections on the left:
- General — whether the board pages by weeks or by a pay cycle starting on a day of the month (the board's Cycle span follows it), which weekday the pay week starts on (the ordinary week is counted from here), the NBCPSS area (Areas 1 & 2 or Area 3 — which minimum-wage table the wage floor and allowances read), the late book-on grace default, the early book-on window, and how officers needed is quoted (the industry 4+2 convention or no-overtime ÷ the ordinary week).
- Attendance rules — the room's defaults for presence and no-show: what counts as present, the after-grace, after-end and early book-off actions, the fence and what happens outside it, welfare after n missed check calls, the check-call cadence a new line starts on, offer round timing and sizes, which posting states Month end counts as worked, the span the board opens on, how far a person's record looks back, how far ahead Today lists check calls, and what a popup site starts with. Every post can override the presence and no-show parts on its own card. Job classes, absence kinds and occurrence codes live on People → Config; the law itself — the 48 h and 45 h weeks, the overtime caps and factors, the night window — is a dated table the roster reads by the date of the shift, never a number in the app.
- Hours & pay basis — which hours Month end counts: Roster hours (the planned hours) or Clock hours (from the first book-on to the book-off), the late deducted after threshold that only means something on the clock basis (blank = off), which class prices a shift when a person has no rate of their own (the person's job class, or the cover line's), and where the long-shift warning starts (12 by law; editable to 18 — the warning stays).
- Rates & allowances — the money, dated. Per job class: the rate in force today (a dated row, or the class's legacy single rate), Add rate from a date, a history with delete — a change is a new row from its date; older exports keep their rate. Per person: the same, for a rate that beats the class's. Overrides: the seven factors and allowances (overtime, Sunday, Sunday ordinarily worked, public holiday, standby, night allowance, special allowance) with the agreement's or the gazette's figure shown beside the room's — absent = the agreement and the gazette speak. Site wage areas: a site in Area 3 while the room sits in Areas 1 & 2 prices at its own table.
- Fill & display — the last numbers that used to live in code: the Fill weights (preferred at the site, familiar with the post, overtime soft and hard, short rest, per no-show, PSIRA not captured or lapsed, EE not captured, undocumented for the line — with Reset to seed); the coverage tones (where coverage and no-show tiles turn amber and red, and check calls green); pings outside the fence before "left post"; the WhatsApp words a guard's reply is read by (book-on words, book-off words — whole words, any case); how long a roster link lives and how many weeks it shows; transport defaults; and the locale for dates and money on every roster surface.
- Clock push key — for a clock that pushes its clockings itself: Generate new key shows the key once (only its hash is kept; the old key stops the moment a new one is made) with the endpoint, the header and a body example. The key is the room's and can only add evidence to this room's shifts.
- Shift types — this company's shapes: a letter for the grid, a name, a window, its hours, whether it is paid, and whether it runs Monday to Friday by default. Seeded with Day 06–18, Night 18–06, Working day 07–17 Mo–Fr, Morning 06–14 and Afternoon 14–22, plus Off and an inactive Standby a room can switch on. A cover line starts from one of these; nowhere else says how long a shift is. Retiring a type takes it out of the pickers — lines that used it keep their window.
- Shift patterns — the library, moved here from the People tab: every pattern with its rhythm spelt out (2 day · 2 night · 2 off (6-day cycle) · 12h shifts), how many people stand it, Edit, Retire (disabled while anyone stands it — a retired pattern's shifts leave the plan; move them first) and Restore. + New pattern lives here and in the crew sheet.
- Absence kinds — what an absence can be and the unit each is measured in, shown read-only here because the grid draws their letters; everyone takes leave, so they are managed on People → Config from P1.
- Import — the day a company arrives with a spreadsheet. Two importers, People and Sites
& cover lines, each reading CSV, TSV, XLS or XLSX and naming which column it took for what
(Employee No, ID No, Cell, Grade, Date Engaged; Site, Post, No of Guards, On, Off, Days).
- Check the file first. It makes exactly the writes the import would and then undoes them, so every rule the database holds has had its say and what it shows is what will happen — created, updated (or matched), skipped, and every row it could not take in full, with the reason and what the file said. Then Import. A row the database refuses is skipped and listed (the database refused this row, with its message); the rest of the file is saved.
- People are matched on employee number, then ID number, then an exact name — but never a
same-named person whose employee or ID number is a different one; that is somebody else, so
the row adds a new person and says so. Re-running a corrected file updates the same people and
never makes a second copy of anybody — which is what actually happens on a migration day.
A value the import cannot read still imports the person, leaves that field as it was, and is
listed:
- Gender reads M or F, Male or Female, Man or Woman; EE category (a Race or Ethnicity column) reads African or Black, Coloured or Colored, Indian or Asian, White, and Foreign national (also foreign_national, Foreigner, Non-SA). Employment reads Permanent (Perm, P, Permanent guard) or Casual (Temp, Temporary, C, Casual guard). Case, spaces and punctuation don't matter, and a blank or a lone "-" is just blank.
- Start date is read day first (01/02/2026 is 1 February; 8/23/2026, which cannot be, is 23 August). A date the reader cannot make out is listed and never guessed at. A start date later than the Last day of the person it matched is not written — clear or move their Last day first if they have come back.
- An ID number verified with PSIRA is locked: a different number in the file is listed and not written. An ID number already on someone else in the room is saved and listed, as the person record warns about it too. An ID number that is not 13 digits is kept (a passport is not an ID).
- Sites & cover lines take one row per cover line, so a site with a day and a night line is two rows. A site is matched only among this room's own sites (an approved link) — a site of the same name in another company is never touched — and one the room does not have yet is created as this room's, linked as primary. A site whose link is still waiting for approval is skipped and listed. A post that does not exist yet is made. Days reads ranges (Mon-Fri, Monday to Friday, Fri-Mon), lists (Mon, Wed & Fri), daily / 7 days / 24/7, weekdays, weekends, and PH or public holiday — a line covers public holidays only when its days say so; blank or daily is Monday to Sunday. A cover line the post already has (same times and days) is not added again — the row is listed with both headcounts when they differ, so re-running the file never doubles the cover. Check calls under 15 minutes apart, an officer count or armed value it cannot read, and a customer that is not on the room's list are listed; the line is still made.
- Recent imports keeps every run, checks included, with its problems.
- Pointers to what lives elsewhere, so nobody hunts for it: Job classes, Leave rules and Occurrence codes (People → Config), Certificates (Settings → Reminders → What can expire), Period locking (Attendance → Month end).