Skip to content

[PDE-3241] accept dot notation - #18

Merged
jazziining merged 16 commits into
mainfrom
PDE-3241/accept-dot-notation
May 20, 2026
Merged

jazziining merged 16 commits into
mainfrom
PDE-3241/accept-dot-notation

Conversation

@jazziining

@jazziining jazziining commented May 16, 2026

Copy link
Copy Markdown
Contributor

Summary
Enhance the Payrix search query builder to support nested field paths using dot notation syntax

Changes

  • Added support for nested search fields using dot notation:

"merchant.entity.login.division"

  • Improve timeout to be 60 seconds

Testing
Current search query should continue to work, add the following code in bin/console

cad_options = {:region=>:ca, :api_key=>API_KEY}
start_date = Time.now - (8 * 24 * 60 * 60)
end_date = Time.now
filter = ::Payrix::Search.and(
  ::Payrix::Search.greater(:returned, start_date.strftime('%Y%m%d').to_i),
  ::Payrix::Search.less(:returned, end_date.strftime('%Y%m%d').to_i),
)
::Payrix::Txn.list(filter, cad_options).auto_paging_map(&:id)
  • Run bin/console, it should return a list of txn ids

New search query should work, add the following code in bin/console

cad_options = {:region=>:ca, :api_key=>API_KEY}
start_date = Time.now - (8 * 24 * 60 * 60)
end_date = Time.now
filter = ::Payrix::Search.and(
  ::Payrix::Search.equals('merchant.entity.login.division', DIVISION_ID),
  ::Payrix::Search.greater(:returned, start_date.strftime('%Y%m%d').to_i),
  ::Payrix::Search.less(:returned, end_date.strftime('%Y%m%d').to_i),
)
::Payrix::Txn.list(filter, cad_options).auto_paging_map(&:id)
  • Run bin/console, it should return a list of txn ids

@jazziining jazziining self-assigned this May 16, 2026
@jazziining jazziining added the enhancement New feature or request label May 16, 2026
@jazziining
jazziining force-pushed the PDE-3241/accept-dot-notation branch from b490dd7 to 7f737b2 Compare May 16, 2026 04:51
Comment thread lib/payrix/http/request.rb Outdated

connection.headers = headers
connection.options.timeout = timeout
connection.options.timeout = 60

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have been experiencing timeout issues with certain Payrix requests. When testing via curl, some requests can still fail even after ~120s. Payrix suggested that including the division ID may improve query performance, and initial testing shows response times improving to ~20s.

To improve reliability and accommodate slower queries, I am increasing the request timeout to 60s for now.

parts
.map { |part| "[#{Payrix::Util.camel_case(part)}]" }
.join
end

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The original implementation always wrapped the key with an [], which could lead to double-wrapping when the field was already partially formatted.

The goal of this change is to treat string inputs using dot notation (e.g. "merchant.entity.login.division") as a structured field path. These strings are parsed into an array of segments and then consistently formatted into the expected bracketed query structure.

This ensures:

  • Symbol inputs remain supported for simple fields
  • Dot notation strings are correctly parsed into nested fields
  • Do not unintentionally double-wrapped nested fields

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Enhances the Payrix search query builder to support nested field paths via dot-notation (e.g., "merchant.entity.login.division") and adjusts HTTP request timeout behavior.

Changes:

  • Add dot-notation rendering for search fields in Payrix::RequestOptions::Search::Atom.
  • Update Faraday request timeout configuration to 60 seconds.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
lib/payrix/request_options/search/atom.rb Adds dot-notation support by rendering nested field paths into bracketed query syntax.
lib/payrix/http/request.rb Changes Faraday timeout configuration (currently hard-codes request timeout to 60s).
Comments suppressed due to low confidence (1)

