atlas_engine 1.0.0 → 1.2.0

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