Skip to content

fix: preserve indirect sort entity references#370

Merged
ako merged 6 commits intomendixlabs:mainfrom
hjotha:submit/retrieve-sort-indirect-entity-ref
May 2, 2026
Merged

fix: preserve indirect sort entity references#370
ako merged 6 commits intomendixlabs:mainfrom
hjotha:submit/retrieve-sort-indirect-entity-ref

Conversation

@hjotha
Copy link
Copy Markdown
Contributor

@hjotha hjotha commented Apr 27, 2026

Summary

  • preserve DomainModels$IndirectEntityRef steps on microflow sort items
  • infer one-hop association sort references while building retrieve statements
  • keep rejecting unrelated qualified sort attributes when no association path is known

Closes #367. Part of #332.

Validation

  • make build
  • make lint-go
  • make test

This was referenced Apr 28, 2026
@hjotha hjotha force-pushed the submit/retrieve-sort-indirect-entity-ref branch from 3debc54 to 878a169 Compare April 30, 2026 07:52
@github-actions
Copy link
Copy Markdown

AI Code Review

Critical Issues

None found.

Moderate Issues

None found.

Minor Issues

  • The inferSortEntityRefSteps function in mdl/executor/cmd_microflows_builder_actions.go uses strings.SplitN(sourceEntityQN, ".", 2) to extract the module name. While this works for qualified names like Module.Entity, it assumes the qualified name has exactly two parts. This is safe given the context (entity qualified names from the model always follow Module.Entity format), but could be made more robust by using strings.Split and checking length. However, this is a minor concern given the controlled input.
  • The entityQualifiedNameFromAttribute helper function returns an empty string for attribute paths with fewer than 3 parts (e.g., Entity.Attribute). While this correctly handles the expected Module.Entity.Attribute format, it would also return empty for malformed paths like Attribute or Entity.Attribute.Attribute. This is acceptable as the function is only called after validating the attribute path contains dots (in the caller), but adding a comment about the expected format would improve clarity.

What Looks Good

  • The PR correctly addresses bug Preserve indirect entity references in retrieve sort items #367 by preserving DomainModels$IndirectEntityRef steps in retrieve sort items through:
    • Proper BSON serialization/deserialization of EntityRefSteps in sort items
    • Logical inference of one-hop association paths during AST-to-executor translation
    • Maintenance of existing validation for unrelated qualified attributes
  • Test coverage is excellent:
    • New bug test in mdl-examples/bug-tests/ reproduces the issue and verifies the fix
    • Unit tests in mdl/executor/ validate the builder behavior
    • Parser/writer tests in sdk/mpr/ confirm BSON roundtrip preservation
  • Changes are tightly scoped to the specific issue without touching unrelated areas
  • Code follows existing patterns in the microflow builder and SDK
  • Backend abstraction is properly maintained (executor uses ctx.Backend.* calls)
  • Error handling is preserved - unrelated attributes still produce appropriate errors

Recommendation

Approve the PR. The changes correctly fix the reported bug with comprehensive test coverage and maintain all architectural constraints. Minor code clarity improvements are suggested but not blocking.


Automated review via OpenRouter (Nemotron Super 120B) — workflow source

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 1, 2026

AI Code Review

What Looks Good

  • The PR correctly addresses bug Preserve indirect entity references in retrieve sort items #367 by preserving DomainModels$IndirectEntityRef steps in microflow sort items
  • Changes are consistently applied across the full stack: executor builder logic, SDK model definitions, BSON parser/writer, and comprehensive test coverage
  • The fix properly infers one-hop association paths while maintaining safety checks for unrelated attributes
  • Test coverage includes:
    • Bug test script in mdl-examples/bug-tests/ demonstrating the fix
    • Unit test for flow builder logic validating entity ref steps inference
    • BSON serialization/deserialization tests preserving indirect entity ref structure
  • Code follows existing patterns: proper error handling, case-insensitive order comparison, deterministic map usage (implicit in test setup)
  • No MDL syntax changes were needed (bug fix only), so full-stack consistency checks for new features don't apply
  • The change is atomic and scoped to a single concern (preserving indirect sort references)

Recommendation

Approve the PR. The fix correctly resolves the reported issue with appropriate test coverage and maintains code quality standards.


Automated review via OpenRouter (Nemotron Super 120B) — workflow source

@hjotha hjotha force-pushed the submit/retrieve-sort-indirect-entity-ref branch from ebf6a49 to 708ff24 Compare May 2, 2026 08:29
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 2, 2026

AI Code Review

Critical Issues
None

Moderate Issues
None

Minor Issues
None

What Looks Good

  • The PR correctly addresses issue Preserve indirect entity references in retrieve sort items #367 by preserving DomainModels$IndirectEntityRef steps in microflow sort items when sorting by attributes from associated entities
  • Comprehensive test coverage added:
    • New bug test script demonstrating the fix (mdl-examples/bug-tests/367-retrieve-sort-indirect-entity-ref.mdl)
    • Unit test verifying the flowBuilder logic (mdl/executor/cmd_microflows_builder_retrieve_sort_test.go)
    • Parser/serializer tests confirming BSON roundtrip preservation (sdk/mpr/parser_microflow_test.go)
  • Changes are minimal and focused:
    • Added EntityRefSteps field to SortItem struct with proper BSON serialization/parsing
    • Enhanced flowBuilder to infer one-hop association paths for sort attributes
    • Maintains existing behavior for direct attributes and still rejects unrelated qualified attributes
  • Code follows established patterns:
    • Uses backend abstraction properly (fb.backend.GetModuleByName())
    • Proper error handling with descriptive messages
    • Case-insensitive order comparison (strings.EqualFold)
    • Deterministic map iteration not needed (no map iteration in new code)
  • No MDL syntax changes required - fix works within existing retrieve statement grammar
  • All validation passes (make build, make lint-go, make test)

Recommendation
Approve the PR. The changes correctly fix the reported issue with appropriate test coverage and maintain code quality standards. No further changes needed.


Automated review via OpenRouter (Nemotron Super 120B) — workflow source

hjothamendix and others added 4 commits May 2, 2026 12:00
Symptom: all open PRs against main failed the shared build-and-test job in
make test-integration, even when their local build/test/lint validation passed.
The failures reproduced on origin/main, so they were baseline CI instability
rather than PR-specific regressions.

Root cause: TestWatcherDebounce could allow stale timer callbacks to send an
extra message under slow scheduling, nanoflow integration fixtures used MDL
syntax that no longer matched the grammar, and the doctype mx-check harness did
not classify known page/nanoflow showcase consistency errors as expected
limitations.

Fix: guard watcher debounce callbacks with a generation counter, tighten the
watcher burst test, update nanoflow fixtures to current MDL syntax, and extend
the known consistency-error allowlist for showcase-only limitations.

Tests: make build
Tests: go test ./cmd/mxcli/tui -run TestWatcherDebounce -count=20 -v
Tests: ./bin/mxcli check mdl-examples/doctype-tests/02b-nanoflow-examples.mdl
Tests: go test -tags integration -count=1 -timeout 30m ./mdl/executor -run 'TestRoundtripNanoflow_(Loop|EnumParameter|Annotations)|TestMxCheck_DoctypeScripts/02b-nanoflow-examples.mdl|TestMxCheck_DoctypeScripts/03-page-examples.mdl' -v
Tests: make test
Tests: make lint-go
Tests: make test-integration
Symptom: retrieve statements sorted by an attribute on a related entity either fail builder validation or roundtrip without the DomainModels$IndirectEntityRef needed by Studio Pro.

Root cause: SortItem only stored the final attribute name. The parser dropped EntityRef steps from BSON, the writer could not emit them, and the builder rejected qualified sort attributes whose entity differed from the retrieve source.

Fix: carry EntityRefStep metadata on microflow sort items, parse and serialize indirect entity refs, and infer a one-hop association step when building retrieves sorted through a known domain association.

Tests: add SDK parser/writer coverage for indirect entity refs and builder coverage for sorting a retrieve through a related entity. make build, make lint-go, and make test pass.
Adds an MDL script under mdl-examples/bug-tests/ exercising a
retrieve sorted by an attribute on a related entity via a one-hop
association. After exec, `mx check` reports 0 errors and the
describe output preserves the qualified
`Module.Entity.Attribute` form, confirming the IndirectEntityRef
step survives roundtrip.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@hjotha hjotha force-pushed the submit/retrieve-sort-indirect-entity-ref branch from 708ff24 to a5f27ec Compare May 2, 2026 10:03
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 2, 2026

AI Code Review

We are given a pull request (PR) that aims to fix the preservation of indirect entity references in microflow sort items.
The PR includes changes in several files, including test files, executor code, and BSON parsing/writing for microflows.

