atlas_engine 0.5.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/countries/atlas_engine/gg/address_validation/validators/full_address/exclusions/city.rb +32 -0
- data/app/countries/atlas_engine/gg/country_profile.yml +4 -0
- data/app/countries/atlas_engine/gg/validation_transcriber/address_parser.rb +43 -0
- data/app/models/atlas_engine/address_validation/candidate.rb +3 -2
- data/app/models/atlas_engine/address_validation/es/candidate_selector.rb +12 -12
- data/app/models/atlas_engine/address_validation/es/datastore.rb +23 -0
- data/app/models/atlas_engine/address_validation/es/validators/full_address.rb +9 -10
- data/app/models/atlas_engine/address_validation/es/validators/full_address_street.rb +1 -1
- data/app/models/atlas_engine/address_validation/validators/full_address/candidate_result.rb +20 -20
- data/app/models/atlas_engine/address_validation/validators/full_address/candidate_result_base.rb +4 -6
- data/app/models/atlas_engine/address_validation/validators/full_address/concern_builder.rb +7 -6
- data/app/models/atlas_engine/address_validation/validators/full_address/invalid_zip_concern_builder.rb +6 -2
- data/app/models/atlas_engine/address_validation/validators/full_address/{invalid_zip_for_country_concern.rb → invalid_zip_for_country_concern_builder.rb} +14 -13
- data/app/models/atlas_engine/address_validation/validators/full_address/{invalid_zip_for_province_concern.rb → invalid_zip_for_province_concern_builder.rb} +15 -15
- data/app/models/atlas_engine/address_validation/validators/full_address/no_candidate_result.rb +2 -4
- data/app/models/atlas_engine/address_validation/validators/full_address/relevant_components.rb +9 -13
- data/app/models/atlas_engine/address_validation/validators/full_address/{unknown_address_concern.rb → unknown_address_concern_builder.rb} +11 -4
- data/app/models/atlas_engine/address_validation/validators/full_address/unknown_province_concern_builder.rb +38 -0
- data/app/models/atlas_engine/address_validation/validators/full_address/{unmatched_field_concern.rb → unmatched_field_concern_builder.rb} +18 -10
- data/app/models/atlas_engine/address_validation/validators/full_address/unsupported_script_result.rb +1 -1
- data/app/models/atlas_engine/address_validation/validators/predicates/country/valid_for_zip.rb +1 -1
- data/app/models/atlas_engine/address_validation/validators/predicates/province/valid_for_country.rb +1 -1
- data/app/models/atlas_engine/address_validation/validators/predicates/street/building_number_in_address1.rb +1 -1
- data/app/models/atlas_engine/address_validation/validators/predicates/street/building_number_in_address1_or_address2.rb +1 -1
- data/app/models/atlas_engine/address_validation/validators/predicates/zip/valid_for_country.rb +1 -1
- data/app/models/atlas_engine/address_validation/validators/predicates/zip/valid_for_province.rb +1 -1
- data/app/models/atlas_engine/elasticsearch/error.rb +19 -0
- data/app/models/atlas_engine/elasticsearch/repository.rb +8 -8
- data/lib/atlas_engine/version.rb +1 -1
- metadata +10 -11
- data/app/models/atlas_engine/address_validation/candidate_tuple.rb +0 -15
- data/app/models/atlas_engine/address_validation/session.rb +0 -47
- data/app/models/atlas_engine/address_validation/validators/full_address/result_updater.rb +0 -42
- data/app/models/atlas_engine/address_validation/validators/full_address/unknown_province_concern.rb +0 -38
- data/app/models/atlas_engine/address_validation/validators/full_address/unknown_zip_for_address_concern.rb +0 -32
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9948b64010b57506c90e07bf0fc324c7ad158112169375aa1ac1f7053850a9be
|
4
|
+
data.tar.gz: 872cd26b540c96af7a777b044a4af20cce6d1b7df5569f0b3cd7aaf999fb1847
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d8ea33678c4c924fb202cecf027e4796892430c35394233c0a971474166b71a10881a6ddc2cc6056d7f66df6b225a63cfdafe18b5590327035d19f3f4e70cf99
|
7
|
+
data.tar.gz: 30d5b8b914d14f4fd6871228435383ff90499e25617af0c7dc5a6a5580fbf4005854f2189034712f4030001878be8c6ee42223e5b94a1890b2a14f8be80e0dc3
|
data/app/countries/atlas_engine/gg/address_validation/validators/full_address/exclusions/city.rb
ADDED
@@ -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
|
@@ -6,9 +6,10 @@ module AtlasEngine
|
|
6
6
|
class Candidate
|
7
7
|
extend T::Sig
|
8
8
|
attr_reader :id, :index
|
9
|
+
attr_accessor :position
|
9
10
|
|
10
|
-
sig { params(id: String, source: Hash, index: T.nilable(String)).void }
|
11
|
-
def initialize(id:, source:, index: nil)
|
11
|
+
sig { params(id: String, source: Hash, position: Integer, index: T.nilable(String)).void }
|
12
|
+
def initialize(id:, source:, position: 0, index: nil)
|
12
13
|
components_hash = Hash.new { |hash, key| hash[key] = Component.new(key, nil) }
|
13
14
|
|
14
15
|
@components = source.each_with_object(components_hash) do |(key, value), hash|
|
@@ -21,7 +21,7 @@ module AtlasEngine
|
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
|
-
sig { returns(T.nilable(
|
24
|
+
sig { returns(T.nilable(AddressValidation::Validators::FullAddress::AddressComparison)) }
|
25
25
|
def best_candidate
|
26
26
|
street_sequences_future = datastore.fetch_street_sequences_async
|
27
27
|
city_sequences_future = datastore.fetch_city_sequence_async
|
@@ -36,28 +36,28 @@ module AtlasEngine
|
|
36
36
|
|
37
37
|
attr_reader :datastore, :address
|
38
38
|
|
39
|
-
sig { returns(T::Array[
|
39
|
+
sig { returns(T::Array[AddressValidation::Validators::FullAddress::AddressComparison]) }
|
40
40
|
def sorted_candidates
|
41
|
-
|
41
|
+
sorted_address_comparisons = datastore.fetch_full_address_candidates
|
42
42
|
.filter_map.with_index(1) do |candidate, position|
|
43
|
-
|
43
|
+
candidate.position = position
|
44
|
+
address_comparison = AddressValidation::Validators::FullAddress::AddressComparison.new(
|
44
45
|
address: address,
|
45
46
|
candidate: candidate,
|
46
47
|
datastore: datastore,
|
47
48
|
)
|
48
|
-
|
49
|
-
tuple if tuple.address_comparison.potential_match?
|
49
|
+
address_comparison if address_comparison.potential_match?
|
50
50
|
end.sort
|
51
51
|
|
52
|
-
emit_sorted_candidates(
|
53
|
-
|
52
|
+
emit_sorted_candidates(sorted_address_comparisons.map(&:candidate))
|
53
|
+
sorted_address_comparisons
|
54
54
|
end
|
55
55
|
|
56
|
-
sig { params(
|
57
|
-
def emit_sorted_candidates(
|
58
|
-
log_info("Sorted candidates:\n #{
|
56
|
+
sig { params(sorted_candidates: T::Array[Candidate]).void }
|
57
|
+
def emit_sorted_candidates(sorted_candidates)
|
58
|
+
log_info("Sorted candidates:\n #{sorted_candidates.map(&:serialize)}")
|
59
59
|
|
60
|
-
initial_position_top_candidate =
|
60
|
+
initial_position_top_candidate = sorted_candidates.first&.position || 0
|
61
61
|
StatsD.distribution(
|
62
62
|
"AddressValidation.query.initial_position_top_candidate",
|
63
63
|
initial_position_top_candidate,
|
@@ -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
|
@@ -9,12 +9,11 @@ module AtlasEngine
|
|
9
9
|
include LogHelper
|
10
10
|
|
11
11
|
attr_reader :address, :result
|
12
|
-
attr_accessor :session
|
13
12
|
|
14
13
|
sig { params(address: TAddress, result: Result).void }
|
15
14
|
def initialize(address:, result: Result.new)
|
16
15
|
super
|
17
|
-
@
|
16
|
+
@matching_strategy = MatchingStrategies::Es
|
18
17
|
end
|
19
18
|
|
20
19
|
sig { override.returns(Result) }
|
@@ -30,23 +29,23 @@ module AtlasEngine
|
|
30
29
|
sig { returns(AddressValidation::Validators::FullAddress::CandidateResultBase) }
|
31
30
|
def build_candidate_result
|
32
31
|
unless supported_address?(address)
|
33
|
-
return AddressValidation::Validators::FullAddress::UnsupportedScriptResult.new(
|
32
|
+
return AddressValidation::Validators::FullAddress::UnsupportedScriptResult.new(address:, result:)
|
34
33
|
end
|
35
34
|
|
36
35
|
if best_candidate.nil?
|
37
|
-
AddressValidation::Validators::FullAddress::NoCandidateResult.new(
|
36
|
+
AddressValidation::Validators::FullAddress::NoCandidateResult.new(address:, result:)
|
38
37
|
else
|
39
38
|
AddressValidation::Validators::FullAddress::CandidateResult.new(
|
40
|
-
|
39
|
+
address_comparison: T.must(best_candidate),
|
40
|
+
matching_strategy: @matching_strategy,
|
41
41
|
result: result,
|
42
|
-
session: session,
|
43
42
|
)
|
44
43
|
end
|
45
44
|
end
|
46
45
|
|
47
46
|
private
|
48
47
|
|
49
|
-
sig { returns(T.nilable(
|
48
|
+
sig { returns(T.nilable(AddressValidation::Validators::FullAddress::AddressComparison)) }
|
50
49
|
def best_candidate
|
51
50
|
@best_candidate ||= T.let(
|
52
51
|
begin
|
@@ -63,15 +62,15 @@ module AtlasEngine
|
|
63
62
|
# We want our futures to complete even when we do not consume their value.
|
64
63
|
candidate_futures&.map(&:wait!)
|
65
64
|
end,
|
66
|
-
T.nilable(
|
65
|
+
T.nilable(AddressValidation::Validators::FullAddress::AddressComparison),
|
67
66
|
)
|
68
67
|
end
|
69
68
|
|
70
69
|
sig { params(locale: T.nilable(String)).returns(Concurrent::Promises::Future) }
|
71
70
|
def best_candidate_future(locale = nil)
|
72
71
|
AddressValidation::Es::CandidateSelector.new(
|
73
|
-
datastore:
|
74
|
-
address:
|
72
|
+
datastore: Es::Datastore.new(address: address, locale: locale),
|
73
|
+
address: address,
|
75
74
|
).best_candidate_async
|
76
75
|
end
|
77
76
|
|
@@ -9,7 +9,7 @@ module AtlasEngine
|
|
9
9
|
sig { params(address: TAddress, result: Result).void }
|
10
10
|
def initialize(address:, result: Result.new)
|
11
11
|
super
|
12
|
-
@
|
12
|
+
@matching_strategy = MatchingStrategies::EsStreet
|
13
13
|
end
|
14
14
|
end
|
15
15
|
end
|
@@ -11,16 +11,16 @@ module AtlasEngine
|
|
11
11
|
|
12
12
|
sig do
|
13
13
|
params(
|
14
|
-
|
15
|
-
|
14
|
+
address_comparison: AddressComparison,
|
15
|
+
matching_strategy: AddressValidation::MatchingStrategies,
|
16
16
|
result: Result,
|
17
|
-
)
|
18
|
-
.void
|
17
|
+
).void
|
19
18
|
end
|
20
|
-
def initialize(
|
21
|
-
super(
|
22
|
-
@
|
23
|
-
@
|
19
|
+
def initialize(address_comparison:, matching_strategy:, result:)
|
20
|
+
super(address: address_comparison.address, result: result)
|
21
|
+
@address_comparison = address_comparison
|
22
|
+
@candidate = address_comparison.candidate
|
23
|
+
@matching_strategy = matching_strategy
|
24
24
|
end
|
25
25
|
|
26
26
|
sig { override.void }
|
@@ -34,7 +34,7 @@ module AtlasEngine
|
|
34
34
|
|
35
35
|
sig { returns(T::Boolean) }
|
36
36
|
def suggestable?
|
37
|
-
ConcernBuilder.should_suggest?(
|
37
|
+
ConcernBuilder.should_suggest?(address, unmatched_components.keys)
|
38
38
|
end
|
39
39
|
|
40
40
|
private
|
@@ -56,11 +56,11 @@ module AtlasEngine
|
|
56
56
|
|
57
57
|
sig { void }
|
58
58
|
def add_concerns_without_suggestions
|
59
|
-
concern = InvalidZipConcernBuilder.for(
|
59
|
+
concern = InvalidZipConcernBuilder.for(address, [])
|
60
60
|
result.concerns << concern if concern
|
61
61
|
|
62
|
-
if ConcernBuilder.too_many_unmatched_components?(
|
63
|
-
result.concerns <<
|
62
|
+
if ConcernBuilder.too_many_unmatched_components?(address, unmatched_components.keys)
|
63
|
+
result.concerns << UnknownAddressConcernBuilder.new(address).build
|
64
64
|
end
|
65
65
|
end
|
66
66
|
|
@@ -77,7 +77,7 @@ module AtlasEngine
|
|
77
77
|
unmatched_component: unmatched_component,
|
78
78
|
unmatched_field: field_name,
|
79
79
|
matched_components: matched_components_to_validate.keys,
|
80
|
-
address:
|
80
|
+
address: address,
|
81
81
|
suggestion_ids: [suggestion.id].compact,
|
82
82
|
).build
|
83
83
|
result.concerns << concern
|
@@ -90,7 +90,7 @@ module AtlasEngine
|
|
90
90
|
unmatched_fields = { street: unmatched_field_name(:street) }.compact
|
91
91
|
|
92
92
|
@suggestion ||= SuggestionBuilder.from_comparisons(
|
93
|
-
|
93
|
+
address.to_h,
|
94
94
|
unmatched_components_to_validate,
|
95
95
|
candidate,
|
96
96
|
unmatched_fields,
|
@@ -126,7 +126,7 @@ module AtlasEngine
|
|
126
126
|
components = {}
|
127
127
|
@matched_and_unmatched_components ||= begin
|
128
128
|
components_to_compare.each do |component|
|
129
|
-
components[component] =
|
129
|
+
components[component] = address_comparison.for(component).sequence_comparison
|
130
130
|
end
|
131
131
|
components
|
132
132
|
end
|
@@ -144,7 +144,7 @@ module AtlasEngine
|
|
144
144
|
|
145
145
|
sig { returns(RelevantComponents) }
|
146
146
|
def relevant_components
|
147
|
-
@relevant_components ||= RelevantComponents.new(
|
147
|
+
@relevant_components ||= RelevantComponents.new(address_comparison, @matching_strategy)
|
148
148
|
end
|
149
149
|
|
150
150
|
sig do
|
@@ -167,17 +167,17 @@ module AtlasEngine
|
|
167
167
|
|
168
168
|
original_street = T.must(unmatched_components_to_validate[:street]).left_sequence.raw_value
|
169
169
|
|
170
|
-
if
|
170
|
+
if address.address1.to_s.include?(original_street)
|
171
171
|
:address1
|
172
|
-
elsif
|
172
|
+
elsif address.address2.to_s.include?(original_street)
|
173
173
|
:address2
|
174
174
|
end
|
175
175
|
end
|
176
176
|
|
177
177
|
sig { void }
|
178
178
|
def log_unknown_field_name
|
179
|
-
potential_streets = { potential_streets:
|
180
|
-
input_address =
|
179
|
+
potential_streets = { potential_streets: address_comparison.parsings.potential_streets }
|
180
|
+
input_address = address.to_h.compact_blank.except(:phone)
|
181
181
|
log_details = input_address.merge(potential_streets)
|
182
182
|
log_info("[AddressValidation] Unable to identify unmatched field name", log_details)
|
183
183
|
end
|
data/app/models/atlas_engine/address_validation/validators/full_address/candidate_result_base.rb
CHANGED
@@ -11,9 +11,9 @@ module AtlasEngine
|
|
11
11
|
|
12
12
|
abstract!
|
13
13
|
|
14
|
-
sig { params(
|
15
|
-
def initialize(
|
16
|
-
@
|
14
|
+
sig { params(address: AbstractAddress, result: Result).void }
|
15
|
+
def initialize(address:, result:)
|
16
|
+
@address = address
|
17
17
|
@result = result
|
18
18
|
end
|
19
19
|
|
@@ -22,9 +22,7 @@ module AtlasEngine
|
|
22
22
|
|
23
23
|
private
|
24
24
|
|
25
|
-
attr_reader :
|
26
|
-
|
27
|
-
delegate :address, to: :session
|
25
|
+
attr_reader :result, :address
|
28
26
|
|
29
27
|
sig { void }
|
30
28
|
def update_result_scope
|
@@ -109,17 +109,13 @@ 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 UnknownZipForAddressConcern.new(address, suggestion_ids)
|
114
|
-
end
|
115
|
-
|
116
112
|
build_default_concern
|
117
113
|
end
|
118
114
|
|
119
115
|
sig { returns(AddressValidation::Concern) }
|
120
116
|
def build_province_concern
|
121
117
|
if ([:zip, :city] - matched_components).empty?
|
122
|
-
|
118
|
+
UnknownProvinceConcernBuilder.new(address).build(suggestion_ids)
|
123
119
|
else
|
124
120
|
build_default_concern
|
125
121
|
end
|
@@ -127,7 +123,12 @@ module AtlasEngine
|
|
127
123
|
|
128
124
|
sig { returns(AddressValidation::Concern) }
|
129
125
|
def build_default_concern
|
130
|
-
|
126
|
+
UnmatchedFieldConcernBuilder.new(
|
127
|
+
unmatched_component,
|
128
|
+
matched_components,
|
129
|
+
address,
|
130
|
+
unmatched_field,
|
131
|
+
).build(suggestion_ids)
|
131
132
|
end
|
132
133
|
end
|
133
134
|
end
|
@@ -22,9 +22,13 @@ module AtlasEngine
|
|
22
22
|
return unless country.has_zip?
|
23
23
|
|
24
24
|
if country_expects_zone_in_address?(country) && province.province?
|
25
|
-
|
25
|
+
return if province.valid_zip?(address.zip)
|
26
|
+
|
27
|
+
InvalidZipForProvinceConcernBuilder.new(address).build
|
26
28
|
else
|
27
|
-
|
29
|
+
return if country.valid_zip?(address.zip)
|
30
|
+
|
31
|
+
InvalidZipForCountryConcernBuilder.new(address).build(suggestion_ids)
|
28
32
|
end
|
29
33
|
end
|
30
34
|
|
@@ -5,31 +5,32 @@ module AtlasEngine
|
|
5
5
|
module AddressValidation
|
6
6
|
module Validators
|
7
7
|
module FullAddress
|
8
|
-
class
|
8
|
+
class InvalidZipForCountryConcernBuilder
|
9
|
+
extend T::Sig
|
9
10
|
include ConcernFormatter
|
10
11
|
attr_reader :address
|
11
12
|
|
12
|
-
sig { params(address: AbstractAddress
|
13
|
-
def initialize(address
|
13
|
+
sig { params(address: AbstractAddress).void }
|
14
|
+
def initialize(address)
|
14
15
|
@address = address
|
16
|
+
end
|
17
|
+
|
18
|
+
sig { params(suggestion_ids: T::Array[String]).returns(Concern) }
|
19
|
+
def build(suggestion_ids = [])
|
20
|
+
message = country.field(key: :zip).error(
|
21
|
+
code: :invalid_for_country,
|
22
|
+
options: { country: country.full_name },
|
23
|
+
).to_s
|
15
24
|
|
16
|
-
|
25
|
+
Concern.new(
|
17
26
|
code: :zip_invalid_for_country,
|
18
27
|
field_names: [:zip],
|
19
28
|
message: message,
|
20
29
|
type: T.must(Concern::TYPES[:error]),
|
21
30
|
type_level: 1,
|
22
|
-
suggestion_ids: suggestion_ids
|
31
|
+
suggestion_ids: suggestion_ids,
|
23
32
|
)
|
24
33
|
end
|
25
|
-
|
26
|
-
sig { returns(String) }
|
27
|
-
def message
|
28
|
-
country.field(key: :zip).error(
|
29
|
-
code: :invalid_for_country,
|
30
|
-
options: { country: country.full_name },
|
31
|
-
).to_s
|
32
|
-
end
|
33
34
|
end
|
34
35
|
end
|
35
36
|
end
|
@@ -5,30 +5,30 @@ module AtlasEngine
|
|
5
5
|
module AddressValidation
|
6
6
|
module Validators
|
7
7
|
module FullAddress
|
8
|
-
class
|
8
|
+
class InvalidZipForProvinceConcernBuilder
|
9
|
+
extend T::Sig
|
9
10
|
include ConcernFormatter
|
10
11
|
attr_reader :address
|
11
12
|
|
12
|
-
|
13
|
-
def initialize(address, suggestion_ids)
|
13
|
+
def initialize(address)
|
14
14
|
@address = address
|
15
|
-
|
16
|
-
super(
|
17
|
-
code: :zip_invalid_for_province,
|
18
|
-
field_names: [:zip],
|
19
|
-
message: message,
|
20
|
-
type: T.must(Concern::TYPES[:error]),
|
21
|
-
type_level: 1,
|
22
|
-
suggestion_ids: suggestion_ids
|
23
|
-
)
|
24
15
|
end
|
25
16
|
|
26
|
-
sig {
|
27
|
-
def
|
28
|
-
country.field(key: :zip).error(
|
17
|
+
sig { params(suggestion_ids: T::Array[String]).returns(Concern) }
|
18
|
+
def build(suggestion_ids = [])
|
19
|
+
message = country.field(key: :zip).error(
|
29
20
|
code: :invalid_for_province,
|
30
21
|
options: { province: province_name },
|
31
22
|
).to_s
|
23
|
+
|
24
|
+
Concern.new(
|
25
|
+
field_names: [:zip],
|
26
|
+
code: :zip_invalid_for_province,
|
27
|
+
type: T.must(Concern::TYPES[:error]),
|
28
|
+
type_level: 1,
|
29
|
+
suggestion_ids: suggestion_ids,
|
30
|
+
message: message,
|
31
|
+
)
|
32
32
|
end
|
33
33
|
end
|
34
34
|
end
|
data/app/models/atlas_engine/address_validation/validators/full_address/no_candidate_result.rb
CHANGED
@@ -10,11 +10,9 @@ module AtlasEngine
|
|
10
10
|
|
11
11
|
sig { void }
|
12
12
|
def update_result
|
13
|
-
result.concerns <<
|
14
|
-
address,
|
15
|
-
)
|
13
|
+
result.concerns << UnknownAddressConcernBuilder.new(address).build
|
16
14
|
|
17
|
-
concern = InvalidZipConcernBuilder.for(
|
15
|
+
concern = InvalidZipConcernBuilder.for(address, [])
|
18
16
|
result.concerns << concern if concern
|
19
17
|
|
20
18
|
update_result_scope
|
data/app/models/atlas_engine/address_validation/validators/full_address/relevant_components.rb
CHANGED
@@ -8,9 +8,6 @@ module AtlasEngine
|
|
8
8
|
class RelevantComponents
|
9
9
|
extend T::Sig
|
10
10
|
|
11
|
-
sig { returns(Session) }
|
12
|
-
attr_reader :session
|
13
|
-
|
14
11
|
sig { returns(Candidate) }
|
15
12
|
attr_reader :candidate
|
16
13
|
|
@@ -19,15 +16,15 @@ module AtlasEngine
|
|
19
16
|
|
20
17
|
sig do
|
21
18
|
params(
|
22
|
-
session: Session,
|
23
|
-
candidate: Candidate,
|
24
19
|
address_comparison: AddressComparison,
|
20
|
+
matching_strategy: AtlasEngine::AddressValidation::MatchingStrategies,
|
25
21
|
).void
|
26
22
|
end
|
27
|
-
def initialize(
|
28
|
-
@session = session
|
29
|
-
@candidate = candidate
|
23
|
+
def initialize(address_comparison, matching_strategy)
|
30
24
|
@address_comparison = address_comparison
|
25
|
+
@matching_strategy = matching_strategy
|
26
|
+
@address = address_comparison.address
|
27
|
+
@candidate = address_comparison.candidate
|
31
28
|
@all_supported_components = address_comparison.relevant_components.dup
|
32
29
|
end
|
33
30
|
|
@@ -62,8 +59,7 @@ module AtlasEngine
|
|
62
59
|
def exclude_street_validation?
|
63
60
|
return @exclude_street_validation if defined?(@exclude_street_validation)
|
64
61
|
|
65
|
-
@exclude_street_validation = if
|
66
|
-
AddressValidation::MatchingStrategies::EsStreet
|
62
|
+
@exclude_street_validation = if @matching_strategy != AddressValidation::MatchingStrategies::EsStreet
|
67
63
|
true
|
68
64
|
elsif address_comparison.street_comparison.sequence_comparison.blank?
|
69
65
|
emit_excluded_validation(:street, "not_found")
|
@@ -80,7 +76,7 @@ module AtlasEngine
|
|
80
76
|
|
81
77
|
sig { returns(CountryProfile) }
|
82
78
|
def country_profile
|
83
|
-
@country_profile ||= CountryProfile.for(
|
79
|
+
@country_profile ||= CountryProfile.for(@address.country_code)
|
84
80
|
end
|
85
81
|
|
86
82
|
sig { params(component: Symbol, reason: String).void }
|
@@ -88,7 +84,7 @@ module AtlasEngine
|
|
88
84
|
tags = [
|
89
85
|
"reason:#{reason}",
|
90
86
|
"component:#{component}",
|
91
|
-
"country:#{
|
87
|
+
"country:#{@address.country_code}",
|
92
88
|
]
|
93
89
|
StatsD.increment("AddressValidation.skip", sample_rate: 1.0, tags: tags)
|
94
90
|
end
|
@@ -97,7 +93,7 @@ module AtlasEngine
|
|
97
93
|
def unsupported_components_for_country
|
98
94
|
@unsupported_components_for_country ||= begin
|
99
95
|
unsupported_components = []
|
100
|
-
country = Worldwide.region(code:
|
96
|
+
country = Worldwide.region(code: @address.country_code)
|
101
97
|
unsupported_components << :province_code if country.province_optional?
|
102
98
|
unsupported_components << :province_code if country.hide_provinces_from_addresses
|
103
99
|
unsupported_components << :city unless country.city_required?
|
@@ -5,7 +5,8 @@ module AtlasEngine
|
|
5
5
|
module AddressValidation
|
6
6
|
module Validators
|
7
7
|
module FullAddress
|
8
|
-
class
|
8
|
+
class UnknownAddressConcernBuilder
|
9
|
+
extend T::Sig
|
9
10
|
include ConcernFormatter
|
10
11
|
|
11
12
|
sig { returns(TAddress) }
|
@@ -14,12 +15,18 @@ module AtlasEngine
|
|
14
15
|
sig { params(address: TAddress).void }
|
15
16
|
def initialize(address)
|
16
17
|
@address = address
|
17
|
-
|
18
|
+
end
|
19
|
+
|
20
|
+
sig { params(suggestion_ids: T::Array[String]).returns(Concern) }
|
21
|
+
def build(suggestion_ids = [])
|
22
|
+
message = country.field(key: :address).error(code: :may_not_exist)
|
23
|
+
|
24
|
+
Concern.new(
|
18
25
|
code: :address_unknown,
|
19
|
-
message:
|
26
|
+
message: message,
|
20
27
|
type: T.must(Concern::TYPES[:warning]),
|
21
28
|
type_level: 1,
|
22
|
-
suggestion_ids:
|
29
|
+
suggestion_ids: suggestion_ids,
|
23
30
|
field_names: [:address1],
|
24
31
|
)
|
25
32
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# typed: true
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module AtlasEngine
|
5
|
+
module AddressValidation
|
6
|
+
module Validators
|
7
|
+
module FullAddress
|
8
|
+
class UnknownProvinceConcernBuilder
|
9
|
+
extend T::Sig
|
10
|
+
include ConcernFormatter
|
11
|
+
attr_reader :address
|
12
|
+
|
13
|
+
sig { params(address: AbstractAddress).void }
|
14
|
+
def initialize(address)
|
15
|
+
@address = address
|
16
|
+
end
|
17
|
+
|
18
|
+
sig { params(suggestion_ids: T::Array[String]).returns(Concern) }
|
19
|
+
def build(suggestion_ids = [])
|
20
|
+
message = country.field(key: :province).error(
|
21
|
+
code: :unknown_for_city_and_zip,
|
22
|
+
options: { city: address.city, zip: address.zip },
|
23
|
+
).to_s
|
24
|
+
|
25
|
+
Concern.new(
|
26
|
+
code: :province_inconsistent,
|
27
|
+
field_names: [:province],
|
28
|
+
message: message,
|
29
|
+
type: T.must(Concern::TYPES[:error]),
|
30
|
+
type_level: 1,
|
31
|
+
suggestion_ids: suggestion_ids,
|
32
|
+
)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -5,9 +5,10 @@ module AtlasEngine
|
|
5
5
|
module AddressValidation
|
6
6
|
module Validators
|
7
7
|
module FullAddress
|
8
|
-
class
|
8
|
+
class UnmatchedFieldConcernBuilder
|
9
|
+
extend T::Sig
|
9
10
|
include ConcernFormatter
|
10
|
-
attr_reader :
|
11
|
+
attr_reader :address, :component, :matched_components, :unmatched_field
|
11
12
|
|
12
13
|
COMPONENTS_TO_LABELS = {
|
13
14
|
zip: "ZIP",
|
@@ -25,29 +26,37 @@ module AtlasEngine
|
|
25
26
|
unmatched_component: Symbol,
|
26
27
|
matched_components: T::Array[Symbol],
|
27
28
|
address: AbstractAddress,
|
28
|
-
suggestion_ids: T::Array[String],
|
29
29
|
unmatched_field: T.nilable(Symbol),
|
30
30
|
).void
|
31
31
|
end
|
32
|
-
def initialize(unmatched_component, matched_components, address,
|
32
|
+
def initialize(unmatched_component, matched_components, address, unmatched_field = nil)
|
33
|
+
@address = address
|
33
34
|
@component = unmatched_component
|
34
35
|
@matched_components = matched_components
|
35
|
-
@address = address
|
36
36
|
@unmatched_field = unmatched_field
|
37
|
+
end
|
37
38
|
|
38
|
-
|
39
|
+
sig do
|
40
|
+
params(
|
41
|
+
suggestion_ids: T::Array[String],
|
42
|
+
).returns(Concern)
|
43
|
+
end
|
44
|
+
def build(suggestion_ids = [])
|
45
|
+
Concern.new(
|
39
46
|
code: code,
|
40
47
|
field_names: field_names,
|
41
48
|
message: message,
|
42
49
|
type: T.must(Concern::TYPES[:warning]),
|
43
50
|
type_level: 3,
|
44
|
-
suggestion_ids: suggestion_ids
|
51
|
+
suggestion_ids: suggestion_ids,
|
45
52
|
)
|
46
53
|
end
|
47
54
|
|
55
|
+
private
|
56
|
+
|
48
57
|
sig { returns(String) }
|
49
58
|
def message
|
50
|
-
|
59
|
+
country.field(key: field_name).error(code: :unknown_for_address).to_s
|
51
60
|
end
|
52
61
|
|
53
62
|
sig { returns(Symbol) }
|
@@ -60,8 +69,6 @@ module AtlasEngine
|
|
60
69
|
[field_name]
|
61
70
|
end
|
62
71
|
|
63
|
-
private
|
64
|
-
|
65
72
|
sig { returns(T::Array[String]) }
|
66
73
|
def valid_address_component_values
|
67
74
|
matched_components.last(2).map do |component|
|
@@ -74,6 +81,7 @@ module AtlasEngine
|
|
74
81
|
SHORTENED_COMPONENT_NAMES[component] || component
|
75
82
|
end
|
76
83
|
|
84
|
+
sig { returns(Symbol) }
|
77
85
|
def field_name
|
78
86
|
unmatched_field || shortened_component_name
|
79
87
|
end
|
data/app/models/atlas_engine/address_validation/validators/predicates/country/valid_for_zip.rb
CHANGED
@@ -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
|
31
|
+
field_names: [:country],
|
32
32
|
code: :country_invalid_for_zip,
|
33
33
|
type: T.must(Concern::TYPES[:error]),
|
34
34
|
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
|
25
|
+
field_names: [:address1, :address2],
|
26
26
|
code: :missing_building_number,
|
27
27
|
type: T.must(Concern::TYPES[:warning]),
|
28
28
|
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
|
-
|
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
|
-
|
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
|
-
|
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]) }
|
data/lib/atlas_engine/version.rb
CHANGED
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.
|
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-
|
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
|
@@ -437,7 +439,6 @@ files:
|
|
437
439
|
- app/models/atlas_engine/address_validation/abstract_address.rb
|
438
440
|
- app/models/atlas_engine/address_validation/address.rb
|
439
441
|
- app/models/atlas_engine/address_validation/candidate.rb
|
440
|
-
- app/models/atlas_engine/address_validation/candidate_tuple.rb
|
441
442
|
- app/models/atlas_engine/address_validation/concern.rb
|
442
443
|
- app/models/atlas_engine/address_validation/concern_producer.rb
|
443
444
|
- app/models/atlas_engine/address_validation/concern_queue.rb
|
@@ -463,7 +464,6 @@ files:
|
|
463
464
|
- app/models/atlas_engine/address_validation/request.rb
|
464
465
|
- app/models/atlas_engine/address_validation/result.rb
|
465
466
|
- app/models/atlas_engine/address_validation/runs_validation.rb
|
466
|
-
- app/models/atlas_engine/address_validation/session.rb
|
467
467
|
- app/models/atlas_engine/address_validation/statsd_emitter.rb
|
468
468
|
- app/models/atlas_engine/address_validation/strategies.rb
|
469
469
|
- app/models/atlas_engine/address_validation/suggestion.rb
|
@@ -485,20 +485,18 @@ files:
|
|
485
485
|
- app/models/atlas_engine/address_validation/validators/full_address/exclusions/exclusion_base.rb
|
486
486
|
- app/models/atlas_engine/address_validation/validators/full_address/field_comparison_base.rb
|
487
487
|
- app/models/atlas_engine/address_validation/validators/full_address/invalid_zip_concern_builder.rb
|
488
|
-
- app/models/atlas_engine/address_validation/validators/full_address/
|
489
|
-
- app/models/atlas_engine/address_validation/validators/full_address/
|
488
|
+
- app/models/atlas_engine/address_validation/validators/full_address/invalid_zip_for_country_concern_builder.rb
|
489
|
+
- app/models/atlas_engine/address_validation/validators/full_address/invalid_zip_for_province_concern_builder.rb
|
490
490
|
- app/models/atlas_engine/address_validation/validators/full_address/no_candidate_result.rb
|
491
491
|
- app/models/atlas_engine/address_validation/validators/full_address/number_comparison.rb
|
492
492
|
- app/models/atlas_engine/address_validation/validators/full_address/postal_code_matcher.rb
|
493
493
|
- app/models/atlas_engine/address_validation/validators/full_address/province_code_comparison.rb
|
494
494
|
- app/models/atlas_engine/address_validation/validators/full_address/relevant_components.rb
|
495
|
-
- app/models/atlas_engine/address_validation/validators/full_address/result_updater.rb
|
496
495
|
- app/models/atlas_engine/address_validation/validators/full_address/street_comparison.rb
|
497
496
|
- app/models/atlas_engine/address_validation/validators/full_address/suggestion_builder.rb
|
498
|
-
- app/models/atlas_engine/address_validation/validators/full_address/
|
499
|
-
- app/models/atlas_engine/address_validation/validators/full_address/
|
500
|
-
- app/models/atlas_engine/address_validation/validators/full_address/
|
501
|
-
- app/models/atlas_engine/address_validation/validators/full_address/unmatched_field_concern.rb
|
497
|
+
- app/models/atlas_engine/address_validation/validators/full_address/unknown_address_concern_builder.rb
|
498
|
+
- app/models/atlas_engine/address_validation/validators/full_address/unknown_province_concern_builder.rb
|
499
|
+
- app/models/atlas_engine/address_validation/validators/full_address/unmatched_field_concern_builder.rb
|
502
500
|
- app/models/atlas_engine/address_validation/validators/full_address/unsupported_script_result.rb
|
503
501
|
- app/models/atlas_engine/address_validation/validators/full_address/zip_comparison.rb
|
504
502
|
- app/models/atlas_engine/address_validation/validators/predicates/cache.rb
|
@@ -533,6 +531,7 @@ files:
|
|
533
531
|
- app/models/atlas_engine/country_repository.rb
|
534
532
|
- app/models/atlas_engine/elasticsearch/client.rb
|
535
533
|
- app/models/atlas_engine/elasticsearch/client_interface.rb
|
534
|
+
- app/models/atlas_engine/elasticsearch/error.rb
|
536
535
|
- app/models/atlas_engine/elasticsearch/repository.rb
|
537
536
|
- app/models/atlas_engine/elasticsearch/repository_interface.rb
|
538
537
|
- app/models/atlas_engine/elasticsearch/response.rb
|
@@ -1,15 +0,0 @@
|
|
1
|
-
# typed: true
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
module AtlasEngine
|
5
|
-
module AddressValidation
|
6
|
-
CandidateTuple = Struct.new(:address_comparison, :position, :candidate) do
|
7
|
-
extend T::Sig
|
8
|
-
|
9
|
-
sig { params(other: CandidateTuple).returns(Integer) }
|
10
|
-
def <=>(other)
|
11
|
-
to_a[0..1] <=> other.to_a[0..1] # only consider address_comparison and position
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
@@ -1,47 +0,0 @@
|
|
1
|
-
# typed: strict
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
require "forwardable"
|
5
|
-
|
6
|
-
module AtlasEngine
|
7
|
-
module AddressValidation
|
8
|
-
class Session
|
9
|
-
extend Forwardable
|
10
|
-
extend T::Sig
|
11
|
-
|
12
|
-
sig { returns(AbstractAddress) }
|
13
|
-
attr_reader :address
|
14
|
-
|
15
|
-
sig { returns(MatchingStrategies) }
|
16
|
-
attr_accessor :matching_strategy
|
17
|
-
|
18
|
-
sig { returns(T::Hash[String, AtlasEngine::AddressValidation::DatastoreBase]) }
|
19
|
-
attr_reader :datastore_hash
|
20
|
-
|
21
|
-
def_delegators :@address, :address1, :address2, :city, :province_code, :country_code, :zip, :phone
|
22
|
-
|
23
|
-
sig do
|
24
|
-
params(
|
25
|
-
address: AbstractAddress,
|
26
|
-
matching_strategy: MatchingStrategies,
|
27
|
-
).void
|
28
|
-
end
|
29
|
-
def initialize(address:, matching_strategy: MatchingStrategies::Es)
|
30
|
-
@address = address
|
31
|
-
@matching_strategy = matching_strategy
|
32
|
-
@datastore_hash = T.let({}, T::Hash[String, AtlasEngine::AddressValidation::DatastoreBase])
|
33
|
-
end
|
34
|
-
|
35
|
-
sig { params(locale: T.nilable(String)).returns(ValidationTranscriber::AddressParsings) }
|
36
|
-
def parsings(locale: nil)
|
37
|
-
datastore(locale: locale).parsings
|
38
|
-
end
|
39
|
-
|
40
|
-
sig { params(locale: T.nilable(String)).returns(AtlasEngine::AddressValidation::DatastoreBase) }
|
41
|
-
def datastore(locale: nil)
|
42
|
-
key = locale || "default"
|
43
|
-
@datastore_hash[key] ||= AtlasEngine::AddressValidation::Es::Datastore.new(address: address, locale: locale)
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
@@ -1,42 +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 ResultUpdater
|
9
|
-
extend T::Sig
|
10
|
-
extend T::Helpers
|
11
|
-
abstract!
|
12
|
-
|
13
|
-
sig { params(session: Session, result: Result).void }
|
14
|
-
def initialize(session:, result:)
|
15
|
-
@session = session
|
16
|
-
@result = result
|
17
|
-
end
|
18
|
-
|
19
|
-
private
|
20
|
-
|
21
|
-
attr_reader :session, :result
|
22
|
-
|
23
|
-
delegate :address, to: :session
|
24
|
-
|
25
|
-
sig { void }
|
26
|
-
def update_result_scope
|
27
|
-
concern_fields = result.concerns.flat_map(&:field_names).uniq
|
28
|
-
scopes_to_remove = concern_fields.flat_map { |field| contained_scopes_for(field) }
|
29
|
-
result.validation_scope.reject! { |scope| scope.in?(scopes_to_remove) }
|
30
|
-
end
|
31
|
-
|
32
|
-
sig { params(scope: Symbol).returns(T.nilable(T::Array[Symbol])) }
|
33
|
-
def contained_scopes_for(scope)
|
34
|
-
return [] unless (scope_index = Result::SORTED_VALIDATION_SCOPES.index(scope))
|
35
|
-
|
36
|
-
Result::SORTED_VALIDATION_SCOPES.slice(scope_index..)
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
data/app/models/atlas_engine/address_validation/validators/full_address/unknown_province_concern.rb
DELETED
@@ -1,38 +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 UnknownProvinceConcern < AddressValidation::Concern
|
9
|
-
include ConcernFormatter
|
10
|
-
attr_reader :address
|
11
|
-
|
12
|
-
sig { params(address: AbstractAddress, suggestion_ids: T::Array[String]).void }
|
13
|
-
def initialize(address, suggestion_ids)
|
14
|
-
@address = address
|
15
|
-
super(
|
16
|
-
code: :province_inconsistent,
|
17
|
-
field_names: [:province],
|
18
|
-
message: message,
|
19
|
-
type: T.must(Concern::TYPES[:error]),
|
20
|
-
type_level: 1,
|
21
|
-
suggestion_ids: suggestion_ids
|
22
|
-
)
|
23
|
-
end
|
24
|
-
|
25
|
-
sig { returns(String) }
|
26
|
-
def message
|
27
|
-
country
|
28
|
-
.field(key: :province)
|
29
|
-
.error(
|
30
|
-
code: :unknown_for_city_and_zip,
|
31
|
-
options: { city: address.city, zip: address.zip },
|
32
|
-
).to_s
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
@@ -1,32 +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 UnknownZipForAddressConcern < AddressValidation::Concern
|
9
|
-
attr_reader :address
|
10
|
-
|
11
|
-
sig { params(address: AbstractAddress, suggestion_ids: T::Array[String]).void }
|
12
|
-
def initialize(address, suggestion_ids)
|
13
|
-
@address = address
|
14
|
-
super(
|
15
|
-
code: :zip_inconsistent,
|
16
|
-
field_names: [:zip],
|
17
|
-
message: message,
|
18
|
-
type: T.must(Concern::TYPES[:warning]),
|
19
|
-
type_level: 3,
|
20
|
-
suggestion_ids: suggestion_ids
|
21
|
-
)
|
22
|
-
end
|
23
|
-
|
24
|
-
sig { returns(String) }
|
25
|
-
def message
|
26
|
-
"Enter a valid ZIP for #{address.address1}, #{address.city}"
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|