lib/payrix/request_options/search/atom.rb:66

  • Dot-notation fields are split on '.', but there’s no validation that each segment is non-empty. Inputs like "merchant..division" or ".division" will produce empty path components (e.g., "[]") in the rendered query, which is very likely to generate invalid SEARCH filters. Consider tightening validate_field (only when the field is a dot-notation String) to reject strings with empty segments.
        def rendered_field(prefix)
          return Payrix::Util.camel_case(@field.to_s) unless @field.is_a?(String) && @field.include?('.')

          dot_field(prefix.empty?)
        end

        def dot_field(unprefixed)
          parts = @field.split('.').map { |part| Payrix::Util.camel_case(part) }


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread lib/payrix/http/request.rb Outdated
Comment on lines 19 to 20
connection.options.timeout = 60
connection.options.open_timeout = timeout
Comment thread lib/payrix/request_options/search/atom.rb
@jazziining
jazziining requested a review from Copilot May 18, 2026 03:55
@jazziining
jazziining requested a review from pdmholden May 18, 2026 03:57
@jazziining
jazziining marked this pull request as ready for review May 18, 2026 03:57

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

end
end

context 'when the field is dot notation with empty segments at the binning' do
end
end

context 'when the field is a dotted string and the prefix is a non empty string' do
include Singleton

def send_http(method, base_url, endpoint, data = {}, headers = {}, timeout = 30)
def send_http(method, base_url, endpoint, data = {}, headers = {}, timeout = 60)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wait, what?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some queries are taking over 20 seconds, so I felt that 30 seconds might still lead to timeouts. That’s why I increased it to 60 seconds.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not convinced we should do that, but I'll leave it to you.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can reduce it to 30 seconds first and see how the query performs, then increase it again if we still encounter timeouts.

"#{field}[#{@operator}]=#{@value}"
if prefix.empty?
"#{formatted_field}[#{@operator}]=#{@value}"
elsif formatted_field.start_with?('[')

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's this branch for?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so the dot notation field will be formatted to something like [merchant][entity][login][division][equals] when it formatted to something start with [ then we do not want to add an outter [].

@pdmholden pdmholden left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question: why do we need to accept dot notation?

I think we should bump the version number to 1.2.0. This is not a breaking change, but it is more than a patch. We need to resume updating the version number, which we haven't done in three years.

include Singleton

def send_http(method, base_url, endpoint, data = {}, headers = {}, timeout = 30)
def send_http(method, base_url, endpoint, data = {}, headers = {}, timeout = 60)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not convinced we should do that, but I'll leave it to you.

@jazziining

Copy link
Copy Markdown
Contributor Author

Question: why do we need to accept dot notation?

I think we should bump the version number to 1.2.0. This is not a breaking change, but it is more than a patch. We need to resume updating the version number, which we haven't done in three years.

Our current implementation only accepts a single field for filtering, represented as a symbol or string:

::Payrix::Search.less(:returned, end_date.strftime('%Y%m%d').to_i)

Here, :returned is the field and end_date is the value we’re matching against.

The division id filter is different because it’s a nested field:

merchant[entity][login][division][equals]=p1_div_

Since this is not a single symbol or string, we would need to support either dot notation like:
'merchant.entity.login.division'
or bracket notation like:
'[merchant][entity][login][division]'.
That would allow us to do something like:
::Payrix::Search.equals('merchant.entity.login.division', DIVISION_ID),


Also, I agree with the version suggestion

@jazziining
jazziining force-pushed the PDE-3241/accept-dot-notation branch from 6cf0770 to 61e2cc8 Compare May 19, 2026 21:22

@pdmholden pdmholden left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you update the version.rb? 🙏

@pdmholden pdmholden left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Everything works according to the test plan. I regret to acknowledge that the 60s timeout may be necessary for the US server. 😭

For the record, I tested with production for both :ca and :us regions.

include Singleton

def send_http(method, base_url, endpoint, data = {}, headers = {}, timeout = 30)
def send_http(method, base_url, endpoint, data = {}, headers = {}, timeout = 60)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not approve of this. LOL.

Comment thread lib/payrix/version.rb Outdated

module Payrix
VERSION = '1.0.0'
VERSION = '1.2.0'

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, maybe this should be 1.1.0. I don't know why I thought it should be 1.2.0. 🤦

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I wasn't thinking either. 🙏 ♻️

@jazziining
jazziining force-pushed the PDE-3241/accept-dot-notation branch from f591f02 to 74f7ac1 Compare May 19, 2026 22:29
@jazziining
jazziining merged commit c6285fd into main May 20, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants