1Ordinary client — internal_role: null

Nothing is added. No staff bar, no Move Forward, no Change Status, no Assign, and no assignee name anywhere — the payload does not carry assigned_to_name at all for this viewer, so the name is absent from the HTTP response, not merely hidden in the DOM (spec decision 7). Identical to the BEFORE capture.

#1527Spec✦ Feature

Ticket panel: Move Forward and a role-correct Change Status control

RARequested by Redmine Admin Updated 2 hours ago ✎ Edit ⏸ Pause
GET …/tasks/1527 → { status_id: 8, allowed_statuses: [] } no can_move_forward · no can_assign · no assigned_to_name key

At a glance

Reference
#1527
Stage
Spec
Type
Feature

2Developer, assigned to this ticket

One control, not two. The server sends allowed_statuses already narrowed to what this viewer may set — for a developer that is exactly [next_status], so length < 2 ⇒ Change Status is not rendered and Move Forward is the only door. A one-option dropdown would be a menu offering a choice that does not exist, three clicks for what the button does in one. The label names the target stage, from next_status_id + next_status_name.

#1527Spec✦ Feature

Ticket panel: Move Forward and a role-correct Change Status control

RARequested by Redmine Admin ✎ Edit ⏸ Pause
⚙ Staff controls
→ Move to Design You are assigned to this ticket.
can_move_forward: true · next_status_id: 15 ("Design") allowed_statuses: [ {id:15, name:"Design"} ] → 1 option ⇒ no dropdown

At a glance

Reference
#1527
Stage
Spec
Assigned to
GWGuillaume W.

3Developer, not assigned — disabled + tooltip

The button is present and keyboard-focusable: aria-disabled="true" with the click handler short-circuited, never a bare disabled (which drops it out of the tab order, so the explanation becomes unreachable exactly for the people who need it most). The tooltip is the aria-describedby target, shown on hover and on :focus-visible. Below: the same button focused by keyboard, with the second reason shape — nothing left to advance to.

#1531In development

Backend: the progression rule and the move-forward route

RARequested by Redmine Admin ⏸ Pause
⚙ Staff controls
Only the developer assigned to this ticket can move it forward. → Move to QA
⚙ Staff controls — variant: no next stage (ticket is Shipped)
This ticket is at the end of the pipeline. → Move forward focus-visible ring — the tooltip opens on keyboard focus too
can_move_forward: false, next_status_id: 10 → “not assigned to you” can_move_forward: false, next_status_id: null → “end of the pipeline” allowed_statuses: [] in both cases ⇒ no Change Status control

At a glance

Stage
In development
Assigned to
ALAlice L.

4CTO / platform admin — full set, backward included, plus Assign

Three controls on one row, in decreasing frequency of use: Move Forward (primary — the one verb used twenty times a day) → Change Status (the correction path, forward and backward) → Assign. The Change Status menu lists allowed_statuses verbatim: the frontend holds no status order, so it cannot decide what “forward” means and does not try. Backlog is absent because the server never puts it there.

#1527Spec✦ Feature

Ticket panel: Move Forward and a role-correct Change Status control

RARequested by Redmine Admin ✎ Edit⏸ Pause
⚙ Staff controls
→ Move to Design SpecChange status
GWAssigned to Guillaume W.

Assign menu open — GET /projects/9/developers. “Unassigned” is an explicit first option, separated by a hairline from the people.

Change Status menu (same anatomy as the existing TransitionControl, §TB.6): each target is a TaskStatusPill, selecting one opens the inline confirm step before the mutation fires. Backward targets are listed in the server's order, unmarked — a “backward” badge would need a status order in src/.
can_move_forward: true · can_assign: true · next_status_id: 15 allowed_statuses: 7, 15, 9, 10, 11, 12, 13, 14 → ≥ 2 options ⇒ dropdown renders

At a glance

Reference
#1527
Stage
Spec
Assigned to
GWGuillaume W.

5Backlog ticket, viewed by a CTO — the credit gate holds

No status control renders for anyone, including CTO and admin. Not a disabled Move Forward with an explanation — absent. Submit stays the only way out of the backlog, and the pane must not suggest a second door exists. The Assign control survives: assigning changes no status and costs no credit, so a CTO can line the work up before the client pays.

#1528Backlog✦ Feature

Ticket panel: Assign to Developer and assignee visibility

Complexity 4/10 ➤ Submit to the team ✎ Edit ⏸ Pause
⚙ Staff controls
Unassigned No developer is configured for this project.

Empty-state variant of the Assign control: GET …/developers legitimately returned []. The trigger is aria-disabled (focusable, described by the note), never an empty menu that opens onto nothing.

Filing is free — nothing starts until you submit this ticket.

status_id: 16 → Move Forward and Change Status are not rendered can_move_forward: false · next_status_id: null · allowed_statuses: [] can_assign: true — assignment is not a status change

At a glance

Stage
Backlog
Assigned to
Unassigned

6Server refusals — inline, never blanking the pane

Every error is a role="alert" paragraph inside the staff bar, under the control that produced it. The ticket, its description and its criteria stay on screen; the status pill never showed an unconfirmed stage, because the controls are pessimistic by design — there is no optimistic state to roll back. Each failure still invalidates the board and detail queries, so a pane made stale by someone else converges on the next paint.

⚙ Staff controls
→ Move to QA In developmentChange status
403 — You're not allowed to make that change. The ticket has been refreshed.
409 — Couldn't move this task. (the existing invalid-transition message, reused verbatim)
MDAssigned to Marc D.
422 — Marc D. has no Redmine account linked yet. An admin can add one in the admin dashboard.
upstream — Couldn't change the assignee.