Skip to content

Refuse rules that point to a missing question, list the rules that use each question - #264

Merged
PhilReinking merged 6 commits into
mainfrom
fix/bits-276-rule-references
Oct 13, 2026
Merged

PhilReinking merged 6 commits into
mainfrom
fix/bits-276-rule-references

Conversation

@PhilReinking

@PhilReinking PhilReinking commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

A logic rule can no longer use or go to a question that was deleted or belongs to another form. The blocks list now names, per question, the rules that use it, for the coming delete dialogs.

Fixes BITS-276

  • Creating or updating a rule: each condition's source and a goto rule's action_payload must be a block uuid of the rule's form, else 422.
  • A hide or show rule may keep an old target from the editor; it saves as before.
  • The template import reuses these rules but skips this check. It already drops rules that point to a missing block.
  • GET /api/{form}/blocks adds used_by per block: [{id,name,block,as}]. block is the rule's block uuid; as is source, target (goto only) or both.

Heads-up: an existing rule with a condition on a deleted question, or a goto rule to one, now gets a 422 when saved through the API. Today's editor already sends no source for such a rule.

Tested: full PHP suite on MariaDB and SQLite. The new tests fail on main (bad rules save, no used_by). Scribe builds and documents both.

Not tested: no UI reads used_by yet.

🤖 Generated with Claude Code

PhilReinking and others added 3 commits October 13, 2026 00:57
A condition's source and the rule's target (action_payload) must be the
uuid of a block of the rule's form. A deleted question or one of another
form now gives a 422 on that field. The template import reuses these
rules without a block and keeps dropping such rules itself.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
GET /api/{form}/blocks adds used_by to each block: id and name of each
rule that uses it, the uuid of the block the rule is on, and whether it
uses the block as a condition source, as the target, or both.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@PhilReinking PhilReinking left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes at 3e15f76, CI green.

One must, inline at two lines: a hide or show rule that kept an old goto target. With both suggestions applied, the full suite passes on MariaDB. Held: the 5 new cases fail on main, another form's question gets the same message as a made-up one, groups still work as source and target, a broken rule can still be deleted, and listing 34 questions with rules takes the same 6 queries as main.

'conditions.*.chainOperator' => 'required|string|in:and,or',
'action' => 'required|string|in:hide,show,goto',
'action_payload' => 'nullable|string',
'action_payload' => ['nullable', 'string', $this->inThisForm('The question to go to is not in this form.')],

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The editor keeps the old target when a rule switches from goto to hide, and hides that field. Once that question is deleted, every save of this question's rules gets this 422 for the hide rule. Only goto uses the payload, so check it only there (plus use Illuminate\Validation\Rule;).

Suggested change
'action_payload' => ['nullable', 'string', $this->inThisForm('The question to go to is not in this form.')],
// only a goto rule uses its payload, a hide or show rule can keep an old target from the editor
'action_payload' => ['nullable', 'string', Rule::when($this->input('action') === 'goto', [$this->inThisForm('The question to go to is not in this form.')])],

'name' => $rule->name,
'block' => $block->uuid,
'sources' => collect($rule->conditions)->pluck('source'),
'target' => $rule->action_payload,

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A hide or show rule with an old target shows up as target here, so the delete dialog would warn about a rule that doesn't go to this question.

Suggested change
'target' => $rule->action_payload,
'target' => $rule->action === 'goto' ? $rule->action_payload : null,

PhilReinking and others added 2 commits October 13, 2026 01:24
The editor keeps the old target when a rule switches from goto to hide
or show. Once that question was deleted, the hide or show rule got 422.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@PhilReinking PhilReinking left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK at 41477fd, CI green. Both points from the last review are fixed.

The 5 new and changed cases fail on 3e15f76. A goto rule to a deleted question, another form's question or a made-up id still gets 422, also when the same request turns a stored hide rule into goto. Hide and show keep any old target. A wrong, missing or uppercase action is refused on its own. The docs text for action_payload still shows.

@PhilReinking PhilReinking left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK at c5ab3fe, CI green. The merge of main changes only CHANGELOG.md by hand: #263's and #264's lines both stay whole. The PR's own diff against main is the reviewed one from 41477fd.

@PhilReinking
PhilReinking merged commit 5b755e1 into main Oct 13, 2026
6 checks passed
PhilReinking added a commit that referenced this pull request Oct 13, 2026
The check from #264 still said "The question of your #1 condition
is not in this form." Now it reads like the other rule messages.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@PhilReinking
PhilReinking deleted the fix/bits-276-rule-references branch October 13, 2026 12:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant