Repository navigation
fix(lint): QUAL004 counts every catalog reference as a caller; published-service microflows get edges - #1746
Merged
Merged
Conversation
Every QUAL004 finding printed its location as `at M.M.NAV_Home`, and so did CONV001-010, the SEC rules and most other bundled Starlark rules: they pass `document_name=<x>.qualified_name`, while Location.QualifiedName() prefixes the module to DocumentName, which it takes to be the short name. The Go rule missing_translations does the same, and CONV018's module-level finding printed `at Sales.Sales`. QualifiedName() is the one place a location becomes a name (text, Markdown, SARIF, `lint -d`), so it now accepts both spellings: a DocumentName that already starts with "<module>." is returned as is (a Mendix document name cannot contain a dot, so the prefix is always the module), and a module-level finding naming the module itself prints the module once. Fixing the ~30 rule files instead would leave every project's stale `mxcli init` copies, and every user-written rule, still doubling. Verified: TestLocationQualifiedNameDoesNotRepeatTheModule (with controls for a document named like its module and a module name that prefixes the document's) and TestShippedRuleLocationPrintsTheModuleOnce (the shipped QUAL004 rule through the text formatter) both fail with `at Sales.Sales.Big_MF` when the change to linter.go is reverted. Found while reproducing #1484. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…m anywhere (#1484) A microflow started only from the navigation — a profile's home microflow, or a menu item's `call microflow` — was reported as "is not called from anywhere. Remove if unused", while `mxcli refs` listed its `home_page` / `menu_item` edge (upstream mendixlabs#1579; the 4 NAV_ findings left in #1639). Cause: orphaned_elements.star decided "has a caller" from its own copy of the reference vocabulary, MICROFLOW_ENTRY_KINDS. PAGE_ENTRY_KINDS had home_page and menu_item; the microflow list did not. It is the fourth time that list fell behind the catalog (datasource/action/calculate, schedule, settings/publish, event), so adding the two kinds would only reset the clock. Fix: the rule keeps no kind list. A microflow or page is used when any edge in the reference graph points at it — what `refs` and GRAPH_DEAD_ASSETS already read; no kind that targets a microflow or a page means anything but "this runs / opens it", so no exclusion list is needed either. Drift is guarded behaviourally: catalog.RefKinds is held complete against the RefKind constants, and TestQUAL004CountsEveryRefKind drives every one of them at a microflow, a nanoflow and a page through the shipped rule (an unreferenced microflow is the per-kind control), so a kind added later is tested the day it is declared and a reintroduced allowlist fails by name. The two catalog tests that pinned the old lists are replaced by it; `schedule` edges are among the kinds driven. Verification: - TestQUAL004CountsNavigationAsACaller (controls: an unreferenced microflow and page are still reported, an ACT_ microflow is still exempt) fails with "QUAL004 reports M.NAV_Home / M.NAV_Orders" when the rule change is reverted; TestQUAL004CountsEveryRefKind fails for every kind, and the RefKinds guard fails when a constant is left out. - Real 11.13 app (blank app + navigation from the repro), BASELINE binary with only the rule swapped: NAV_Home and NAV_Orders drop out of QUAL004; the unreferenced control microflow M.Unused and page M.ItemEdit are still reported; ACT_Entry still exempt. Repro: mdl-examples/bug-tests/qual004-1484-navigation-microflows.mdl. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ntication microflows dead (#1639) `mxcli refs Mod.Read_Drivers` said "no references found" for a microflow that is a published OData resource's `ReadMode: microflow`, and likewise for the service's `Authentication: (microflow X)`; `impact` agreed and QUAL004 advised "Remove if unused" — 35 of the reporter's backend's 43 QUAL004 findings. Half 1 of the issue (QUAL004 ignoring references the catalog already has) was, after the reporter's re-measurement, the navigation menu-item case alone; it is fixed by the #1484 commit, which makes the rule count every edge. This commit is half 2: the edges themselves. Cause: buildODataServices catalogued the service and emitted no edge for any microflow it names — entity-set read/change modes, published OData actions, the authentication microflow. Auditing the sibling services (every `*Microflow*QualifiedName()` in modelsdk/gen against the builders) found the same gap where the reader already has the name: a published REST service's authentication microflow, a business event service operation's handler (stored in business_events_data, dropped), and a consumed OData service's configuration / headers / error-handling microflows. Fix: the service builders collect one edge per distinct microflow (builder_service_refs.go) and buildReferences emits them, from the service (new source types PUBLISHED_ODATA_SERVICE, PUBLISHED_REST_SERVICE, BUSINESS_EVENT_SERVICE, CONSUMED_ODATA_SERVICE, equal to their objects ObjectType, catalog id in SourceId). Kinds are reused, not minted, so `show callers`, the analysis graph and QUAL004 need no list change: `publish` (a published service runs it), `event` (an event handler — entity or business event), `call` (the consumed service calls its configuration microflow, as a workflow calls its handlers). CatalogSchemaVersion 28 -> 29 so cached catalogs rebuild. Verification: - builder_service_refs_test.go pins each edge, the SourceId join, the dedup and the no-microflow modes; with the collection hooks reverted every edge test gets [] and GRAPH_DEAD_ASSETS lists Read_Rows and AuthenticateApiClient again (unreferenced control still listed). - Real 11.13 app, same model, baseline vs fixed binary: `refs` for the read, authentication and action microflows of a published OData service, a published REST service's authentication microflow and a business event handler goes from "no references found" to one publish/event row each; `show callers` names the service; QUAL004 and GRAPH_DEAD_ASSETS drop them; the unreferenced control is still reported. On ako/TestApp (Studio Pro reference) the three published OData actions gain `publish` edges. No Studio Pro document with a read or authentication microflow was at hand, so those two read paths are verified on mxcli-written documents (keys match generated/metamodel). Not fixed, same symptom, different mechanism (no reader or no table): published SOAP web services, import/export mapping custom-handler microflows, ProjectSecurity.SignInMicroflow, a microflow's ConcurrencyErrorMicroflow, the navigation not-found page. Repro: mdl-examples/bug-tests/catalog-1639-service-microflow-refs.mdl. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #1484 (mirror of mendixlabs#1579). Closes #1639.
Lint rule QUAL004 told users to remove live entry points ("is not called from anywhere — Remove if unused"). Three commits: the location fix found on the way, then one per issue.
Lint locations repeated the module (
at M.M.NAV_Home)Cause:
Location.QualifiedName()(mdl/linter/linter.go) prefixed the module toDocumentName, and ~30 bundled Starlark rules plusmissing_translationspass the qualified name there. CONV018's module-level finding printedSales.Sales.Fix: in that one function (text, Markdown, SARIF and
lint -dall go through it): a name already starting with<module>.is returned unchanged, and a module-level finding prints just the module. Fixing it there also covers stalemxcli initcopies and user-written rules. Tests with controls for a document named like its module and a module name that prefixes the document name.#1484 — a navigation-started microflow reported as unused
Cause:
orphaned_elements.starkept its ownMICROFLOW_ENTRY_KINDSlist, missinghome_pageandmenu_item(the page list had both).Fix: no kind list at all: a microflow, nanoflow, rule or page counts as used when any edge in the catalog's reference graph points at it, which is what
mxcli refsandGRAPH_DEAD_ASSETSalready mean. Drift is pinned by tests:catalog.RefKindslists every kind andTestEveryObjectTypeConstantIsInAPublishedListties it to the RefKind constants;TestQUAL004CountsEveryRefKindsends every kind at a microflow, a nanoflow and a page through the shipped rule, so a reintroduced allowlist fails naming the kind.#1639 — published-service microflows have no catalog edge
Half 1 (QUAL004 ignoring references the catalog has) reduced, after the reporter's re-measure, to the menu-item case fixed above.
Half 2, cause:
buildODataServicesemitted no edge for any microflow a service names.Fix:
builder_service_refs.go: one edge per distinct microflow, sourced from the service, with existing kinds soshow callers, the analysis graph and QUAL004 need no list changes — published OData (publish: read/insert/update/delete, published actions, authentication), published REST (publish: authentication), business event service (event: operation handler), consumed OData (call: configuration, headers, error handling).CatalogSchemaVersion28 → 29 so cached catalogs rebuild.Verified
at Sales.Sales.Big_MF; the edge tests get[]andGRAPH_DEAD_ASSETSlists the service microflows again. Controls: an unreferenced microflow and page are still reported;ACT_stays exempt.refsfor OData read/authentication/action microflows, a REST authentication microflow and a business event handler go from "no references found" to one row each. On TestApp (Studio Pro-authored), the 3 published OData actions getpublishedges.go test ./...,go vet, gofmt and CI's doc checks pass with all five of this batch's branches merged onto main. Bug-testsqual004-1484-navigation-microflows.mdl,catalog-1639-service-microflow-refs.mdl; findings recorded; starlark-rules and catalog-schema docs, write-lint-rules skill updated.generated/metamodel); consumed OData edges only by unit test (authoring needs a reachable$metadata).Noticed, not fixed
Edges still missing (different mechanism: no reader or no table): published SOAP operations and their header-authentication microflow; import/export mapping custom-handler microflows;
ProjectSecurity.SignInMicroflow; a microflow'sConcurrencyErrorMicroflow; the navigation's not-found page (stored, but no edge, so a page used only as the 404 page can still be reported); document-template data sources and app services. Also: QUAL004's page message ("is not shown from any microflow") is out of date now that navigation counts.🤖 Generated with Claude Code