Skip to content

feat(adapters): honor real list-filter/query params across 37 adapters (query_select wiring) - #41

Merged
deblasis merged 2 commits into
mainfrom
feat/query-select-wiring
Aug 14, 2026
Merged

feat(adapters): honor real list-filter/query params across 37 adapters (query_select wiring)#41
deblasis merged 2 commits into
mainfrom
feat/query-select-wiring

Conversation

@deblasis

Copy link
Copy Markdown
Contributor

Wire the sweep's largest gap class (filter params accepted, silently
ignored) onto the query_select builtin. Each adapter maps its provider's
documented params to filter clauses applied before paging, envelope
unchanged (~210 params across 37 adapters):

  • Google: gmail (q/labelIds/includeSpamTrash default-false), gcalendar
    (timeMin/timeMax/iCalUID/showDeleted/orderBy=startTime with the real
    singleEvents!=true 400), gtasks (showCompleted/due*/completed*/q),
    ga4 (body-driven dimensionFilter/metricFilter trees via explicit-stack
    walk, orderBys multi-key sort, limit/offset after filtering), gsheets,
    youtube, photos, google-admin (14 params), drive (q), instagram
  • Apple + pinata: appstoreconnect (filters[...] param syntax),
    apple-searchads (selector conditions), apple-music, cloudkit, pinata
  • Cloud: aws-s3 (list-type/prefix/marker), cloudflare (per-resource
    filters), aws-iam-sts (PathPrefix/MaxItems — verified on resume)
  • Payments/ERP: stripe (10 params), plaid, zuora (ZOQL WHERE), avalara,
    qbo, xero, netsuite (SuiteQL predicates), workday (documented-only),
    psd2 (booking/date windows)
  • CRM/social/comms: servicenow (sysparm_query), marketo, zendesk,
    hubspot, github (13 params), twitter, sendgrid (query subset),
    thegraph, powerplatform ($filter), etherscan (topic/address filters),
    printful (status + filtered paging.total)

hn-style unchanged (the real API takes no query params); no params
invented anywhere — only documented provider params are honored.
Per-adapter READMEs updated. Gates: parse guard, QC boot, full suite,
adapter lint (91/91 clean), gofmt/vet.

Wire the sweep's largest gap class (filter params accepted, silently
ignored) onto the query_select builtin. Each adapter maps its provider's
documented params to filter clauses applied before paging, envelope
unchanged (~210 params across 37 adapters):

- Google: gmail (q/labelIds/includeSpamTrash default-false), gcalendar
  (timeMin/timeMax/iCalUID/showDeleted/orderBy=startTime with the real
  singleEvents!=true 400), gtasks (showCompleted/due*/completed*/q),
  ga4 (body-driven dimensionFilter/metricFilter trees via explicit-stack
  walk, orderBys multi-key sort, limit/offset after filtering), gsheets,
  youtube, photos, google-admin (14 params), drive (q), instagram
- Apple + pinata: appstoreconnect (filters[...] param syntax),
  apple-searchads (selector conditions), apple-music, cloudkit, pinata
- Cloud: aws-s3 (list-type/prefix/marker), cloudflare (per-resource
  filters), aws-iam-sts (PathPrefix/MaxItems — verified on resume)
- Payments/ERP: stripe (10 params), plaid, zuora (ZOQL WHERE), avalara,
  qbo, xero, netsuite (SuiteQL predicates), workday (documented-only),
  psd2 (booking/date windows)
- CRM/social/comms: servicenow (sysparm_query), marketo, zendesk,
  hubspot, github (13 params), twitter, sendgrid (query subset),
  thegraph, powerplatform ($filter), etherscan (topic/address filters),
  printful (status + filtered paging.total)

hn-style unchanged (the real API takes no query params); no params
invented anywhere — only documented provider params are honored.
Per-adapter READMEs updated. Gates: parse guard, QC boot, full suite,
adapter lint (91/91 clean), gofmt/vet.
…eviews

Three reviewers over the query_select wiring; all verified findings fixed:
- gcalendar: timeMin/timeMax are an overlap window (end > timeMin,
  start < timeMax, exclusive) — were both applied to start.dateTime;
  q no longer 500s on null description/location
- ga4: stringFilter honors caseSensitive (default false = insensitive);
  unknown dimension/metric/filter names now 400 INVALID_ARGUMENT
- netsuite: q implements the DOCUMENTED operator vocabulary (IS/IS_NOT,
  CONTAIN, START_WITH, ENDWITH, GREATER_OR_EQUAL..., ANY_OF, BETWEEN,
  AFTER/BEFORE/ON..., EMPTY) with OR groups; unparseable q 400s instead
  of returning the superset; default page size 1000
- servicenow: string ops case-insensitive like the real Table API;
  operator parsing anchored (state=IN_PROGRESS no longer mis-parses);
  invalid queries 400
- apple-searchads: multi-value EQUALS is OR (in-list), NOT_EQUALS
  not-in; reports apply selector.conditions + require startTime/endTime
- zuora: EQ/NE/IN/SW case-insensitive, EQ:null matches nulls; single
  filter[] limitation documented
- psd2: transactions require bookingStatus/dateFrom (400
  PARAMETER_MISSING-* per Berlin Group); test updated to the contract
- google-admin: users bare query matches givenName/familyName/email;
  groups support documented name=/name:{prefix}*/memberKey= forms
- stripe: lists sorted newest-first by default (charges, customers,
  payment_intents, refunds, payouts, transfers); non-numeric created
  400s parameter_invalid_integer
- avalara: unquoted digit/bool literals typed in $filter parsing
- thegraph: _not_in no longer inverted; adjacent list-valued _in and
  scalar _not_in bugs fixed with regression test

Gates: parse guard, QC boot, full suite, adapter lint 91/91, gofmt/vet.
@deblasis
deblasis merged commit cd2c8c6 into main Aug 14, 2026
1 check 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.

1 participant