atlas_engine 0.5.0 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|