Coverage starts with one assignment that needs a replacement; a swap starts with two valid assignments, so forcing both through the same state path creates the wrong intermediate meaning.

Taylor has a Friday cleaning shift at 6:00 PM.
Jordan has a Saturday shift.
They want to trade.
I already have a coverage path that can replace the cleaner on one assigned shift, so there is an obvious implementation shortcut:
Run the coverage flow for Taylor’s shift.
Then run it again for Jordan’s.
I would not do that.
The two operations may both end with different names attached to shift records, but they start from different conditions. A coverage flow starts because one assigned shift has lost its worker. A swap starts while two assignments are still valid and the workers want to exchange them.
Coverage starts with one assignment becoming unresolved
The coverage path has a very specific trigger.
One cleaner is already assigned to one shift and can no longer work it. In CleanConfirm’s current model, that can begin with a Cannot make it response. The shift then needs cover review, an Owner or Admin reviews the Cover Request, and only an approved request changes the assigned cleaner. The replacement still has to confirm the new assignment afterward.
That gives the shift a sequence that makes sense for a missing-worker problem:
Taylor assigned
↓
Cannot make it
↓
Pending Cover
↓
Cover approved
↓
Jordan assigned
↓
Jordan confirms
One shift is carrying the unresolved staffing problem.
The state names describe that problem reasonably well because there really is a shift that now needs someone else.
A swap starts with nothing uncovered
Now go back to Taylor and Jordan wanting to exchange Friday and Saturday.
Neither shift is necessarily uncovered.
Taylor still owns Friday.
Jordan still owns Saturday.
The unresolved action is the trade between those two existing assignments, not finding someone to fill a shift whose cleaner dropped out. The comparison page makes this distinction explicit: coverage usually concerns one assigned shift and one replacement, while a swap concerns two existing assignments whose workers want to exchange them.
If I force that situation through the coverage state machine, I immediately have to manufacture a condition that is not really true.
Do I mark Taylor’s Friday shift Pending Cover?
Taylor did not call out.
Do I record Cannot make it?
That is not what Taylor said.
Do I create a Cover Request for Jordan and then another one in the opposite direction?
Now two valid assignments temporarily look like two staffing failures.
The software may eventually arrive at the desired names, but the history would describe the wrong event.
Reusing the transition would also distort the middle
The final assignment is only part of a state model.
The intermediate records matter too.
In a real coverage case, Pending Cover tells an Owner or Admin something useful: one specific assigned shift still needs a replacement decision. An availability reply is not itself a reassignment, and even a Cover Request does not change the assigned cleaner until it is approved.
Those meanings work because the shift is genuinely at risk.
A swap needs different questions.
Conceptually, I would expect a swap process to care about things like:
Shift A currently belongs to Taylor
Shift B currently belongs to Jordan
Exchange requested
Exchange approved or rejected
Both assignments updated according to the trade
I am not claiming CleanConfirm implements that model—it does not manage worker-to-worker shift swaps. This is the separate state space I would expect to design if shift trading became part of the product.
That distinction matters for debugging later.
If I see Pending Cover, I want to know that I am looking for a replacement for one at-risk shift.
I do not want to wonder whether the status actually means “two cleaners are trying to trade Friday and Saturday.”
Approval means something different in each path
Coverage approval answers:
Who should take over this one shift?
The page’s coverage flow leaves that decision with the Owner or Admin. Once approved, the replacement becomes the assigned cleaner, but approval still does not mean the replacement has confirmed. That confirmation happens separately.
A swap approval has a different job.
It needs to authorize an exchange between two assignments that already existed.
Those are different decisions even if both eventually update an assigned_cleaner value somewhere.
That is the part I would not hide behind shared UI copy such as:
Approve change
The screen needs to communicate what is actually being approved.
For coverage:
Approve Jordan as replacement for Taylor’s Friday shift.
For a swap:
Approve Taylor and Jordan exchanging their Friday and Saturday assignments.
The second action carries two existing assignments as context.
The first carries one uncovered assignment.
Keep the state name tied to the problem it represents
The shift coverage vs shift swap comparison helped me draw the boundary around the current product.
CleanConfirm handles the side where a schedule already exists, an assigned cleaner explicitly responds, a Cannot make it response can lead to Cover review, and an approved replacement still needs to confirm. It does not provide employee self-service shift trading or a swap workflow.
That limitation keeps the current state names useful.
Pending Cover means there is actually a coverage problem.
Approved means the Cover Request was approved.
Confirmed means the newly assigned cleaner explicitly accepted the resulting assignment.
If shift swaps ever became part of the product, I would rather give them their own transitions than make two healthy shifts pretend to be uncovered just so I could reuse an existing flow.
When one worker is missing, use the coverage states.
When two valid assignments are being exchanged, model the exchange.
Top comments (0)