Feature/follow all exposed joins in input record filter step #6

Merged
darinkelkhoff merged 6 commits from feature/follow-all-exposed-joins-in-input-record-filter-step into develop 2026-03-24 21:37:14 +00:00
darinkelkhoff commented 2026-02-16 22:24:17 +00:00 (Migrated from github.com)

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

  • Filters on 1:1 joins match/reject correctly
  • Filters on N:1 joins match/reject correctly
  • Filters on 1:N joins match/reject correctly
  • 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
  • Missing FK values or empty join sets result in no match (no NPE)
  • RecordWorkflowTypeTester.doesFilterMatch works post-execution after reset() clears stale cache

🤖 Generated with Claude Code

## 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)
Sign in to join this conversation.