atlas_engine 0.6.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (18) hide show
  1. checksums.yaml +4 -4
  2. data/app/countries/atlas_engine/gg/address_validation/validators/full_address/exclusions/city.rb +32 -0
  3. data/app/countries/atlas_engine/gg/country_profile.yml +4 -0
  4. data/app/countries/atlas_engine/gg/validation_transcriber/address_parser.rb +43 -0
  5. data/app/models/atlas_engine/address_validation/es/datastore.rb +23 -0
  6. data/app/models/atlas_engine/address_validation/validators/full_address/concern_builder.rb +0 -4
  7. data/app/models/atlas_engine/address_validation/validators/full_address/unmatched_field_concern_builder.rb +1 -1
  8. data/app/models/atlas_engine/address_validation/validators/predicates/country/valid_for_zip.rb +1 -1
  9. data/app/models/atlas_engine/address_validation/validators/predicates/province/valid_for_country.rb +1 -1
  10. data/app/models/atlas_engine/address_validation/validators/predicates/street/building_number_in_address1.rb +1 -1
  11. data/app/models/atlas_engine/address_validation/validators/predicates/street/building_number_in_address1_or_address2.rb +1 -1
  12. data/app/models/atlas_engine/address_validation/validators/predicates/zip/valid_for_country.rb +1 -1
  13. data/app/models/atlas_engine/address_validation/validators/predicates/zip/valid_for_province.rb +1 -1
  14. data/app/models/atlas_engine/elasticsearch/error.rb +19 -0
  15. data/app/models/atlas_engine/elasticsearch/repository.rb +8 -8
  16. data/lib/atlas_engine/version.rb +1 -1
  17. metadata +5 -3
  18. data/app/models/atlas_engine/address_validation/validators/full_address/unknown_zip_for_address_concern_builder.rb +0 -34
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 56b5b41a624c3481954aadfa0101c9883dfe3479a3cdec373f8ecccab8bae879
4
- data.tar.gz: 73ee021ecf5d8357ae8f000df7e963e7504153fdc3b7bb98f188445aa8cd7989
3
+ metadata.gz: 9948b64010b57506c90e07bf0fc324c7ad158112169375aa1ac1f7053850a9be
4
+ data.tar.gz: 872cd26b540c96af7a777b044a4af20cce6d1b7df5569f0b3cd7aaf999fb1847
5
5
  SHA512:
6
- metadata.gz: b93dee8561c73619222ca4a4e803fb2f911b3149955c5b1af7803990318a7ebd36e781c41643cf3076197f579833e9c2d361e8e4550a9d2d3de628d8e7819ef7
7
- data.tar.gz: f2f593c6e2a7849dae6dce6a52d9402ce7d907a90511664d1218133b5d4a501b5ae98a26e54a06412c3fb37e3dc74c75ae17c575ae24fa4805c02ad888467d21
6
+ metadata.gz: d8ea33678c4c924fb202cecf027e4796892430c35394233c0a971474166b71a10881a6ddc2cc6056d7f66df6b225a63cfdafe18b5590327035d19f3f4e70cf99
7
+ data.tar.gz: 30d5b8b914d14f4fd6871228435383ff90499e25617af0c7dc5a6a5580fbf4005854f2189034712f4030001878be8c6ee42223e5b94a1890b2a14f8be80e0dc3
@@ -0,0 +1,32 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ module AtlasEngine
5
+ module Gg
6
+ module AddressValidation
7
+ module Validators
8
+ module FullAddress
9
+ module Exclusions
10
+ class City <
11
+ AtlasEngine::AddressValidation::Validators::FullAddress::Exclusions::ExclusionBase
12
+ extend T::Sig
13
+ class << self
14
+ sig do
15
+ override.params(
16
+ candidate: AtlasEngine::AddressValidation::Candidate,
17
+ address_comparison: AtlasEngine::AddressValidation::Validators::FullAddress::AddressComparison,
18
+ )
19
+ .returns(T::Boolean)
20
+ end
21
+ def apply?(candidate, address_comparison)
22
+ # If the candidate city is already present in the parsings
23
+ address_comparison.parsings.parsings.pluck(:city)&.include?(candidate.component(:city)&.value&.first)
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -3,5 +3,9 @@ validation:
3
3
  enabled: true
4
4
  default_matching_strategy: es
5
5
  has_provinces: false
6
+ address_parser: AtlasEngine::Gg::ValidationTranscriber::AddressParser
6
7
  restrictions:
7
8
  - class: AtlasEngine::Gg::AddressValidation::Validators::FullAddress::Restrictions::UnsupportedCity
9
+ exclusions:
10
+ city:
11
+ - AtlasEngine::Gg::AddressValidation::Validators::FullAddress::Exclusions::City
@@ -0,0 +1,43 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ module AtlasEngine
5
+ module Gg
6
+ module ValidationTranscriber
7
+ class AddressParser < AtlasEngine::ValidationTranscriber::AddressParserBase
8
+ private
9
+
10
+ CITY = %r{
11
+ (?<city>
12
+ st\.?\s?saviour[']?[s]?|
13
+ st\.?\s?sampson[']?[s]?|
14
+ st\.?\s?andrew[']?[s]?|
15
+ st\.?\s?martin[']?[s]?|
16
+ st\.?\s?peter[']?[s]?\s?port|
17
+ st\.?\s?peter[']?[s]?|
18
+ st\.?\s?pierre\s?du\s?bois|
19
+ vale|
20
+ torteval|
21
+ castel|
22
+ forest
23
+ )
24
+ }ix
25
+
26
+ sig { returns(T::Array[Regexp]) }
27
+ def country_regex_formats
28
+ @country_regex_formats ||= [
29
+ /^#{BUILDING_NAME},\s+#{CITY}$/,
30
+ /^#{BUILDING_NAME},\s+#{STREET_NO_COMMAS},\s+#{CITY}$/,
31
+ /^#{BUILDING_NAME},\s+#{STREET_NO_COMMAS}$/,
32
+ /^#{NUMERIC_ONLY_BUILDING_NUM}?\s+#{STREET_NO_COMMAS},\s+#{CITY}$/,
33
+ /^#{UNIT_TYPE}\s+#{UNIT_NUM_NO_HYPHEN},\s+#{BUILDING_NAME},\s+#{CITY}$/,
34
+ /^#{CITY}$/,
35
+ /^#{NUMERIC_ONLY_BUILDING_NUM}?\s+#{STREET_NO_COMMAS}$/,
36
+ /^#{BUILDING_NAME}$/,
37
+ /^#{STREET_NO_COMMAS}$/,
38
+ ]
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -128,6 +128,9 @@ module AtlasEngine
128
128
  end
129
129
  Token::Sequence.new(tokens: tokens, raw_value: city_value)
130
130
  end
131
+ rescue Elasticsearch::Error => e
132
+ log_elasticsearch_error(error: e, method: "city_sequence")
133
+ Token::Sequence.new(tokens: [], raw_value: city_value)
131
134
  end
132
135
 
133
136
  sig { returns(T::Array[T::Hash[String, T.untyped]]) }
@@ -135,6 +138,9 @@ module AtlasEngine
135
138
  measure_es_validation_request_time(method: "full_address_candidates") do
136
139
  repository.search(query_builder.full_address_query)
137
140
  end
141
+ rescue Elasticsearch::Error => e
142
+ log_elasticsearch_error(error: e, method: "full_address_candidates")
143
+ []
138
144
  end
139
145
 
140
146
  sig { returns(T::Array[Token::Sequence]) }
@@ -154,6 +160,9 @@ module AtlasEngine
154
160
  end
155
161
  end
156
162
  end
163
+ rescue Elasticsearch::Error => e
164
+ log_elasticsearch_error(error: e, method: "street_sequence")
165
+ [Token::Sequence.new(tokens: [], raw_value: "")]
157
166
  end
158
167
 
159
168
  sig { params(candidates: T::Array[Candidate]).void }
@@ -165,6 +174,8 @@ module AtlasEngine
165
174
  end
166
175
 
167
176
  TermVectors.new(term_vectors_hashes: candidate_term_vectors, candidates: candidates).set_candidate_sequences
177
+ rescue Elasticsearch::Error => e
178
+ log_elasticsearch_error(error: e, method: "term_vectors")
168
179
  end
169
180
 
170
181
  sig { params(candidates: T::Array[Candidate]).returns(T::Hash[String, T.untyped]) }
@@ -190,6 +201,18 @@ module AtlasEngine
190
201
  )
191
202
  end
192
203
 
204
+ sig { params(error: Elasticsearch::Error, method: String).void }
205
+ def log_elasticsearch_error(error:, method:)
206
+ log_error("Elasticsearch error: #{error.message}")
207
+ StatsD.increment(
208
+ "AddressValidation.elasticsearch_error",
209
+ tags: {
210
+ country: country_code,
211
+ method:,
212
+ },
213
+ )
214
+ end
215
+
193
216
  sig { params(future: T.nilable(Concurrent::Promises::Future), method: String).void }
194
217
  def log_future_state_on_join(future:, method:)
195
218
  state = future&.state || :unsubmitted
@@ -109,10 +109,6 @@ module AtlasEngine
109
109
  concern = InvalidZipConcernBuilder.for(address, suggestion_ids)
110
110
  return concern if concern
111
111
 
112
- if :province_code.in?(matched_components) && :city.in?(matched_components)
113
- return UnknownZipForAddressConcernBuilder.new(address).build(suggestion_ids)
114
- end
115
-
116
112
  build_default_concern
117
113
  end
118
114
 
@@ -56,7 +56,7 @@ module AtlasEngine
56
56
 
57
57
  sig { returns(String) }
58
58
  def message
59
- "Enter a valid #{COMPONENTS_TO_LABELS[component]} for #{valid_address_component_values.join(", ")}"
59
+ country.field(key: field_name).error(code: :unknown_for_address).to_s
60
60
  end
61
61
 
62
62
  sig { returns(Symbol) }
@@ -28,7 +28,7 @@ module AtlasEngine
28
28
  sig { params(suggestion: Suggestion).returns(Concern) }
29
29
  def build_concern(suggestion)
30
30
  Concern.new(
31
- field_names: [:country, :zip],
31
+ field_names: [:country],
32
32
  code: :country_invalid_for_zip,
33
33
  type: T.must(Concern::TYPES[:error]),
34
34
  type_level: 1,
@@ -24,7 +24,7 @@ module AtlasEngine
24
24
  sig { returns(Concern) }
25
25
  def build_concern
26
26
  Concern.new(
27
- field_names: [:province, :country],
27
+ field_names: [:province],
28
28
  code: :province_invalid,
29
29
  type: T.must(Concern::TYPES[:error]),
30
30
  type_level: 3,
@@ -24,7 +24,7 @@ module AtlasEngine
24
24
  sig { returns(Concern) }
25
25
  def build_concern
26
26
  Concern.new(
27
- field_names: [:address1, :country],
27
+ field_names: [:address1],
28
28
  code: :missing_building_number,
29
29
  type: T.must(Concern::TYPES[:warning]),
30
30
  type_level: 1,
@@ -22,7 +22,7 @@ module AtlasEngine
22
22
  sig { returns(Concern) }
23
23
  def build_concern
24
24
  Concern.new(
25
- field_names: [:address1, :address2, :country],
25
+ field_names: [:address1, :address2],
26
26
  code: :missing_building_number,
27
27
  type: T.must(Concern::TYPES[:warning]),
28
28
  type_level: 3,
@@ -26,7 +26,7 @@ module AtlasEngine
26
26
  sig { returns(Concern) }
27
27
  def build_concern
28
28
  Concern.new(
29
- field_names: [:zip, :country],
29
+ field_names: [:zip],
30
30
  code: :zip_invalid_for_country,
31
31
  type: T.must(Concern::TYPES[:error]),
32
32
  type_level: 3,
@@ -29,7 +29,7 @@ module AtlasEngine
29
29
  sig { returns(Concern) }
30
30
  def build_concern
31
31
  Concern.new(
32
- field_names: [:zip, :country, :province],
32
+ field_names: [:zip],
33
33
  code: :zip_invalid_for_province,
34
34
  type: T.must(Concern::TYPES[:error]),
35
35
  type_level: 3,
@@ -0,0 +1,19 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module AtlasEngine
5
+ module Elasticsearch
6
+ class Error < StandardError
7
+ extend T::Sig
8
+
9
+ sig { params(message: String, cause: T.nilable(Exception)).void }
10
+ def initialize(message, cause = nil)
11
+ super(message)
12
+ @cause = cause
13
+ end
14
+
15
+ sig { returns(T.nilable(Exception)) }
16
+ attr_reader :cause
17
+ end
18
+ end
19
+ end
@@ -133,8 +133,8 @@ module AtlasEngine
133
133
  response = client.post(path, query, {})
134
134
 
135
135
  response.body
136
- rescue ::Elastic::Transport::Transport::Error
137
- { "hits" => { "hits" => [] } }
136
+ rescue ::Elastic::Transport::Transport::Error => e
137
+ raise Elasticsearch::Error.new(e.message, e)
138
138
  end
139
139
 
140
140
  sig { override.params(query: T::Hash[String, T.untyped]).returns(T::Hash[String, T.untyped]) }
@@ -143,8 +143,8 @@ module AtlasEngine
143
143
  response = client.post(path, query, {})
144
144
 
145
145
  response.body
146
- rescue ::Elastic::Transport::Transport::Error
147
- { "tokens" => [] }
146
+ rescue ::Elastic::Transport::Transport::Error => e
147
+ raise Elasticsearch::Error.new(e.message, e)
148
148
  end
149
149
 
150
150
  sig { override.params(query: T::Hash[String, T.untyped]).returns(T::Hash[String, T.untyped]) }
@@ -153,8 +153,8 @@ module AtlasEngine
153
153
  response = client.post(path, query, {})
154
154
 
155
155
  response.body
156
- rescue ::Elastic::Transport::Transport::Error
157
- { "docs" => [] }
156
+ rescue ::Elastic::Transport::Transport::Error => e
157
+ raise Elasticsearch::Error.new(e.message, e)
158
158
  end
159
159
 
160
160
  sig { override.params(id: T.any(String, Integer)).returns(T::Hash[String, T.untyped]) }
@@ -163,8 +163,8 @@ module AtlasEngine
163
163
  response = client.get(path, nil, {})
164
164
 
165
165
  response.body["_source"]
166
- rescue ::Elastic::Transport::Transport::Error
167
- {}
166
+ rescue ::Elastic::Transport::Transport::Error => e
167
+ raise Elasticsearch::Error.new(e.message, e)
168
168
  end
169
169
 
170
170
  sig { override.params(post_address: PostAddressData).returns(T::Hash[Symbol, T.untyped]) }
@@ -2,5 +2,5 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module AtlasEngine
5
- VERSION = "0.6.0"
5
+ VERSION = "0.7.0"
6
6
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: atlas_engine
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shopify
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-02-26 00:00:00.000000000 Z
11
+ date: 2024-03-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: annex_29
@@ -305,8 +305,10 @@ files:
305
305
  - app/countries/atlas_engine/gb/country_profile.yml
306
306
  - app/countries/atlas_engine/gb/validation_transcriber/full_address_parser.rb
307
307
  - app/countries/atlas_engine/gb/validation_transcriber/parsed_address.rb
308
+ - app/countries/atlas_engine/gg/address_validation/validators/full_address/exclusions/city.rb
308
309
  - app/countries/atlas_engine/gg/address_validation/validators/full_address/restrictions/unsupported_city.rb
309
310
  - app/countries/atlas_engine/gg/country_profile.yml
311
+ - app/countries/atlas_engine/gg/validation_transcriber/address_parser.rb
310
312
  - app/countries/atlas_engine/ie/country_profile.yml
311
313
  - app/countries/atlas_engine/it/address_importer/corrections/open_address/city_corrector.rb
312
314
  - app/countries/atlas_engine/it/address_importer/corrections/open_address/province_corrector.rb
@@ -494,7 +496,6 @@ files:
494
496
  - app/models/atlas_engine/address_validation/validators/full_address/suggestion_builder.rb
495
497
  - app/models/atlas_engine/address_validation/validators/full_address/unknown_address_concern_builder.rb
496
498
  - app/models/atlas_engine/address_validation/validators/full_address/unknown_province_concern_builder.rb
497
- - app/models/atlas_engine/address_validation/validators/full_address/unknown_zip_for_address_concern_builder.rb
498
499
  - app/models/atlas_engine/address_validation/validators/full_address/unmatched_field_concern_builder.rb
499
500
  - app/models/atlas_engine/address_validation/validators/full_address/unsupported_script_result.rb
500
501
  - app/models/atlas_engine/address_validation/validators/full_address/zip_comparison.rb
@@ -530,6 +531,7 @@ files:
530
531
  - app/models/atlas_engine/country_repository.rb
531
532
  - app/models/atlas_engine/elasticsearch/client.rb
532
533
  - app/models/atlas_engine/elasticsearch/client_interface.rb
534
+ - app/models/atlas_engine/elasticsearch/error.rb
533
535
  - app/models/atlas_engine/elasticsearch/repository.rb
534
536
  - app/models/atlas_engine/elasticsearch/repository_interface.rb
535
537
  - app/models/atlas_engine/elasticsearch/response.rb
@@ -1,34 +0,0 @@
1
- # typed: true
2
- # frozen_string_literal: true
3
-
4
- module AtlasEngine
5
- module AddressValidation
6
- module Validators
7
- module FullAddress
8
- class UnknownZipForAddressConcernBuilder
9
- extend T::Sig
10
- attr_reader :address
11
-
12
- sig { params(address: AbstractAddress).void }
13
- def initialize(address)
14
- @address = address
15
- end
16
-
17
- sig { params(suggestion_ids: T::Array[String]).returns(Concern) }
18
- def build(suggestion_ids = [])
19
- message = "Enter a valid ZIP for #{address.address1}, #{address.city}"
20
-
21
- Concern.new(
22
- code: :zip_inconsistent,
23
- field_names: [:zip],
24
- message: message,
25
- type: T.must(Concern::TYPES[:warning]),
26
- type_level: 3,
27
- suggestion_ids: suggestion_ids,
28
- )
29
- end
30
- end
31
- end
32
- end
33
- end
34
- end