atlas_engine 1.0.0 → 1.2.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.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +39 -24
  3. data/app/countries/atlas_engine/at/country_profile.yml +1 -1
  4. data/app/countries/atlas_engine/au/country_profile.yml +1 -1
  5. data/app/countries/atlas_engine/be/country_profile.yml +2 -2
  6. data/app/countries/atlas_engine/ch/country_profile.yml +1 -1
  7. data/app/countries/atlas_engine/fr/country_profile.yml +1 -1
  8. data/app/countries/atlas_engine/nl/country_profile.yml +1 -1
  9. data/app/countries/atlas_engine/pl/country_profile.yml +1 -1
  10. data/app/countries/atlas_engine/us/country_profile.yml +1 -0
  11. data/app/graphql/atlas_engine/schema.graphql +14 -1
  12. data/app/graphql/atlas_engine/types/address_validation/address_input.rb +4 -0
  13. data/app/graphql/atlas_engine/types/address_validation/concern_type.rb +8 -1
  14. data/app/graphql/atlas_engine/types/address_validation/suggestion_type.rb +4 -0
  15. data/app/graphql/atlas_engine/types/message_format_type.rb +11 -0
  16. data/app/graphql/atlas_engine/types/query_type.rb +3 -1
  17. data/app/lib/atlas_engine/validation_transcriber/address_parsings.rb +14 -9
  18. data/app/lib/atlas_engine/validation_transcriber/formatter.rb +10 -1
  19. data/app/models/atlas_engine/address_number_range.rb +1 -1
  20. data/app/models/atlas_engine/address_validation/abstract_address.rb +12 -0
  21. data/app/models/atlas_engine/address_validation/address.rb +8 -0
  22. data/app/models/atlas_engine/address_validation/concern_record.rb +28 -0
  23. data/app/models/atlas_engine/address_validation/es/validators/full_address.rb +18 -5
  24. data/app/models/atlas_engine/address_validation/es/validators/full_address_street.rb +2 -2
  25. data/app/models/atlas_engine/address_validation/full_address_validator_base.rb +6 -2
  26. data/app/models/atlas_engine/address_validation/message_format.rb +13 -0
  27. data/app/models/atlas_engine/address_validation/predicate_pipeline_builder.rb +90 -0
  28. data/app/models/atlas_engine/address_validation/request.rb +1 -0
  29. data/app/models/atlas_engine/address_validation/suggestion.rb +26 -1
  30. data/app/models/atlas_engine/address_validation/validator.rb +31 -14
  31. data/app/models/atlas_engine/address_validation/validators/full_address/candidate_result.rb +9 -5
  32. data/app/models/atlas_engine/address_validation/validators/full_address/candidate_result_base.rb +4 -3
  33. data/app/models/atlas_engine/address_validation/validators/full_address/concern_builder.rb +19 -4
  34. data/app/models/atlas_engine/address_validation/validators/full_address/invalid_zip_concern_builder.rb +4 -3
  35. data/app/models/atlas_engine/address_validation/validators/full_address/invalid_zip_for_country_concern_builder.rb +6 -4
  36. data/app/models/atlas_engine/address_validation/validators/full_address/invalid_zip_for_province_concern_builder.rb +4 -2
  37. data/app/models/atlas_engine/address_validation/validators/full_address/no_candidate_result.rb +1 -1
  38. data/app/models/atlas_engine/address_validation/validators/full_address/suggestion_builder.rb +9 -2
  39. data/app/models/atlas_engine/address_validation/validators/full_address/unknown_address_concern_builder.rb +16 -4
  40. data/app/models/atlas_engine/address_validation/validators/full_address/unknown_province_concern_builder.rb +8 -3
  41. data/app/models/atlas_engine/address_validation/validators/full_address/unmatched_field_concern_builder.rb +13 -3
  42. data/app/models/atlas_engine/address_validation/validators/full_address/unsupported_script_result.rb +1 -1
  43. data/app/models/atlas_engine/address_validation/validators/predicates/city/present.rb +1 -1
  44. data/app/models/atlas_engine/address_validation/validators/predicates/country/exists.rb +5 -1
  45. data/app/models/atlas_engine/address_validation/validators/predicates/country/valid_for_zip.rb +1 -1
  46. data/app/models/atlas_engine/address_validation/validators/predicates/neighborhood/present.rb +35 -0
  47. data/app/models/atlas_engine/address_validation/validators/predicates/not_exceed_max_length.rb +18 -3
  48. data/app/models/atlas_engine/address_validation/validators/predicates/phone/valid.rb +3 -1
  49. data/app/models/atlas_engine/address_validation/validators/predicates/predicate.rb +6 -2
  50. data/app/models/atlas_engine/address_validation/validators/predicates/province/exists.rb +3 -1
  51. data/app/models/atlas_engine/address_validation/validators/predicates/province/valid_for_country.rb +3 -1
  52. data/app/models/atlas_engine/address_validation/validators/predicates/street/present.rb +3 -1
  53. data/app/models/atlas_engine/address_validation/validators/predicates/street_name/present.rb +35 -0
  54. data/app/models/atlas_engine/address_validation/validators/predicates/street_number/present.rb +35 -0
  55. data/app/models/atlas_engine/address_validation/validators/predicates/zip/present.rb +2 -2
  56. data/app/models/atlas_engine/address_validation/validators/predicates/zip/valid_for_country.rb +1 -1
  57. data/app/models/atlas_engine/address_validation/validators/predicates/zip/valid_for_province.rb +1 -1
  58. data/app/models/atlas_engine/services/validation.rb +4 -0
  59. data/db/data/validation_pipelines/es.yml +46 -0
  60. data/db/data/validation_pipelines/es_street.yml +46 -0
  61. data/db/data/validation_pipelines/local.yml +46 -0
  62. data/lib/atlas_engine/version.rb +1 -1
  63. metadata +39 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2236db9cf72e66e7bec983fec0ce919b31e1a795e6509ac65e1f914e8cda1c2b
