Improves InputRecordFilterStep to correctly handle filters referencing fields across multi-hop joins (including one-to-many and many-to-one relationships) by properly sorting and traversing join paths from the main table outward.
Extracts joined-record caching and lookup logic into a new reusable class RecordWorkflowContextJoinedRecordHelper that application-defined workflow types can use for their own filter steps
Adds sortQueryJoinsFromMainTableOutward (adapted from AbstractRDBMSAction) to ensure joins are processed in the correct order when building the cross-product
Updates buildCrossProduct to be static and take the helper object, making it callable from RecordWorkflowTypeTester and custom workflows
Adds a reset() method to the helper so cached join records can be cleared after workflow execution (when records may have been persisted)
Comprehensive test coverage via InputRecordFilterStepTest exercising 1:1, 1:N, N:1, and multi-hop join combinations
Chore commits
Updates qqq-backend-core to a tagged branch build that includes the flipped-join validation fix
## Summary
Improves **InputRecordFilterStep** to correctly handle filters referencing fields across multi-hop joins (including one-to-many and many-to-one relationships) by properly sorting and traversing join paths from the main table outward.
- Extracts joined-record caching and lookup logic into a new reusable class **`RecordWorkflowContextJoinedRecordHelper`** that application-defined workflow types can use for their own filter steps
- Adds **`sortQueryJoinsFromMainTableOutward`** (adapted from `AbstractRDBMSAction`) to ensure joins are processed in the correct order when building the cross-product
- Updates `buildCrossProduct` to be `static` and take the helper object, making it callable from `RecordWorkflowTypeTester` and custom workflows
- Adds a **`reset()`** method to the helper so cached join records can be cleared after workflow execution (when records may have been persisted)
- Comprehensive test coverage via `InputRecordFilterStepTest` exercising 1:1, 1:N, N:1, and multi-hop join combinations
## Chore commits
- Updates `qqq-backend-core` to a tagged branch build that includes the flipped-join validation fix
- Updates `qbit-build-parent` to 1.5.1 (Java 21)
- Updates CircleCI orb to `kingsrook/qqq-orb@0.6`
## Test plan
- [x] Filters on 1:1 joins match/reject correctly
- [x] Filters on N:1 joins match/reject correctly
- [x] Filters on 1:N joins match/reject correctly
- [x] Filters on multi-hop paths (N:1→N:1, 1:N→1:1, 1:N→N:1, N:1→1:N, 1:N→1:N, 1:N→N:1→1:1) match/reject correctly
- [x] Missing FK values or empty join sets result in no match (no NPE)
- [x] `RecordWorkflowTypeTester.doesFilterMatch` works post-execution after `reset()` clears stale cache
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
Improves InputRecordFilterStep to correctly handle filters referencing fields across multi-hop joins (including one-to-many and many-to-one relationships) by properly sorting and traversing join paths from the main table outward.
RecordWorkflowContextJoinedRecordHelperthat application-defined workflow types can use for their own filter stepssortQueryJoinsFromMainTableOutward(adapted fromAbstractRDBMSAction) to ensure joins are processed in the correct order when building the cross-productbuildCrossProductto bestaticand take the helper object, making it callable fromRecordWorkflowTypeTesterand custom workflowsreset()method to the helper so cached join records can be cleared after workflow execution (when records may have been persisted)InputRecordFilterStepTestexercising 1:1, 1:N, N:1, and multi-hop join combinationsChore commits
qqq-backend-coreto a tagged branch build that includes the flipped-join validation fixqbit-build-parentto 1.5.1 (Java 21)kingsrook/qqq-orb@0.6Test plan
RecordWorkflowTypeTester.doesFilterMatchworks post-execution afterreset()clears stale cache🤖 Generated with Claude Code