Skip to content

fix: a filter survives only where the field it selects on does - #106

Merged
ShocOne merged 1 commit into
mainfrom
fix/filters-survive-binding
Aug 15, 2026
Merged

fix: a filter survives only where the field it selects on does#106
ShocOne merged 1 commit into
mainfrom
fix/filters-survive-binding

Conversation

@ShocOne

@ShocOne ShocOne commented Aug 15, 2026

Copy link
Copy Markdown
Member

Two defects in #105, both found by re-emitting Jamf Pro, ThousandEyes and
GitHub rather than by any test. The fictional fixtures produce neither shape.

A filter outlived the field it selects on

Filters are derived from the listed object in derive.go, which runs before
sdkbind prunes. Binding deletes what the SDK cannot carry, and the item model
is built from what survives — so a filter over a deleted field compared against
a model field that no longer existed:

internal/services/datasources/account_groups/v1/account_group/read.go:39:70:
  item.AccountToken undefined (type *AccountGroupItemModel has no field or method AccountToken)

Emission now reconciles the two, keeping only the filters whose field survived.
Derivation still declares the intent; emission is the only place that knows
what binding left.

An integer id was declared as a string

The id short-circuit hard-coded data.ID.ValueString(), which was correct only
while the argument was the always-string filter_value. A filter takes the type
of the field it selects on, and Jamf Pro keys api_integration by an integer:

internal/services/datasources/api_integrations/v1/api_integration/read.go:59:17:
  data.ID.ValueString undefined (type types.Int64 has no field or method ValueString)

The parameter is built through buildCallPlan now — the same path the resource
read and the lookup datasource already use, which converts the attribute to the
parameter's type and declares any import that needs. readPlanWithoutParams and
the hand-written IDParamDecl are deleted; there is nothing left that assumed
the id was a string.

Re-measured

All three trees regenerate and pass postcheck — go mod tidy, go build,
go vet:

Document Resources Data sources List resources Actions
Jamf Pro 76 211 39 101
GitHub 59 323 23 77
ThousandEyes 35 95 11 51
Total 170 629 73 229

README.md carried 161 / 272 / 69 / 210. Actions moving to 229 is the
lone-write change in #104; the rest predates this work and was simply stale, so
the line is re-measured rather than adjusted.

Verification

Added a regression test that deletes one field binding and proves the filter
goes with it — out of the schema, the model and the match — while the filters
whose fields survived are untouched. make check passes at 91.3%.

The load-bearing check remains generating the three documents, which is what
caught both of these. Neither would have been found by the fixtures.

🤖 Generated with Claude Code

Emitting the three pilot documents refused two shapes the fictional
fixtures never produce.

A filter is derived from the listed object before binding runs, and
binding deletes what the SDK cannot carry. Where a field went, the match
still compared against a model field that no longer existed and the tree
would not build. Filters are now reconciled against the item nodes that
survived.

An id filter takes the type of the field it selects on, and an integer
key is as common as a string one. The by-id parameter was declared as
ValueString regardless, which does not compile against a types.Int64
field. It is built through the shared call plan now, which converts.

Counts in the readme are re-measured across all three trees rather than
carried forward.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@ShocOne
ShocOne merged commit 8c68058 into main Aug 15, 2026
2 checks passed
@ShocOne
ShocOne deleted the fix/filters-survive-binding branch August 15, 2026 13:28
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