4
- data.tar.gz: c4bb6b2c1c8c927abbdf22d66d7a198052ab772f9243ffbd4c02bccced29b4ea
3
+ metadata.gz: 2ac0ad464ab86fe1db96b5ca3f5a69254d6ad52571d8c83350645c9e031ea58b
4
+ data.tar.gz: f683950cfa6d89c1cdf4935d8a49d76e416c57220ac29e5aa62adcdaf2a628d5
5
5
  SHA512:
6
- metadata.gz: a1ccff91cd2b8026fd568ba9aced9688741bf1fd107fd180a83447e9d62ce20750d1ba8d14efe690ab22db6d239dfc1af51edda770c00de31cf07bfc210dc8cf
7
- data.tar.gz: 9ee3408a1926463cf05cef4ba3b835e71fb8f490b61033154ac47dc586e2eb8b20fa971c9ca8c23859cec7fd4f7f8e81370f506fdba16e081b6299595a517f05
6
+ metadata.gz: 79ae2f83d4b4ee2d65a7d6e566bee41ac3b0c5e44f879090b4659151ca9f7987e128badf6f31569530c142ea683b8df6dce10275423469924c44f1477f6480d6
7
+ data.tar.gz: e1a0e889113742443408d479dba7f1bb294230d4bcfd0af8f128e6c200a19d6c595c1bdf420798ebd2a9cb9caa8fa2cd69ef21ab4361ae066aa6a48861e9f91d
data/README.md CHANGED
@@ -7,6 +7,7 @@ Atlas Engine is a rails engine that provides a global end-to-end address validat
7
7
  * [Local Development Installation](#local-development-installation)
8
8
  * [Address Data Ingestion](#address-data-ingestion)
9
9
  * [Elasticsearch Matching Strategy](#elasticsearch-matching-strategy)
10
+ * [Hosted Solution](#hosted-solution)
10
11
 
11
12
  ## Address Validation API
12
13
 
@@ -24,7 +25,6 @@ query validation {
24
25
  zip: "K2P 2L8"
25
26
  }
26
27
  locale: "en"
27
- matchingStrategy: LOCAL
28
28
  ) {
29
29
  validationScope
30
30
  concerns {
@@ -69,21 +69,6 @@ presence or absence differs per country.
69
69
 
70
70
  **Locale:** The language in which to render any messages in the validation API response.
71
71
 
72
- **MatchingStrategy:** The strategy used to evaluate the validity of the address input. Out of the box, Atlas Engine
73
- supports three different matching strategies: `local`, `es`, and `es_street`.
74
- - `local` matching uses the [worldwide](https://github.com/Shopify/worldwide) gem to provide the most basic level of
75
- address validation. This may include simple errors (required fields not populated) or more advanced errors (province
76
- not belonging to the country, zip code not belonging to the province). This level of matching does not require
77
- [ingestion](#ingestion) of country data to work, but the level of support and suggestions it can provide in its
78
- responses is minimal.
79
- - `es` matching uses data indexed in elasticsearch via our [ingestion](#ingestion) process to validate the city,
80
- province, country, and zip code fields of the input address, in addition to all of the basic functionality provided
81
- in the `local` strategy. A more detailed explanation for how this strategy works can be found [here](#elasticsearch-matching-strategy).
82
- - `es_street` is our most advanced matching strategy and requires the highest quality data indexed in elasticsearch
83
- via our [ingestion](#ingestion) process. This matching strategy provides everything that `es` and `local` does along
84
- with validation of the address1 and address2 components of the address input. A more detailed explanation of how
85
- this strategy works can be found [here](#elasticsearch-matching-strategy).
86
-
87
72
  **Validation Scope:** This response object is populated with the field names from the input that have been successfully
88
73
  validated.
89
74
 
@@ -108,7 +93,6 @@ query validation {
108
93
  zip: "90210"
109
94
  }
110
95
  locale: "en"
111
- matchingStrategy: LOCAL
112
96
  ) {
113
97
  validationScope
114
98
  concerns {
@@ -303,23 +287,24 @@ At the moment, `atlas_engine` supports advanced address validation for the follo
303
287
 
304
288
  | Country/territory | Two-letter code | Locales | Street | City | Postal Code | Province/State |
305
289
  |-------------------|-----------------|----------|--------|------|-------------|----------------|
306
- | Australia | AU | | | x | x | x |
307
- | Austria | AT | | | x | x | x |
308
- | Belgium | BE | fr,nl,de | | x | x | |
290
+ | Australia | AU | | x | x | x | x |
291
+ | Austria | AT | | x | x | x | x |
292
+ | Belgium | BE | fr,nl,de | x | x | x | |
309
293
  | Bermuda | BM | | | x | x | x |
310
294
  | Czechia | CZ | | | x | x | |
311
295
  | Denmark | DK | | | x | x | |
312
296
  | Faroe Islands | FO | | | x | x | |
313
- | France | FR | | | x | x | |
297
+ | France | FR | | x | x | x | |
298
+ | Gurnsey | GG | | | x | x | |
314
299
  | Italy | IT | | | | x | |
315
300
  | Liechtenstein | LI | | | x | x | x |
316
301
  | Luxembourg | LU | fr,lb | | x | x | |
317
- | Netherlands | NL | nl | | x | x | x |
318
- | Poland | PL | | | x | x | x |
302
+ | Netherlands | NL | nl | x | x | x | x |
303
+ | Poland | PL | | x | x | x | x |
319
304
  | Portugal | PT | | | x | x | x |
320
305
  | Slovenia | SI | | | x | x | x |
321
306
  | South Korea | KR | | | x | x | x |
322
- | Switzerland | CH | de,fr,it | | x | x | |
307
+ | Switzerland | CH | de,fr,it | x | x | x | |
323
308
  | United States | US | en | x | x | x | x |
324
309
 
325
310
  ### Downloading and indexing instructions
@@ -408,6 +393,20 @@ and the US data is in mysql the rest of the process for creating the elasticsear
408
393
 
409
394
  ## Elasticsearch Matching Strategy
410
395
 
396
+ An optional GraphQL parameter, and the strategy used to evaluate the validity of the address input. Out of the box, Atlas Engine
397
+ supports three different matching strategies: `local`, `es`, and `es_street`.
398
+ - `local` matching uses the [worldwide](https://github.com/Shopify/worldwide) gem to provide the most basic level of
399
+ address validation. This may include simple errors (required fields not populated) or more advanced errors (province
400
+ not belonging to the country, zip code not belonging to the province). This level of matching does not require
401
+ [ingestion](#ingestion) of country data to work, but the level of support and suggestions it can provide in its
402
+ responses is minimal.
403
+ - `es` matching uses data indexed in elasticsearch via our [ingestion](#ingestion) process to validate the city,
404
+ province, country, and zip code fields of the input address, in addition to all of the basic functionality provided
405
+ in the `local` strategy.
406
+ - `es_street` is our most advanced matching strategy and requires the highest quality data indexed in elasticsearch
407
+ via our [ingestion](#ingestion) process. This matching strategy provides everything that `es` and `local` does along
408
+ with validation of the address1 and address2 components of the address input.
409
+
411
410
  Once we have successfully created and activated an elasticsearch index using open address data, we may now use
412
411
  the more advanced elasticsearch matching strategies `es` and `es_street`.
413
412
 
@@ -653,3 +652,19 @@ will produce the response:
653
652
  ```
654
653
 
655
654
  This response has no concerns or suggestions, and the input address is therefore considered to be valid.
655
+
656
+ ## Hosted Solution
657
+
658
+ If you wish to use the Shopify hosted version of the `atlas_engine` codebase in your applications, you will need to [register for an api key](https://address-validation.shopify.dev/#request-api-key) and agree to our [terms and conditions](https://address-validation.shopify.dev/terms-of-service).
659
+
660
+ Once you have successfully redeemed an api key, you will be able to access the `/graphql` endpoint, which can be queried using this example curl request:
661
+
662
+ ```
663
+ curl --request POST \
664
+ --url https://atlas-validation.shopifyapps.com/graphql \
665
+ --header 'Authorization: Bearer {your-api-key}' \
666
+ --header 'Content-Type: application/json' \
667
+ --data '{"query":"query validation { validation(address: { address1: \"233 S Wacker Dr\" address2: \"\" city: \"Chicago\" countryCode: US provinceCode: \"IL\" zip: \"60606\" } locale: \"EN\" ) { validationScope concerns { code fieldNames suggestionIds type typeLevel message } suggestions { id address1 address2 city province provinceCode zip } }}","operationName":"validation"}'
668
+ ```
669
+
670
+ Any updates to the `atlas_engine` codebase that are merged into our `main` branch will be deployed to our hosted solution as well.
@@ -9,7 +9,7 @@ ingestion:
9
9
  data_mapper: AtlasEngine::AddressValidation::Es::DataMappers::DecompoundingDataMapper
10
10
  validation:
11
11
  enabled: true
12
- default_matching_strategy: es
12
+ default_matching_strategy: es_street
13
13
  has_provinces: true
14
14
  address_parser: AtlasEngine::At::ValidationTranscriber::AddressParser
15
15
  normalized_components:
@@ -8,6 +8,6 @@ ingestion:
8
8
  validation:
9
9
  address_parser: AtlasEngine::Au::ValidationTranscriber::AddressParser
10
10
  enabled: true
11
- default_matching_strategy: es
11
+ default_matching_strategy: es_street
12
12
  open_address:
13
13
  filter: AtlasEngine::Au::AddressImporter::OpenAddress::Filter
@@ -5,9 +5,9 @@ ingestion:
5
5
  max_zip_edge_ngram: "4"
6
6
  validation:
7
7
  enabled: true
8
- default_matching_strategy: local
8
+ default_matching_strategy: es_street
9
9
  address_parser: AtlasEngine::Be::ValidationTranscriber::AddressParser
10
- has_provinces: false
10
+ has_provinces: false
11
11
  index_locales:
12
12
  - fr
13
13
  - nl
@@ -1,7 +1,7 @@
1
1
  id: CH
2
2
  validation:
3
3
  enabled: true
4
- default_matching_strategy: local
4
+ default_matching_strategy: es_street
5
5
  has_provinces: false
6
6
  address_parser: AtlasEngine::De::ValidationTranscriber::AddressParser
7
7
  index_locales:
@@ -10,6 +10,6 @@ ingestion:
10
10
  validation:
11
11
  address_parser: AtlasEngine::Fr::ValidationTranscriber::AddressParser
12
12
  enabled: true
13
- default_matching_strategy: es
13
+ default_matching_strategy: es_street
14
14
  has_provinces: false
15
15
  zip_prefix_length: 3
@@ -7,7 +7,7 @@ ingestion:
7
7
  validation:
8
8
  enabled: true
9
9
  has_provinces: true
10
- default_matching_strategy: es
10
+ default_matching_strategy: es_street
11
11
  normalized_components:
12
12
  - street_decompounded
13
13
  address_parser: AtlasEngine::Nl::ValidationTranscriber::AddressParser
@@ -7,7 +7,7 @@ ingestion:
7
7
  validation:
8
8
  address_parser: AtlasEngine::Pl::ValidationTranscriber::AddressParser
9
9
  enabled: true
10
- default_matching_strategy: es
10
+ default_matching_strategy: es_street
11
11
  exclusions:
12
12
  city:
13
13
  - AtlasEngine::Pl::AddressValidation::Exclusions::RuralAddress
@@ -9,6 +9,7 @@ ingestion:
9
9
  validation:
10
10
  enabled: true
11
11
  default_matching_strategy: es_street
12
+ unmatched_components_suggestion_threshold: 1
12
13
  address_parser: AtlasEngine::ValidationTranscriber::AddressParserNorthAmerica
13
14
  open_address:
14
15
  filter: AtlasEngine::Us::AddressImporter::OpenAddress::Filter
@@ -6,8 +6,12 @@ input AddressInput {
6
6
  address2: String
7
7
  city: String
8
8
  countryCode: ValidationSupportedCountry
9
+ line2: String
10
+ neighborhood: String
9
11
  phone: String
10
12
  provinceCode: String
13
+ streetName: String
14
+ streetNumber: String
11
15
  zip: String
12
16
  }
13
17
 
@@ -43,8 +47,13 @@ enum MatchingStrategy {
43
47
  LOCAL
44
48
  }
45
49
 
50
+ enum MessageFormat {
51
+ INFORMATIVE
52
+ INSTRUCTIONAL
53
+ }
54
+
46
55
  type Query {
47
- validation(address: AddressInput!, locale: String!, matchingStrategy: MatchingStrategy): Validation!
56
+ validation(address: AddressInput!, locale: String!, matchingStrategy: MatchingStrategy, messageFormat: MessageFormat): Validation!
48
57
  }
49
58
 
50
59
  """
@@ -56,8 +65,12 @@ type Suggestion {
56
65
  city: String
57
66
  countryCode: ValidationSupportedCountry
58
67
  id: String!
68
+ line2: String
69
+ neighborhood: String
59
70
  province: String
60
71
  provinceCode: String
72
+ streetName: String
73
+ streetNumber: String
61
74
  zip: String
62
75
  }
63
76
 
@@ -12,7 +12,11 @@ module AtlasEngine
12
12
  description "Address fields used to fulfill a validation request"
13
13
 
14
14
  argument :address1, String, required: false
15
+ argument :street_name, String, required: false
16
+ argument :street_number, String, required: false
15
17
  argument :address2, String, required: false
18
+ argument :line2, String, required: false
19
+ argument :neighborhood, String, required: false
16
20
  argument :city, String, required: false
17
21
  argument :country_code, ValidationSupportedCountry, required: false
18
22
  argument :province_code, String, required: false
@@ -1,10 +1,12 @@
1
- # typed: false
1
+ # typed: true
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module AtlasEngine
5
5
  module Types
6
6
  module AddressValidation
7
7
  class ConcernType < BaseObject
8
+ extend T::Sig
9
+
8
10
  description "A piece of relevant information regarding the address validation result." \
9
11
  "They can be categorized as either a Warning or Error."
10
12
 
@@ -14,6 +16,11 @@ module AtlasEngine
14
16
  field :type, Enums::ConcernEnum, null: false
15
17
  field :type_level, Int, null: false
16
18
  field :suggestion_ids, [String], null: false
19
+
20
+ sig { returns(T::Array[String]) }
21
+ def field_names
22
+ object.field_names.map { |field_name| field_name.to_s.camelize(:lower) }
23
+ end
17
24
  end
18
25
  end
19
26
  end
@@ -9,7 +9,11 @@ module AtlasEngine
9
9
 
10
10
  field :id, String, null: false
11
11
  field :address1, String, null: true
12
+ field :street_name, String, null: true
13
+ field :street_number, String, null: true
12
14
  field :address2, String, null: true
15
+ field :line2, String, null: true
16
+ field :neighborhood, String, null: true
13
17
  field :city, String, null: true
14
18
  field :zip, String, null: true
15
19
  field :province_code, String, null: true
@@ -0,0 +1,11 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module AtlasEngine
5
+ module Types
6
+ class MessageFormatType < BaseEnum
7
+ value :INSTRUCTIONAL, value: "instructional"
8
+ value :INFORMATIVE, value: "informative"
9
+ end
10
+ end
11
+ end
@@ -10,9 +10,10 @@ module AtlasEngine
10
10
  argument :address, AddressValidation::AddressInput, required: true
11
11
  argument :locale, String, required: true
12
12
  argument :matching_strategy, MatchingStrategyType, required: false
13
+ argument :message_format, MessageFormatType, required: false
13
14
  end
14
15
 
15
- def validation(address:, locale: "en", matching_strategy: nil)
16
+ def validation(address:, locale: "en", matching_strategy: nil, message_format: nil)
16
17
  raise build_graphql_error(AtlasEngine::AddressValidation::Errors::MISSING_PARAMETER) if address.blank?
17
18
 
18
19
  locale = LocaleFormatHelper.format_locale(locale)
@@ -26,6 +27,7 @@ module AtlasEngine
26
27
  address: address,
27
28
  locale: locale,
28
29
  matching_strategy: matching_strategy,
30
+ message_format: message_format,
29
31
  ),
30
32
  )
31
33
  end
@@ -9,22 +9,27 @@ module AtlasEngine
9
9
 
10
10
  ParsedComponents = T.type_alias { T::Hash[Symbol, String] }
11
11
 
12
- sig { returns(T::Array[ParsedComponents]) }
13
- attr_reader :parsings
14
-
15
12
  sig { params(address_input: AddressValidation::AbstractAddress, locale: T.nilable(String)).void }
16
13
  def initialize(address_input:, locale: nil)
17
- @parsings = T.let(
14
+ @address_input = address_input
15
+ @locale = locale
16
+ end
17
+
18
+ sig { returns(T::Array[ParsedComponents]) }
19
+ def parsings
20
+ @parsings ||= T.let(
18
21
  begin
19
- if address_input.country_code.blank?
22
+ if @address_input.country_code.blank?
20
23
  []
21
- else
22
- parsing_result = AddressParserFactory.create(address: address_input, locale: locale).parse
23
- log_unparsable_address(address_input) if parsing_result.empty?
24
+ elsif @address_input.street_name.nil? && @address_input.street_number.nil?
25
+ parsing_result = AddressParserFactory.create(address: @address_input, locale: @locale).parse
26
+ log_unparsable_address(@address_input) if parsing_result.empty?
24
27
  parsing_result
28
+ else
29
+ [{ street: @address_input.street_name, building_num: @address_input.street_number }]
25
30
  end
26
31
  end,
27
- T::Array[ParsedComponents],
32
+ T.nilable(T::Array[ParsedComponents]),
28
33
  )
29
34
  end
30
35
 
@@ -22,7 +22,11 @@ module AtlasEngine
22
22
  sig do
23
23
  params(
24
24
  address1: String,
25
+ street_name: String,
26
+ street_number: String,
25
27
  address2: String,
28
+ line2: String,
29
+ neighborhood: String,
26
30
  city: String,
27
31
  province_code: String,
28
32
  zip: String,
@@ -30,10 +34,15 @@ module AtlasEngine
30
34
  phone: String,
31
35
  ).returns(AddressValidation::Address)
32
36
  end
33
- def build_address(address1: "", address2: "", city: "", province_code: "", zip: "", country_code: "", phone: "")
37
+ def build_address(address1: "", street_name: "", street_number: "", address2: "", line2: "", neighborhood: "",
38
+ city: "", province_code: "", zip: "", country_code: "", phone: "")
34
39
  AddressValidation::Address.new(
35
40
  address1: address1,
41
+ street_name: street_name,
42
+ street_number: street_number,
36
43
  address2: address2,
44
+ line2: line2,
45
+ neighborhood: neighborhood,
37
46
  city: city,
38
47
  province_code: province_code,
39
48
  zip: zip,
@@ -164,7 +164,7 @@ module AtlasEngine
164
164
 
165
165
  sig { params(value: String).returns(T::Boolean) }
166
166
  def include_fractions?(value)
167
- %r{^([0-9]+ )?([0-9]+/[0-9]+)?$}.match?(value)
167
+ %r{^([0-9]+ )?([0-9]+/[1-9][0-9]*)?$}.match?(value)
168
168
  end
169
169
 
170
170
  sig { params(str: String).returns(String) }
@@ -13,9 +13,21 @@ module AtlasEngine
13
13
  sig { abstract.returns(ComponentType) }
14
14
  def address1; end
15
15
 
16
+ sig { returns(ComponentType) }
17
+ def street_name; end
18
+
19
+ sig { returns(ComponentType) }
20
+ def street_number; end
21
+
16
22
  sig { abstract.returns(ComponentType) }
17
23
  def address2; end
18
24
 
25
+ sig { returns(ComponentType) }
26
+ def line2; end
27
+
28
+ sig { returns(ComponentType) }
29
+ def neighborhood; end
30
+
19
31
  sig { abstract.returns(ComponentType) }
20
32
  def city; end
21
33
 
@@ -13,7 +13,11 @@ module AtlasEngine
13
13
  AddressInput = T.type_alias { Types::AddressValidation::AddressInput }
14
14
 
15
15
  const :address1, ComponentType
16
+ const :street_name, ComponentType
17
+ const :street_number, ComponentType
16
18
  const :address2, ComponentType
19
+ const :line2, ComponentType
20
+ const :neighborhood, ComponentType
17
21
  const :city, ComponentType
18
22
  const :province_code, ComponentType
19
23
  const :phone, ComponentType
@@ -33,7 +37,11 @@ module AtlasEngine
33
37
  def from_address(address:)
34
38
  new(
35
39
  address1: address.address1,
40
+ street_name: address.street_name,
41
+ street_number: address.street_number,
36
42
  address2: address.address2,
43
+ line2: address.line2,
44
+ neighborhood: address.neighborhood,
37
45
  city: address.city,
38
46
  country_code: address.country_code,
39
47
  province_code: address.province_code,
@@ -9,9 +9,21 @@ module AtlasEngine
9
9
  sig { returns(String) }
10
10
  attr_reader :address1
11
11
 
12
+ sig { returns(String) }
13
+ attr_reader :street_name
14
+
15
+ sig { returns(String) }
16
+ attr_reader :street_number
17
+
12
18
  sig { returns(String) }
13
19
  attr_reader :address2
14
20
 
21
+ sig { returns(String) }
22
+ attr_reader :line2
23
+
24
+ sig { returns(String) }
25
+ attr_reader :neighborhood
26
+
15
27
  sig { returns(String) }
16
28
  attr_reader :city
17
29
 
@@ -73,7 +85,11 @@ module AtlasEngine
73
85
  timestamp: Time,
74
86
  origin: String,
75
87
  address1: String,
88
+ street_name: String,
89
+ street_number: String,
76
90
  address2: String,
91
+ line2: String,
92
+ neighborhood: String,
77
93
  city: String,
78
94
  province_code: String,
79
95
  country_code: String,
@@ -87,7 +103,11 @@ module AtlasEngine
87
103
  timestamp: Time.zone.now,
88
104
  origin: "",
89
105
  address1: "",
106
+ street_name: "",
107
+ street_number: "",
90
108
  address2: "",
109
+ line2: "",
110
+ neighborhood: "",
91
111
  city: "",
92
112
  province_code: "",
93
113
  country_code: "",
@@ -100,7 +120,11 @@ module AtlasEngine
100
120
  @timestamp = timestamp
101
121
  @origin = origin
102
122
  @address1 = address1
123
+ @street_name = street_name
124
+ @street_number = street_number
103
125
  @address2 = address2
126
+ @line2 = line2
127
+ @neighborhood = neighborhood
104
128
  @city = city
105
129
  @province_code = province_code
106
130
  @country_code = country_code
@@ -114,7 +138,11 @@ module AtlasEngine
114
138
  def address_attributes
115
139
  {
116
140
  address1: address1,
141
+ street_name: street_name,
142
+ street_number: street_number,
117
143
  address2: address2,
144
+ line2: line2,
145
+ neighborhood: neighborhood,
118
146
  city: city,
119
147
  province_code: province_code,
120
148
  zip: zip,
@@ -8,12 +8,13 @@ module AtlasEngine
8
8
  class FullAddress < FullAddressValidatorBase
9
9
  include LogHelper
10
10
 
11
- attr_reader :address, :result
11
+ attr_reader :address, :result, :message_format
12
12
 
13
- sig { params(address: TAddress, result: Result).void }
14
- def initialize(address:, result: Result.new)
13
+ sig { params(address: TAddress, result: Result, message_format: MessageFormat).void }
14
+ def initialize(address:, result: Result.new, message_format: MessageFormat::Instructional)
15
15
  super
16
16
  @matching_strategy = MatchingStrategies::Es
17
+ @message_format = message_format
17
18
  end
18
19
 
19
20
  sig { override.returns(Result) }
@@ -29,16 +30,23 @@ module AtlasEngine
29
30
  sig { returns(AddressValidation::Validators::FullAddress::CandidateResultBase) }
30
31
  def build_candidate_result
31
32
  unless supported_address?(address)
32
- return AddressValidation::Validators::FullAddress::UnsupportedScriptResult.new(address:, result:)
33
+ return AddressValidation::Validators::FullAddress::UnsupportedScriptResult.new(
34
+ address:,
35
+ result:,
36
+ message_format:,
37
+ )
33
38
  end
34
39
 
35
40
  if best_candidate.nil?
36
- AddressValidation::Validators::FullAddress::NoCandidateResult.new(address:, result:)
41
+ AddressValidation::Validators::FullAddress::NoCandidateResult.new(
42
+ address:, result:, message_format:,
43
+ )
37
44
  else
38
45
  AddressValidation::Validators::FullAddress::CandidateResult.new(
39
46
  address_comparison: T.must(best_candidate),
40
47
  matching_strategy: @matching_strategy,
41
48
  result: result,
49
+ message_format:,
42
50
  )
43
51
  end
44
52
  end
@@ -100,6 +108,10 @@ module AtlasEngine
100
108
  :zip,
101
109
  :address1,
102
110
  :address2,
111
+ :street_name,
112
+ :street_number,
113
+ :neighborhood,
114
+ :line2,
103
115
  ])
104
116
  end
105
117
 
@@ -108,6 +120,7 @@ module AtlasEngine
108
120
  result.concerns.flat_map(&:code).intersect?([
109
121
  :address1_contains_too_many_words,
110
122
  :address2_contains_too_many_words,
123
+ :street_name_contains_too_many_words,
111
124
  ])
112
125
  end
113
126
 
@@ -6,8 +6,8 @@ module AtlasEngine
6
6
  module Es
7
7
  module Validators
8
8
  class FullAddressStreet < FullAddress
9
- sig { params(address: TAddress, result: Result).void }
10
- def initialize(address:, result: Result.new)
9
+ sig { params(address: TAddress, message_format: MessageFormat, result: Result).void }
10
+ def initialize(address:, message_format:, result: Result.new)
11
11
  super
12
12
  @matching_strategy = MatchingStrategies::EsStreet
13
13
  end
@@ -14,10 +14,14 @@ module AtlasEngine
14
14
  sig { returns(AbstractAddress) }
15
15
  attr_reader :address
16
16
 
17
- sig { params(address: AbstractAddress, result: Result).void }
18
- def initialize(address:, result:)
17
+ sig { returns(MessageFormat) }
18
+ attr_reader :message_format
19
+
20
+ sig { params(address: AbstractAddress, result: Result, message_format: MessageFormat).void }
21
+ def initialize(address:, result:, message_format: MessageFormat::Instructional)
19
22
  @address = address
20
23
  @result = result
24
+ @message_format = message_format
21
25
  end
22
26
 
23
27
  sig { abstract.returns(Result) }
@@ -0,0 +1,13 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module AtlasEngine
5
+ module AddressValidation
6
+ class MessageFormat < T::Enum
7
+ enums do
8
+ Instructional = new("instructional")
9
+ Informative = new("informative")
10
+ end
11
+ end
12
+ end
13
+ end