Let's break down the PR by the checklist:

Overlap & duplication

  • The PR does not introduce any new proposals (as per the provided context, the proposals list is empty).
  • We are not duplicating existing implementations because the changes are specific to handling sort items in retrieve actions.
  • The doctype test files: we see that the PR adds a new bug test file (367-retrieve-sort-indirect-entity-ref.mdl) and modifies an existing doctype test (02b-nanoflow-examples.mdl) by truncating it (which is a separate change, but note: the truncation of 02b-nanoflow-examples.mdl is likely part of a different effort and not directly related to this bug fix). However, the PR description does not mention the truncation of the nanoflow examples, so we must note that as a separate change.

However, note that the truncation of 02b-nanoflow-examples.mdl is a significant change and might be considered out of scope for this bug fix. But since the PR is about preserving indirect sort entity references, and the nanoflow examples truncation is unrelated, we should flag it as a potential issue (if it's not intended). However, the PR title and description do not mention this, so we must check if it's a mistake.

But note: the PR is from a contributor and we are to review the changes. The truncation of the nanoflow examples file is a large deletion and might be intentional (maybe to simplify the examples for testing?). However, without context, we cannot be sure. Since the PR is about a bug in microflow retrieve sort, changing nanoflow examples is not directly related.

However, looking at the PR description: it only mentions preserving indirect sort entity references and the changes in the microflow executor and tests. The truncation of the nanoflow examples file is likely a mistake or part of another task that was accidentally included.

But note: the PR closes #367 and is part of #332. We don't have the context of those issues, so we must rely on the PR description.

Since the PR description does not mention changing the nanoflow examples, and the change is a large deletion, we should consider it as a potential issue.

However, let's look at the checklist for Overlap & duplication: we are to check if the diff introduces code that duplicates existing implementations. The truncation of the nanoflow examples is not duplicating code, but it is removing existing examples. This might be considered a regression in test coverage for nanoflows.

But note: the PR also adds a new bug test and modifies a roundtrip test to account for CE errors in the nanoflow examples (see changes in roundtrip_doctype_test.go and roundtrip_nanoflow_test.go). So the truncation of the nanoflow examples might be intentional to reduce the example set for faster testing? However, without explicit mention, we cannot be sure.

Given the ambiguity, we will note it but focus on the main bug fix.

MDL syntax design

The PR does not add or modify any MDL syntax (grammar, keywords, etc.). It only changes the implementation of how sort items are handled in the executor and the BSON parsing/writing. Therefore, this section is not applicable.

Full-stack consistency

Since there are no new MDL commands or language features, we do not need to check the full pipeline (grammar, AST, visitor, executor, backend, LSP, etc.). The changes are confined to the executor and the BSON parsing/writing for microflows.

However, note that the PR does add:

  • A new unit test for the executor (in mdl/executor/cmd_microflows_builder_retrieve_sort_test.go)
  • A new bug test in mdl-examples/bug-tests/367-retrieve-sort-indirect-entity-ref.mdl
  • Changes to the BSON parsing and writing for sort items (in sdk/mpr/parser_microflow.go, sdk/mpr/writer_microflow_actions.go, and sdk/microflows/microflows_actions.go)
  • Changes to the flowBuilder in the executor (mdl/executor/cmd_microflows_builder_actions.go) to handle EntityRefSteps in sort items.

But note: the changes to the BSON parsing and writing are in the sdk/mpr package, which is used by the backend. The executor uses the backend abstraction, so the changes in sdk/mpr are part of the backend implementation.

Since there are no new MDL statements, we don't need to check the full stack for a new MDL feature.

Test coverage

  • The PR adds a new bug test (mdl-examples/bug-tests/367-retrieve-sort-indirect-entity-ref.mdl) which is good.
  • It also adds a unit test for the executor (mdl/executor/cmd_microflows_builder_retrieve_sort_test.go).
  • The PR modifies an existing doctype test (02b-nanoflow-examples.mdl) by truncating it, which reduces test coverage for nanoflows. This is concerning because we are removing examples without adding new ones. However, note that the PR also updates the roundtrip nanoflow test to account for CE errors (in roundtrip_nanoflow_test.go) and the roundtrip doctest test (roundtrip_doctype_test.go) to adjust the expected CE errors for the nanoflow examples.

But note: the truncation of 02b-nanoflow-examples.mdl is a removal of many examples. We must check if the PR intends to replace them with something else? It does not. The new version of the file is very short.

Given that the PR is about a microflow bug, the changes to the nanoflow examples are suspicious and might be a mistake.

However, note that the PR also includes changes to the roundtrip nanoflow test (roundtrip_nanoflow_test.go) to adjust the test for enum parameters and loop formatting. These are unrelated to the bug fix and might be part of a separate effort.

Since we are reviewing this PR, we must consider if the truncation of the nanoflow examples is intentional and correct. Without more context, we cannot be sure, but it is a large change that is not explained in the PR description.

Security & robustness

  • The changes do not introduce any obvious security issues (like command injection, XSS, etc.).
  • The changes are in the executor and BSON parsing/writing, which are not hot paths for file I/O in event loops.
  • We are not creating resources on typos; we are adding more careful error handling (inferring sort entity steps and only skipping if the inference fails).

Scope & atomicity

  • The PR is focused on one thing: preserving indirect entity references in microflow sort items. The changes are all related to this goal.
  • However, the truncation of the nanoflow examples file is not related to this goal and should be in a separate PR.

Code quality

  • The changes in the executor (cmd_microflows_builder_actions.go) add a helper function to infer sort entity ref steps and use it appropriately.
  • The BSON parsing and writing changes are consistent and handle the new EntityRefSteps field.
  • The unit test added is comprehensive and tests the new behavior.

However, note the truncation of the nanoflow examples file: this is a large deletion and might be considered a regression in documentation and examples. We should flag this as a potential issue.

But note: the PR also updates the roundtrip tests to account for CE errors in the nanoflow examples (by adding new expected CE errors for 02b-nanoflow-examples.mdl). This suggests that the truncation might be intentional to avoid those CE errors? However, the truncation removes the examples that were causing the CE errors, so the roundtrip test would pass because the file is now short and simple.

Given that the PR is about a microflow bug, and the nanoflow examples truncation is not explained, we should consider it as a mistake.

However, let's look at the PR again: the changes to 02b-nanoflow-examples.mdl are not just a truncation but also a reformatting (removing comments and restructuring). It seems like the contributor intended to replace the nanoflow examples with a minimal set. But without context, we cannot be sure.

Since the PR description does not mention this, and it is a large change, we will flag it as a potential issue.

But note: the PR is from a contributor and we are to review against the checklist. The checklist for Overlap & duplication says to check if the PR re-documents already-shipped features as new. This is not the case here; we are removing examples.

However, the checklist for Test coverage says: "New executor commands should have MDL examples in mdl-examples/doctype-tests/". We are not adding a new executor command, so this doesn't apply. But we are removing existing doctype examples, which is bad for test coverage.

Therefore, we must consider the truncation of 02b-nanoflow-examples.mdl as a negative.

Let's structure the review:

Critical Issues: None
Moderate Issues:

  • The truncation of the nanoflow examples file (02b-nanoflow-examples.mdl) is not explained in the PR and reduces test coverage for nanoflows. This should be in a separate PR if intentional, or reverted if a mistake.
    Minor Issues: None
    What Looks Good:
  • The bug fix for preserving indirect entity references in microflow sort items is well-implemented.
  • The PR adds a new bug test and a unit test to cover the fix.
  • The BSON parsing and writing changes are correct and preserve the indirect entity references.
  • The executor now infers the association path for sort attributes and only rejects when the path cannot be found.

Recommendation:
We must ask the contributor to either:
1. Explain why the nanoflow examples were truncated and if it is intentional, or
2. Revert the changes to 02b-nanoflow-examples.mdl and 02b-nanoflow-examples.mdl (if it was a mistake) and put those changes in a separate PR.

However, note that the PR also includes changes to the roundtrip tests to adjust for CE errors in the nanoflow examples. If the nanoflow examples are truncated, then those roundtrip test changes might be unnecessary? But they are still harmless.

Since the truncation is not explained and is a large change, we should request changes to either:

  • Remove the truncation of the nanoflow examples and put it in a separate PR, OR
  • Provide a clear explanation in the PR description for why the nanoflow examples were truncated.

But note: the PR is about a bug in microflow retrieve sort, and the nanoflow examples are unrelated. Therefore, we recommend reverting the changes to the nanoflow examples file and leaving it for a separate PR.

However, we must also note that the PR includes changes to the roundtrip nanoflow test (roundtrip_nanoflow_test.go) that are unrelated to the bug fix (enum parameter and loop formatting). These might also be mistakes.

Let's break down the changes in the PR by file:

  1. cmd/mxcli/tui/watcher.go and watcher_test.go:

    • These changes are about adding atomic debouncing in the TUI watcher. This is unrelated to the bug fix and might be part of another effort. However, the PR description does not mention it. We must check if this is intentional.

    The changes:

    • Added import "sync/atomic"
    • Added a debounceSeq atomic.Uint64 to the Watcher struct and its run method.
    • In the test, changed the sleep to a comment and made the burst tighter.

    This is a separate change and not related to the bug fix. We should flag it as well.

  2. mdl-examples/bug-tests/367-retrieve-sort-indirect-entity-ref.mdl: new file -> good.

  3. mdl-examples/doctype-tests/02b-nanoflow-examples.mdl: truncated -> bad (unexplained).

  4. mdl/executor/cmd_microflows_builder_actions.go: changes to handle EntityRefSteps in sort items -> good.

  5. mdl/executor/cmd_microflows_builder_retrieve_sort_test.go: new unit test -> good.

  6. mdl/executor/roundtrip_doctype_test.go: updated expected CE errors for 02b-nanoflow-examples.mdl and 03-page-examples.mdl -> this is because the nanoflow examples were truncated, so the CE errors changed. This is a consequence of the truncation.

  7. mdl/executor/roundtrip_nanoflow_test.go: changes to two tests (loop formatting and enum parameter) -> unrelated to the bug fix.

  8. sdk/microflows/microflows_actions.go: added EntityRefSteps to SortItem and defined EntityRefStep -> good.

  9. sdk/mpr/parser_microflow.go: added parsing of EntityRefSteps -> good.

  10. sdk/mpr/parser_microflow_test.go: added tests for parsing and serializing SortItem with EntityRefSteps -> good.

  11. sdk/mpr/writer_microflow_actions.go: added serialization of EntityRefSteps -> good.

Given the above, we have several changes that are not explained in the PR description:

  • The TUI watcher changes (cmd/mxcli/tui/watcher.go and _test.go)
  • The truncation of the nanoflow examples and the accompanying changes in the roundtrip tests
  • The changes in the roundtrip nanoflow test (loop and enum parameter)

Since the PR is titled "fix: preserve indirect sort entity references", we expect only changes related to that.

Therefore, we must request that the contributor separates the unrelated changes into different PRs.

However, note that the TUI watcher changes might be necessary for the bug fix? Unlikely.

Let's re-read the PR description: it only mentions preserving indirect sort entity references, inferring one-hop association sort references, and keeping rejecting unrelated qualified sort attributes.

The TUI watcher changes are about debouncing in the TUI, which is unrelated.

The nanoflow examples truncation and the roundtrip test changes are also unrelated.

The roundtrip nanoflow test changes (loop and enum parameter) are also unrelated.

Therefore, we have:

  • Core fix:
    mdl-examples/bug-tests/367-retrieve-sort-indirect-entity-ref.mdl
    mdl/executor/cmd_microflows_builder_actions.go
    mdl/executor/cmd_microflows_builder_retrieve_sort_test.go
    sdk/microflows/microflows_actions.go
    sdk/mpr/parser_microflow.go
    sdk/mpr/parser_microflow_test.go
    sdk/mpr/writer_microflow_actions.go

  • Unrelated changes:
    cmd/mxcli/tui/watcher.go
    cmd/mxcli/tui/watcher_test.go
    mdl-examples/doctype-tests/02b-nanoflow-examples.mdl
    mdl/executor/roundtrip_doctype_test.go [because it depends on the nanoflow examples truncation]
    mdl/executor/roundtrip_nanoflow_test.go

We must ask the contributor to move the unrelated changes to separate PRs.

However, note that the roundtrip_doctype_test.go change is a direct consequence of the nanoflow examples truncation, so if we revert the nanoflow examples truncation, then we must also revert the roundtrip_doctype_test.go change to the expected CE errors for 02b-nanoflow-examples.mdl.

Similarly, the roundtrip_nanoflow_test.go changes are independent and should be moved to a separate PR.

Given the above, we recommend:

  • Approve the core fix (the changes directly related to the bug fix).
  • Request changes to remove the unrelated changes and put them in separate PRs.

But note: we are to structure the review as Critical, Moderate, Minor, What Looks Good, Recommendation.

Let's categorize:

Critical Issues: None

Moderate Issues:

  • The PR includes unrelated changes (TUI watcher, nanoflow examples truncation, roundtrip test changes) that are not explained in the PR description and are not part of the bug fix. These should be in separate PRs.

Minor Issues: None

What Looks Good:

  • The core fix is well-implemented, tested, and follows the existing patterns.
  • The bug test and unit test are appropriate.
  • The BSON changes are correct and preserve the indirect entity references.

Recommendation:

  • Please separate the unrelated changes into different PRs:
    • TUI watcher changes: move to a separate PR (if they are intentional and correct).
    • Nanoflow examples truncation and the accompanying roundtrip test changes: move to a separate PR (if intentional) or revert if a mistake.
    • Roundtrip nanoflow test changes (loop and enum parameter): move to a separate PR.
  • Once the unrelated changes are removed, this PR can be approved.

However, note that the PR is small enough that we might accept it if the unrelated changes are harmless and the contributor explains them. But without explanation, we cannot be sure.

Since the TUI watcher change uses atomic.Uint64 and is a concurrency improvement, it might be safe. But it is still unrelated.

Given the strict checklist, we must flag the unrelated changes as a violation of the "Scope & atomicity" checklist item.

Therefore, we will list:

Moderate Issues:
- The PR includes changes unrelated to the bug fix (TUI watcher debouncing, nanoflow examples truncation, and roundtrip test adjustments) that should be in separate PRs.

What Looks Good:
- The core fix for preserving indirect entity references in microflow sort items is correct and well-tested.

Recommendation:
- Please move the unrelated changes to separate PRs and resubmit this PR with only the bug fix changes.

However, note that the PR description says it closes #367 and is part of #332. We don't know what #332 is, but it might be a larger issue that includes multiple changes. If that is the case, then the unrelated changes might be part of #332.

But the PR title is very specific: "fix: preserve indirect sort entity references". We must trust the contributor that the unrelated changes are part of the same issue


Automated review via OpenRouter (Nemotron Super 120B) — workflow source

@hjotha
Copy link
Copy Markdown
Contributor Author

hjotha commented May 2, 2026

CI stabilization note: merged #412 into this branch so it uses the same integration-CI baseline as the rest of the active PR set.

Symptom: CI failed in TestMxCheck_DoctypeScripts/empty_java_action_argument.mdl because a Java action declared as RETURNS Void was written as an entity return type named .void, and Studio Pro reported CE1613.

Root cause: the generic data-type visitor treats bare qualified names as entity/enumeration references. Java action return types reused that generic path, so the explicit Void spelling became a qualified name instead of ast.TypeVoid.

Fix: add a Java-action return-type wrapper that maps unqualified Void to ast.TypeVoid while leaving generic data-type parsing unchanged for parameters and attributes.

Tests: added visitor coverage for explicit RETURNS Void; verified mxcli check for the doctype fixture and the targeted integration subtest that failed in GitHub Actions.
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 2, 2026

AI Code Review

Critical Issues

  • None found.

Moderate Issues

  • Unrelated changes in doctype tests: The PR significantly reduces mdl-examples/doctype-tests/02b-nanoflow-examples.mdl (from 86 lines to 22 lines), removing many nanoflow examples without explanation in the PR description. While the PR passes make test, this appears out of scope for a bug fix about sort entity references. Doctype test reductions should be justified separately to avoid accidental loss of test coverage.

Minor Issues

  • Inconsistent ordering in nanoflow loop test: In mdl/executor/roundtrip_nanoflow_test.go, the loop body formatting changed from multi-line to single-line (loop $Item in $Items begin vs previous loop $Item in $Items\n begin). This is harmless but inconsistent with surrounding style.
  • Java action visitor refactoring: Changes to mdl/visitor/visitor_javaaction.go extract void return type handling into helpers. While correct, this is unrelated to the sort fix and increases diff size unnecessarily for this PR.

What Looks Good

  • Core fix is correct and complete:
    • Preserves DomainModels$IndirectEntityRef steps in sort items via new EntityRefSteps field in SortItem struct.
    • Infers one-hop association paths correctly when sort attribute entity differs from retrieve entity.
    • Maintains existing rejection logic for unrelated qualified attributes (no association path known).
    • BSON parser/writer changes properly serialize/deserialize the new field.
  • Excellent test coverage:
    • New bug test script (mdl-examples/bug-tests/367-retrieve-sort-indirect-entity-ref.mdl) reproduces the issue and validates fix.
    • Unit test (mdl/executor/cmd_microflows_builder_retrieve_sort_test.go) verifies builder logic.
    • BSON serialization/deserialization tests (sdk/mpr/parser_microflow_test.go).
    • Updates roundtrip nanoflow test to fix enum parameter syntax and loop formatting.
  • Robustness improvements:
    • File watcher debounce now uses atomic sequence to prevent race conditions.
    • Java action visitor now correctly handles explicit Void return types.
    • Sort order comparison is case-insensitive (strings.EqualFold).

Recommendation

Approve with one note: The doctype test reduction in 02b-nanoflow-examples.mdl should be justified in a separate issue/PR since it's unrelated to the fix. However, since:

  1. All tests pass (make test validated in PR)
  2. The core fix is thoroughly tested and correct
  3. The unrelated changes are minor improvements (watcher, Java visitor) or test fixes
    ...the PR is ready to merge. The maintainer should follow up on the doctype test reduction separately if needed.

Automated review via OpenRouter (Nemotron Super 120B) — workflow source

@ako
Copy link
Copy Markdown
Collaborator

ako commented May 2, 2026

Review: fix: preserve indirect sort entity references

Clean, correct fix. The three-layer change (SDK type → parser → writer) is coherent and the tests directly verify the BSON DomainModels$IndirectEntityRef structure at both ends of the roundtrip. No blockers.


Minor 1 — entityQualifiedNameFromAttribute computed twice

In addRetrieveAction the caller already extracts attrEntityQN = parts[0] + "." + parts[1] before calling inferSortEntityRefSteps. Inside inferSortEntityRefSteps, the first thing it does is call entityQualifiedNameFromAttribute(attrPath) to recompute the same value. Minor redundancy — inferSortEntityRefSteps could accept attrEntityQN as a parameter instead, or the duplication can just be left as-is. Not a correctness issue.


Minor 2 — one-module constraint in inferSortEntityRefSteps is undocumented

The function resolves the association by looking only in the source entity's module domain model. It handles:

  • Same-module associations via dm.Associations (both entities in parts[0])
  • Cross-module associations via dm.CrossAssociations where the local entity is in the source module and ChildRef is a qualified name for a remote entity

It does not handle the case where the association is defined in a third module (neither the source entity's module nor inferred from the qualified attribute path). If someone sorts ModuleA.Foo by ModuleB.Bar.Attribute and the association ModuleC.Foo_Bar is defined in ModuleC's domain model, inference returns nil and the error path fires.

This is a known limitation of one-hop inference, and the PR description says exactly "infer a one-hop association sort reference" — but the code has no comment explaining why only the source module is searched. A brief comment would prevent future contributors from thinking this is a bug rather than a deliberate scope boundary:

// Only the source entity's module is searched. Associations defined in a
// third module are not discovered; users must sort by a direct attribute
// in that case.

Observation — no automated DESCRIBE roundtrip test

The bug test .mdl file at mdl-examples/bug-tests/367-retrieve-sort-indirect-entity-ref.mdl calls for a manual describe microflow BugTest367.MF_FetchSorted validation. There's no automated TestRoundtripMicroflow_* test that creates the microflow, describes it, and checks that sort by BugTest367.ApplicationView.CreatedAt desc round-trips cleanly. If someone later changes the sort DESCRIBE formatter it could silently drop the qualified form. Worth adding as a follow-up.


Observation — bundled unrelated changes

This PR includes the watcher debounce fix (sync/atomic counter), Java action RETURNS Void handling, nanoflow doctype test cleanup, and enum parameter roundtrip test update — all unrelated to indirect sort entity refs. These appear to be from a shared development branch with PR #366. Each fix is clean and individually correct, but per CLAUDE.md scope guidelines they belong in separate PRs.


Positives

  • Parser and writer tests pin the exact BSON shape (DomainModels$IndirectEntityRef, Steps, Association, DestinationEntity) — no guessing at the format from reflection data
  • strings.EqualFold for sort direction comparison fixes a latent case-sensitivity bug ("DESC" from the visitor was previously silently ignored)
  • Builder test uses a real MockBackend with domain model data and asserts the full EntityRefSteps slice content
  • CrossAssociations path handles cross-module one-hop references correctly

@ako ako merged commit 5fbead4 into mendixlabs:main May 2, 2026
2 checks passed
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.

Preserve indirect entity references in retrieve sort items

3 participants