fix(m7): stamping executed_at no longer requires a prior state transition
User reported `HTTP 400 — executed_at can only be set when state is
executed/reviewed_by_blue` when typing the timestamp inline in the new
scenario table. The state-gate predates the simplified UX — it made
sense back when the workflow was "Mark executed button + override
toggle", but the user has since asked for a single freely-typeable
datetime input.
- update_mission_test_fields drops the state check. Stamping a non-null
executed_at while state ∈ {pending, skipped, blocked} now auto-promotes
the state to `executed` in the same write. The promotion is gated by
the same mission.write_red_fields perm that executed_at already
required — no privilege escalation.
- MissionTestPage.tsx drops the state-based UI gate on canEditExecutedAt;
red perm alone now unlocks the input regardless of state.
- Replaced the old "rejection while pending" test with two new tests:
pending→executed via inline stamp + blue 403, and skipped→executed via
inline stamp.
- 139 pytest green.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
24
CHANGELOG.md
24
CHANGELOG.md
@@ -4,6 +4,30 @@ All notable changes to this project will be documented here. Format: [Keep a Cha
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Fixed (post-amendement 2026-05-15) — stamping executed_at no longer needs a prior state transition
|
||||
|
||||
User feedback: when a red user typed `executed_at` inline on a pending test
|
||||
in the new scenario table, the backend rejected with `HTTP 400 — executed_at
|
||||
can only be set when state is executed/reviewed_by_blue`. The state-gate
|
||||
was a holdover from the original "Mark executed button + override toggle"
|
||||
workflow; it made no sense once the UX let the operator type the time
|
||||
directly.
|
||||
|
||||
- `update_mission_test_fields` (`backend/app/services/mission_tests.py`) no
|
||||
longer rejects writes based on the source state. Stamping a non-null
|
||||
`executed_at` while state ∈ {`pending`, `skipped`, `blocked`} now
|
||||
auto-promotes the state to `executed` in the same write. The promotion
|
||||
rides on the same `mission.write_red_fields` perm that the executed_at
|
||||
field already required — no privilege escalation.
|
||||
- `MissionTestPage.tsx` drops the state-based gate on `canEditExecutedAt`:
|
||||
the field is editable any time the viewer holds `mission.write_red_fields`.
|
||||
- Tests: `test_executed_at_override_requires_red_perm_and_state` was the
|
||||
old guard; it's split into two new cases — `test_red_setting_executed_at_on_pending_auto_transitions_to_executed`
|
||||
(pending → executed via inline stamp, blue still 403'd) and
|
||||
`test_red_setting_executed_at_from_skipped_state_auto_transitions`
|
||||
(skipped → executed via the same path).
|
||||
- Total: **139 pytest** green.
|
||||
|
||||
### Added — M7 amendment (2026-05-15) — blue review fields + full-width scenario table
|
||||
|
||||
User feedback after the M7 ship: the blue team used to maintain 5 extra
|
||||
|
||||
Reference in New Issue
Block a user