Crews
A Crew is the gang that works together on a project — a saved list of people.
That is the whole of it. A crew grants no authority, bills nothing, and owns no docket. It exists so the office can name the group that turns up together and act on it in one go.
A crew holds anyone on the project. The two subcontractors, the labour-hire chippie, the plant operator — they go on the same crew because that is who works together, not because they share a company. There is no supplier restriction, no agreement-type restriction, and no requirement that a member be verified.
Membership is keyed on the person, not on their engagement with a supplier. A worker who holds no supplier engagement on the project at all can still be a crew member.
What a crew does NOT decide
| Question | Answered by |
|---|---|
| What is this person paid? | Their own assignment’s contract and rate line |
| Which docket do their hours land on? | Their own supplier’s agreement type, resolved at their sign-on |
| Can they manage a docket? | Their own permissions — not their presence on a list |
Putting someone on a crew changes none of those. It is a grouping, not a billing construct.
Who uses it
| Persona | What they do |
|---|---|
| HC Project Admin | Creates crews and puts anyone working on the project on them, whoever they are engaged through. |
| Site Supervisor | References a crew when assigning work. |
Where to manage crews
Crews are managed in the Field Users area of the project configuration:
/admin/config?tab=crewsOpen the project, navigate to Configuration → Field Users, then select the Crews tab. From here you can create a new crew, view existing crews, and add or remove members.
The Crew Lead is not set here. Since 2026-08-12 it is a property of the person, ticked on the worker’s own record when you verify them — see Crew Lead below. The Crews tab reports who the leads are; it does not choose them.
Managing crews requires the fieldusers.manage permission — the same permission that governs the rest of the Field Users area.
What a crew is made of
| Field | Notes |
|---|---|
| Name | Free text, unique within the project, case-insensitively. A name collision returns a 409 on both create and rename. |
| Members | People on this project, under any supplier and any agreement type — or under none at all. |
| Supplier | Not entered, and not a property of the crew. The crews table lists every supplier the crew’s members are engaged with, which may be several and may be of different kinds. |
| Crew Lead | Not a property of the crew. Any member the office has ticked as a crew lead on this project shows a Lead badge here, and a crew may have several — or none. |
Member eligibility
One rule: the worker is on this crew’s project.
That is the only fence a crew has, and it is there because per-project isolation is the basis of the whole app. Everything else that used to gate membership is gone:
| Rule that used to apply | Status |
|---|---|
| Must be engaged with the same supplier as the crew | Removed (2026-08-04). A crew spans suppliers. |
| Must be engaged as a subcontractor | Removed (2026-08-12). A crew is the gang, not one company’s staff. |
| Must be verified | Removed (2026-08-12). Verification never affected pricing — an unverified worker has always been priced normally. |
| Must have a supplier engagement at all | Removed (2026-08-12). Membership keys on the person, so a worker with no assignment row can be on a crew. |
These are removed, not merely relaxed: the refusal codes that expressed them no longer exist anywhere in the product.
Who the “Add worker” picker offers (2026-08-14)
Deleting the rules above was not enough on its own. Until 2026-08-14 the picker was built from supplier engagements, so a field user with no assignment row had nothing to be listed by and never appeared — whatever the membership rules said. The office could not reach the people the rules had just made eligible.
The picker now offers two kinds of candidate, and labels each:
| Candidate | Shown as |
|---|---|
| Holds a live supplier engagement on this project | Name — classification, grouped under supplier + agreement type |
| Holds one that the office has not verified | …and Unverified |
| No engagement on this project yet | …and Not yet assigned |
An unassigned candidate is grouped under the same supplier heading as everybody else, because their supplier and agreement type are read from the live link that supplier holds to this project — the same link their docket would actually be raised under. They sit beside the people they will be billed alongside, not in a separate list.
“Not yet assigned” and “Unverified” are never shown together. A candidate with no engagement has nothing that could have been verified, and saying both would send you to a verification screen that cannot help. The stronger fact wins.
Who is still not offered
| Not offered | Why |
|---|---|
| Somebody with no supplier organisation at all | They are not billable through a supplier engagement, so the crew fan-out can only skip them (not_a_supplier_worker). |
| Somebody whose supplier holds no live link to this project | There is no engagement policy to bill against, so the fan-out answers no_active_engagement. |
| A project member who is not a field worker | Office staff and engineers are on the project, but they are not the gang. |
| Anybody on another project | Per-project isolation. |
The first two are the important ones, and they are a deliberate line rather than an oversight: the picker aims never to know something billing does not.
It is an aim, not yet a guarantee, and two shapes still fall through it. Both are pre-existing and neither is introduced by the two-arm picker; they are written down here because this is the page that states the rule.
| Still offered, but the fan-out will refuse | What you see |
|---|---|
| Somebody holding two distinct supplier engagements on this project | They appear twice, once under each supplier heading. The fan-out will not guess whose invoice their day lands on and skips them with multiple_supplier_engagements. Resolve which applies. |
| Somebody whose supplier’s engagement is attendance-only | They are offered like anyone else, and the fan-out skips them with sign_on_only — by contract that engagement never raises a billing docket. |
The first cannot simply be filtered: two engagements are two real facts about that person, and the office needs to see both in order to fix it. The second is a roster question rather than a billing one — an attendance-only worker genuinely belongs on the gang, they just never get a docket.
What happens to an unassigned member’s paperwork
Exactly what happens when they sign on themselves — the same code decides both.
They get their own docket (or a line on their supplier’s master docket, under a subcontractor engagement) with an empty pricing grid: no classification, no rate line, no pricing lines at all. Nothing is guessed and nothing is billed at zero by accident.
How the grid gets filled. The office can price it by hand. It also fills itself once that worker is assigned a rate — but not at the instant of assigning: the repair happens the next time that shift’s paperwork is touched, which in practice is the supervisor pressing Create crew dockets (or Try again) again, or the worker’s own next sign-on. Assigning a rate on the Field Users tab does not, on its own, reach back into a docket the fan-out already raised. Until then the row keeps reporting that pricing is outstanding, so nothing goes quiet over an unpriced shift.
The crew fan-out reports this per member, so a supervisor is never told the job is finished when it is not: the row still reads “Docket created” — the man can work the shift — with “No pricing yet — the office adds the lines” underneath. It says so on every run while the pricing is still missing, not only the first.
One member is deliberately NOT flagged, and it is not an oversight. A subcontractor billed on a crew-hour, flat-shift or material rate line is fully configured: that line prices once per crew allocation, never per head, so he sits on the master with no per-worker rate on purpose and the crew lead groups him into the allocation. He is not pricing-pending, and saying he was would send the office to add per-worker lines that double-bill against that allocation.
A worker can be on several crews
A leading hand runs two gangs; a person appears in both a day crew and a night crew. Adding somebody to a second crew leaves their first membership exactly as it was, and leaves that crew’s lead alone.
This reverses the behaviour that shipped on 2026-08-09, where adding a worker to a second crew silently removed them from the first and could strip that crew of its lead. Nothing is displaced by an add any more, so nothing is reported about it — the toast is simply “Member added”.
Which crew decides their paperwork? None of them. Since 2026-08-13, subcontractor master dockets key on the supplier, not the crew, so a worker on two gangs needs no tiebreak: their hours land on the master of the supplier that engages them, whichever crews they happen to be on. The rule that used to live here — “the crew they were most recently added to” — was a way of choosing between two answers, and there is only one now.
One person, one crew, once
The single refusal that survives:
| Refusal | When |
|---|---|
already-a-member | This person is already on this crew, whichever supplier engagement was used to name them. |
This one guards money rather than tidiness. A worker holding two engagements on one project could otherwise be added twice, and the office crew-docket path maps members one-to-one onto docket workers — so the same human would appear on the docket twice and be billed twice. The database enforces it as well as the API.
The project check is enforced in the service before insert, so the API returns a
400 naming the cause when it fails.
Raising a subcontractor docket from a crew
A subcontractor master docket belongs to one supplier, and only a subcontractor engagement produces one. So when a crew is used to start a master docket:
- The crew is a seed, not the docket’s identity. The master is identified by supplier, project, date and shift, so two of one supplier’s crews working the same shift fill in the same docket rather than raising two.
- The docket is pre-filled with the crew’s subcontractor members. The labour-hire chippie and the plant operator are deliberately left off: their hours belong on their own dockets, which is where their own sign-on puts them. You can still add anyone explicitly — this is a sensible default, not a fence.
- Only those subcontractor members lend a classification to a worker added without one. A labour-hire agency’s rate can never be stamped on a subcontractor’s docket, however many of its people are on the crew.
- Every crew that has members can be picked. A crew with no subcontractor members among them is still offered, and says so by name when you pick it rather than vanishing from the list for a reason nobody can see.
Pricing on a multi-supplier crew
Two different rules apply, and conflating them is the usual mistake:
- Individual labour — every worker prices from their own billing anchor, on the contract that owns it. One supplier is often engaged under several agreements at once, so a single master legitimately spans more than one contract.
- Grouped (crew-rate) allocation — same-supplier only. A crew-rate group
takes its supplier from the contract that owns its rate line, and only workers
engaged with that supplier may be grouped onto it. Adding anyone else returns a
named
400explaining why.
Once a billing anchor is stamped on a docket worker it is permanent for that docket: moving the worker to another supplier afterwards never re-rates or zeroes past work. Changing the anchor is a new decision, and the choices offered — and accepted — are the supplier engagements the worker holds today.
Crew Lead
The lead is a property of the PERSON, not of the crew and not of the docket. (CTO ruling, 2026-08-12.)
It is an authority grant, not a label. A person flagged as crew lead on the project can, on any subcontractor master docket they appear on, edit the docket’s worker rows — change and remove them — manage worker groups, edit scheduled-item lines, and submit the docket. Office users holding docket pricing rights can always do the same, so the lead never blocks anybody; they are simply admitted alongside.
A master raised in the field carries no stamp, and does not need one: since the lead is a live flag on the person, a flagged worker who appears on that docket can manage it, and nobody else in the field can. Being first to sign on is not an authority grant.
Adding a member from the phone was retired on 2026-08-13. The lead’s other powers are unchanged, including removing someone. A worker joins a master by signing on; the office can add anyone from the web docket editor.
Two rules follow, and the app refuses by name when either is broken:
Where it is set
On the worker, at verification. Open Configuration → Field Users, click the worker, and tick Crew lead in the dialog’s footer — the same footer that carries Verify. It is one switch per person per project, and it applies the moment you tick it. You do not have to verify or re-verify anyone to change it: ticking and un-ticking are independent of verification, in both directions. There is no “Set lead” control on the Crews tab any more. There cannot be one: the same person leads on every subcontractor master they appear on for this project, so choosing it crew-by-crew would promise something the system does not do.
What it grants
A flagged person is a full-crew editor on any subcontractor master docket they appear on: they can add, change and remove the docket’s worker rows, manage worker groups, edit scheduled-item lines, and submit the docket.
Three consequences worth stating plainly, because each is deliberate:
- It applies to dockets raised BEFORE you ticked it. The permission is checked live, against the person, every time. It is not stamped onto a docket when the docket is created, so there is no “too late”.
- It spans suppliers. A crew can hold workers from several subcontractors, and a flagged person leads the crew — so they can run a master that carries another supplier’s workers. That is the accepted trade, made deliberately: the lead leads the gang, and the gang is not one company’s.
- A crew can have more than one lead. Tick two people and both can run the same master. Nothing has to be un-ticked first.
- Only a lead sees the whole crew (owner ruling, 2026-10-23). Everyone else on a master sees their own line and the crew line (group) they are on, with that group’s members. Other workers’ lines and sign-ons, other crew lines, and the master’s scheduled items and equipment are hidden from them, on the phone and from the API alike. Office users see everything. If nobody is ticked, no one in the field sees the whole crew, so tick the lead when you verify them.
Two things it does not grant:
- No money. The lead tier never confers rate or amount visibility. A field crew lead sees hours, names and quantities, and no dollars — exactly as before.
- No reach beyond their own dockets. A flagged person gets nothing on a master they are not on.
Office users holding docket pricing rights can always manage any crew docket, so a lead never blocks anybody — they are admitted alongside.
What it does not do any more
Two behaviours were retired with this change:
-
The docket’s
crew_lead_user_idstamp no longer decides anything. It is still recorded, as a historical note of who the office considered the lead when the docket was raised, and it is still worth reading as history. It is no longer read to decide what anyone may do — that is precisely the bug this replaced, where swapping a lead mid-shift left the outgoing person in charge and locked the incoming one out. -
Removing a crew member is never blocked “because they are the lead”. Being on a crew and being a lead are separate facts; take anyone off a crew freely, and their tick is unaffected.
One consequence worth knowing before you do it, on the small number of crews carrying a legacy nomination made before this change: the crew’s header supplier is derived from its members, and a legacy nomination is the first tiebreak. Take that particular member off the crew and the tiebreak falls through to the supplier most of the crew is engaged with, so the next crew docket raised can be hosted by a different supplier organisation — which is who sees it in their supplier portal. There is no control that restores the old nomination, because setting one was retired with this change. It is a header change only: every worker still prices from their own supplier’s own contract, and dockets already raised keep the supplier they were stamped with.
Create crew docket — starting the whole gang’s paperwork
From a diary’s Labour & Plant section, Create crew docket starts the day’s paperwork for everyone on a crew at once. Pick the crew, press the button, and each member is routed exactly as they would be if they had signed on to a prestart themselves:
- Labourers get their own individual docket for the shift.
- Plant operators get their own docket with their machine on it.
- Subcontractors land on their supplier’s master docket for that day and shift. Two people from the same supplier share one master; two people from different suppliers produce two, because a master is keyed on the supplier and a crew never merges suppliers onto one invoice.
Shift times come from the project’s shift configuration for the diary’s shift — not a fixed 7:00–3:30 day. (The in-diary ”+ Add Docket” picker used to send that hardcoded window on every project; it now sends nothing and the server fills it from the project’s own configuration.)
Running it twice is safe
The action is idempotent. Running it again, or running it after people have already signed on, creates nothing the second time — everyone reports already had one. When a member’s docket already exists, the diary’s supervisor is recorded on it as an associated supervisor, so the shift shows up in their diary too.
It never fails the whole crew for one person
Every member comes back with an outcome, and anyone the fan-out could not route is named with a reason rather than quietly left out:
| Reason | What it means |
|---|---|
| Not engaged through a supplier | The person has no supplier organisation, so no supplier docket is raised for them. |
| No live engagement | No active supplier↔project engagement. Restore or add their assignment and re-run. |
| Two supplier engagements | Refused deliberately — see below. |
| Attendance-only engagement | The contract is sign-on-only, so no docket is raised by policy. |
| Billing lookup failed | Transient. Nothing changed for that person; run it again. |
| No user record | There is no account for this member. |
| Removed by the office | The office took this person off the supplier’s docket for this shift. Nothing is added back — see the note below. |
A member whose docket landed with no pricing is reported as started, not as skipped. Since 2026-08-14 a member with no supplier assignment on this project gets their paperwork like everybody else — an empty grid the office prices — so their row reads Docket created (or On supplier docket) with “No pricing yet — the office adds the lines” underneath. It is not a refusal: the man can work the shift, and the counts a supervisor reads — “17 started” — still mean what they always did.
The note stays put. Run the fan-out again, press Try again, or let a second supervisor run the same crew, and a member who is still unpriced is still reported that way — his row reads Already had one and the note is still underneath it. The one warning about an unpriced man does not disappear because somebody looked twice.
A worker the office removed is reported as removed, not as “already had one.” Taking somebody off a supplier’s master docket is a deliberate decision, and a later fan-out honours it rather than quietly putting them back. Because nothing is added for them, the honest answer is that they have no paperwork for that shift — so they are neither billed nor paid unless the office puts them back on the docket. Reporting that as already had one would have said the opposite of the truth about somebody’s pay.
A crew only fans out onto its own project’s diary. Crews belong to a project, and raising a crew’s paperwork on another project’s diary is refused outright — a supervisor with access to one job cannot start dockets from another job’s gang.
A worker holding more than one supplier engagement on the project is refused by name, and the rest of the crew still gets their paperwork. This is on purpose: with two live engagements there is no single answer to whose invoice that person’s day belongs on, and the system will not pick one. Resolve which engagement applies and run it again.
On the phone
The same action is on the mobile app, so a supervisor standing on site does not have to find a laptop to start his gang’s day. Open the diary, and the Dockets section carries + Crew docket; pick the crew and press Create.
It is the same endpoint and therefore the same behaviour throughout — the same routing, the same idempotency, the same refusals. The result is reported the same way too: every member is listed by name, with what happened to each, and anybody the fan-out could not route is named with the reason above rather than left out of the list. A run that could start nobody still shows you all of them and says why.
Two mobile-only notes:
- The Dockets section now appears on a diary that has no dockets yet, which it previously did not. That is exactly the diary you open to start the day, so the action has to be reachable there.
- Try again is offered only when a skip was worth retrying — a billing lookup that failed, or an engagement that is not live yet. The other reasons will not change on a second press, so no retry is offered for them.
Scope boundary — what ships later
| Capability | Slice |
|---|---|
| Crew Lead labour-approval powers | Later |
| Mobile crew CRUD | Follow-on |
| Supplier portal surface for crews | Follow-on |
| Crew-lead tick on the mobile app | Follow-on |
Related
- Overview — module architecture and persona breakdown.
- Schedule of Rates — the contract-level authoring step for subcontractor pricing.
- Spec:
docs/superpowers/specs/(subcontractor-crews-dockets branch).