atlas_engine 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +123 -0
- data/Rakefile +20 -0
- data/app/assets/config/atlas_engine_manifest.js +3 -0
- data/app/assets/stylesheets/atlas_engine/application.css +15 -0
- data/app/concerns/atlas_engine/handles_blob.rb +26 -0
- data/app/concerns/atlas_engine/handles_interruption.rb +22 -0
- data/app/controllers/atlas_engine/application_controller.rb +7 -0
- data/app/controllers/atlas_engine/connectivity_controller.rb +21 -0
- data/app/controllers/atlas_engine/country_imports_controller.rb +73 -0
- data/app/controllers/atlas_engine/graphql_controller.rb +59 -0
- data/app/countries/atlas_engine/ar/country_profile.yml +9 -0
- data/app/countries/atlas_engine/at/address_importer/corrections/open_address/city_corrector.rb +23 -0
- data/app/countries/atlas_engine/at/country_profile.yml +24 -0
- data/app/countries/atlas_engine/at/index_configuration.yml +63 -0
- data/app/countries/atlas_engine/at/synonyms.yml +6 -0
- data/app/countries/atlas_engine/at/validation_transcriber/address_parser.rb +58 -0
- data/app/countries/atlas_engine/au/address_importer/open_address/filter.rb +26 -0
- data/app/countries/atlas_engine/au/address_importer/open_address/mapper.rb +41 -0
- data/app/countries/atlas_engine/au/country_profile.yml +13 -0
- data/app/countries/atlas_engine/au/synonyms.yml +209 -0
- data/app/countries/atlas_engine/au/validation_transcriber/address_parser.rb +121 -0
- data/app/countries/atlas_engine/be/country_profile.yml +12 -0
- data/app/countries/atlas_engine/bm/address_importer/corrections/open_address/city_alias_corrector.rb +38 -0
- data/app/countries/atlas_engine/bm/address_importer/open_address/mapper.rb +40 -0
- data/app/countries/atlas_engine/bm/country_profile.yml +12 -0
- data/app/countries/atlas_engine/br/country_profile.yml +4 -0
- data/app/countries/atlas_engine/ca/country_profile.yml +7 -0
- data/app/countries/atlas_engine/ca/synonyms.yml +1615 -0
- data/app/countries/atlas_engine/ch/address_importer/corrections/open_address/city_corrector.rb +29 -0
- data/app/countries/atlas_engine/ch/address_importer/corrections/open_address/locale_corrector.rb +74 -0
- data/app/countries/atlas_engine/ch/address_importer/open_address/mapper.rb +40 -0
- data/app/countries/atlas_engine/ch/country_profile.yml +15 -0
- data/app/countries/atlas_engine/ch/locales/de/country_profile.yml +15 -0
- data/app/countries/atlas_engine/ch/locales/de/index_configuration.yml +63 -0
- data/app/countries/atlas_engine/ch/locales/de/synonyms.yml +7 -0
- data/app/countries/atlas_engine/ch/locales/fr/synonyms.yml +21 -0
- data/app/countries/atlas_engine/cz/country_profile.yml +6 -0
- data/app/countries/atlas_engine/de/country_profile.yml +19 -0
- data/app/countries/atlas_engine/de/index_configuration.yml +64 -0
- data/app/countries/atlas_engine/de/synonyms.yml +2 -0
- data/app/countries/atlas_engine/de/validation_transcriber/address_parser.rb +19 -0
- data/app/countries/atlas_engine/dk/country_profile.yml +6 -0
- data/app/countries/atlas_engine/dk/synonyms.yml +3 -0
- data/app/countries/atlas_engine/dk/validation_transcriber/address_parser.rb +21 -0
- data/app/countries/atlas_engine/fo/country_profile.yml +5 -0
- data/app/countries/atlas_engine/fr/address_importer/corrections/open_address/city_corrector.rb +28 -0
- data/app/countries/atlas_engine/fr/country_profile.yml +13 -0
- data/app/countries/atlas_engine/fr/synonyms.yml +21 -0
- data/app/countries/atlas_engine/fr/validation_transcriber/address_parser.rb +34 -0
- data/app/countries/atlas_engine/gb/address_validation/es/query_builder.rb +98 -0
- data/app/countries/atlas_engine/gb/country_profile.yml +10 -0
- data/app/countries/atlas_engine/gb/validation_transcriber/full_address_parser.rb +164 -0
- data/app/countries/atlas_engine/gb/validation_transcriber/parsed_address.rb +120 -0
- data/app/countries/atlas_engine/gg/address_validation/validators/full_address/restrictions/unsupported_city.rb +39 -0
- data/app/countries/atlas_engine/gg/country_profile.yml +7 -0
- data/app/countries/atlas_engine/ie/country_profile.yml +3 -0
- data/app/countries/atlas_engine/it/address_importer/corrections/open_address/city_corrector.rb +27 -0
- data/app/countries/atlas_engine/it/address_importer/corrections/open_address/province_corrector.rb +29 -0
- data/app/countries/atlas_engine/it/address_importer/open_address/mapper.rb +42 -0
- data/app/countries/atlas_engine/it/country_profile.yml +11 -0
- data/app/countries/atlas_engine/jp/address_validation/es/data_mapper.rb +63 -0
- data/app/countries/atlas_engine/jp/country_profile.yml +6 -0
- data/app/countries/atlas_engine/kr/address_importer/open_address/mapper.rb +41 -0
- data/app/countries/atlas_engine/kr/country_profile.yml +11 -0
- data/app/countries/atlas_engine/li/address_importer/corrections/open_address/city_corrector.rb +25 -0
- data/app/countries/atlas_engine/li/country_profile.yml +21 -0
- data/app/countries/atlas_engine/li/index_configuration.yml +63 -0
- data/app/countries/atlas_engine/li/synonyms.yml +6 -0
- data/app/countries/atlas_engine/lt/country_profile.yml +6 -0
- data/app/countries/atlas_engine/lt/synonyms.yml +7 -0
- data/app/countries/atlas_engine/lt/validation_transcriber/address_parser.rb +24 -0
- data/app/countries/atlas_engine/lu/address_importer/corrections/open_address/locale_corrector.rb +54 -0
- data/app/countries/atlas_engine/lu/country_profile.yml +12 -0
- data/app/countries/atlas_engine/nl/address_importer/corrections/open_address/city_corrector.rb +25 -0
- data/app/countries/atlas_engine/nl/country_profile.yml +18 -0
- data/app/countries/atlas_engine/nl/index_configuration.yml +52 -0
- data/app/countries/atlas_engine/nl/synonyms.yml +92 -0
- data/app/countries/atlas_engine/nl/validation_transcriber/address_parser.rb +85 -0
- data/app/countries/atlas_engine/no/country_profile.yml +5 -0
- data/app/countries/atlas_engine/nz/country_profile.yml +3 -0
- data/app/countries/atlas_engine/pl/country_profile.yml +5 -0
- data/app/countries/atlas_engine/pl/validation_transcriber/address_parser.rb +19 -0
- data/app/countries/atlas_engine/pt/address_importer/corrections/open_address/city_corrector.rb +32 -0
- data/app/countries/atlas_engine/pt/address_importer/open_address/mapper.rb +39 -0
- data/app/countries/atlas_engine/pt/country_profile.yml +10 -0
- data/app/countries/atlas_engine/pt/synonyms.yml +7 -0
- data/app/countries/atlas_engine/sa/country_profile.yml +10 -0
- data/app/countries/atlas_engine/se/country_profile.yml +5 -0
- data/app/countries/atlas_engine/tt/address_importer/open_address/mapper.rb +38 -0
- data/app/countries/atlas_engine/tt/country_profile.yml +7 -0
- data/app/countries/atlas_engine/us/country_profile.yml +12 -0
- data/app/countries/atlas_engine/us/synonyms.yml +350 -0
- data/app/graphql/atlas_engine/errors/locale_unsupported_error.rb +17 -0
- data/app/graphql/atlas_engine/schema.graphql +1293 -0
- data/app/graphql/atlas_engine/schema.rb +23 -0
- data/app/graphql/atlas_engine/types/address_validation/address_input.rb +51 -0
- data/app/graphql/atlas_engine/types/address_validation/concern_type.rb +20 -0
- data/app/graphql/atlas_engine/types/address_validation/enums/concern_enum.rb +15 -0
- data/app/graphql/atlas_engine/types/address_validation/field_type.rb +15 -0
- data/app/graphql/atlas_engine/types/address_validation/suggestion_type.rb +21 -0
- data/app/graphql/atlas_engine/types/base_argument.rb +9 -0
- data/app/graphql/atlas_engine/types/base_enum.rb +9 -0
- data/app/graphql/atlas_engine/types/base_field.rb +10 -0
- data/app/graphql/atlas_engine/types/base_input_object.rb +9 -0
- data/app/graphql/atlas_engine/types/base_interface.rb +10 -0
- data/app/graphql/atlas_engine/types/base_object.rb +9 -0
- data/app/graphql/atlas_engine/types/base_scalar.rb +9 -0
- data/app/graphql/atlas_engine/types/base_union.rb +9 -0
- data/app/graphql/atlas_engine/types/matching_strategy_type.rb +12 -0
- data/app/graphql/atlas_engine/types/mutation_type.rb +9 -0
- data/app/graphql/atlas_engine/types/query_type.rb +61 -0
- data/app/graphql/atlas_engine/types/validation_supported_country.rb +12 -0
- data/app/graphql/atlas_engine/types/validation_type.rb +22 -0
- data/app/helpers/atlas_engine/address_importer/import_log_helper.rb +66 -0
- data/app/helpers/atlas_engine/application_helper.rb +7 -0
- data/app/helpers/atlas_engine/locale_format_helper.rb +40 -0
- data/app/helpers/atlas_engine/log_base.rb +32 -0
- data/app/helpers/atlas_engine/log_helper.rb +24 -0
- data/app/helpers/atlas_engine/metrics_helper.rb +25 -0
- data/app/jobs/atlas_engine/address_importer/clear_records_job.rb +39 -0
- data/app/jobs/atlas_engine/address_importer/open_address/geo_json_import_job.rb +212 -0
- data/app/jobs/atlas_engine/address_importer/open_address/geo_json_import_launcher_job.rb +67 -0
- data/app/jobs/atlas_engine/address_importer/open_address/prepares_geo_json_file.rb +41 -0
- data/app/jobs/atlas_engine/address_importer/resumable_import_job.rb +49 -0
- data/app/jobs/atlas_engine/address_importer/street_backfill_job.rb +63 -0
- data/app/jobs/atlas_engine/application_job.rb +10 -0
- data/app/jobs/atlas_engine/concerns/address_importer/handles_errors.rb +43 -0
- data/app/lib/atlas_engine/concern_formatter.rb +40 -0
- data/app/lib/atlas_engine/restrictions/base.rb +20 -0
- data/app/lib/atlas_engine/restrictions/unsupported_script.rb +31 -0
- data/app/lib/atlas_engine/validation_transcriber/address_parser_base.rb +201 -0
- data/app/lib/atlas_engine/validation_transcriber/address_parser_factory.rb +27 -0
- data/app/lib/atlas_engine/validation_transcriber/address_parser_north_america.rb +39 -0
- data/app/lib/atlas_engine/validation_transcriber/address_parser_oceanic.rb +17 -0
- data/app/lib/atlas_engine/validation_transcriber/address_parser_preprocessor.rb +132 -0
- data/app/lib/atlas_engine/validation_transcriber/address_parsing_helper.rb +38 -0
- data/app/lib/atlas_engine/validation_transcriber/address_parsings.rb +54 -0
- data/app/lib/atlas_engine/validation_transcriber/constants.rb +50 -0
- data/app/lib/atlas_engine/validation_transcriber/english_street_parser.rb +59 -0
- data/app/lib/atlas_engine/validation_transcriber/formatter.rb +46 -0
- data/app/lib/atlas_engine/validation_transcriber/french_street_parser.rb +50 -0
- data/app/lib/atlas_engine/validation_transcriber/province_code_normalizer.rb +45 -0
- data/app/lib/atlas_engine/validation_transcriber/street_parser.rb +18 -0
- data/app/lib/atlas_engine/validation_transcriber/zip_normalizer.rb +23 -0
- data/app/mailers/atlas_engine/application_mailer.rb +9 -0
- data/app/models/atlas_engine/address_importer/corrections/corrector.rb +33 -0
- data/app/models/atlas_engine/address_importer/import_events_notifier/base.rb +35 -0
- data/app/models/atlas_engine/address_importer/import_events_notifier/notifier.rb +26 -0
- data/app/models/atlas_engine/address_importer/open_address/default_mapper.rb +46 -0
- data/app/models/atlas_engine/address_importer/open_address/feature_helper.rb +110 -0
- data/app/models/atlas_engine/address_importer/open_address/filter.rb +17 -0
- data/app/models/atlas_engine/address_importer/open_address/loader.rb +27 -0
- data/app/models/atlas_engine/address_importer/open_address/transformer.rb +39 -0
- data/app/models/atlas_engine/address_importer/open_address.rb +10 -0
- data/app/models/atlas_engine/address_importer/validation/base_validator.rb +86 -0
- data/app/models/atlas_engine/address_importer/validation/default_validator.rb +27 -0
- data/app/models/atlas_engine/address_importer/validation/field_validations/city.rb +47 -0
- data/app/models/atlas_engine/address_importer/validation/field_validations/interface.rb +29 -0
- data/app/models/atlas_engine/address_importer/validation/field_validations/province.rb +73 -0
- data/app/models/atlas_engine/address_importer/validation/field_validations/zip.rb +84 -0
- data/app/models/atlas_engine/address_importer/validation/validator.rb +17 -0
- data/app/models/atlas_engine/address_importer/validation/wrapper.rb +70 -0
- data/app/models/atlas_engine/address_number.rb +36 -0
- data/app/models/atlas_engine/address_number_range.rb +200 -0
- data/app/models/atlas_engine/address_validation/abstract_address.rb +49 -0
- data/app/models/atlas_engine/address_validation/address.rb +47 -0
- data/app/models/atlas_engine/address_validation/candidate.rb +109 -0
- data/app/models/atlas_engine/address_validation/candidate_tuple.rb +15 -0
- data/app/models/atlas_engine/address_validation/concern.rb +74 -0
- data/app/models/atlas_engine/address_validation/concern_producer.rb +19 -0
- data/app/models/atlas_engine/address_validation/concern_queue.rb +20 -0
- data/app/models/atlas_engine/address_validation/concern_record.rb +122 -0
- data/app/models/atlas_engine/address_validation/datastore_base.rb +27 -0
- data/app/models/atlas_engine/address_validation/errors.rb +13 -0
- data/app/models/atlas_engine/address_validation/es/candidate_selector.rb +70 -0
- data/app/models/atlas_engine/address_validation/es/data_mappers/decompounding_data_mapper.rb +39 -0
- data/app/models/atlas_engine/address_validation/es/data_mappers/default_data_mapper.rb +110 -0
- data/app/models/atlas_engine/address_validation/es/datastore.rb +229 -0
- data/app/models/atlas_engine/address_validation/es/default_query_builder.rb +30 -0
- data/app/models/atlas_engine/address_validation/es/query_builder.rb +160 -0
- data/app/models/atlas_engine/address_validation/es/term_vectors.rb +78 -0
- data/app/models/atlas_engine/address_validation/es/validators/full_address.rb +123 -0
- data/app/models/atlas_engine/address_validation/es/validators/full_address_street.rb +18 -0
- data/app/models/atlas_engine/address_validation/es/validators/restriction_evaluator.rb +37 -0
- data/app/models/atlas_engine/address_validation/field.rb +30 -0
- data/app/models/atlas_engine/address_validation/full_address_validator_base.rb +27 -0
- data/app/models/atlas_engine/address_validation/log_emitter.rb +66 -0
- data/app/models/atlas_engine/address_validation/matching_strategies.rb +16 -0
- data/app/models/atlas_engine/address_validation/normalizer.rb +38 -0
- data/app/models/atlas_engine/address_validation/predicate_pipeline.rb +80 -0
- data/app/models/atlas_engine/address_validation/request.rb +12 -0
- data/app/models/atlas_engine/address_validation/result.rb +154 -0
- data/app/models/atlas_engine/address_validation/runs_validation.rb +16 -0
- data/app/models/atlas_engine/address_validation/session.rb +47 -0
- data/app/models/atlas_engine/address_validation/statsd_emitter.rb +72 -0
- data/app/models/atlas_engine/address_validation/strategies.rb +10 -0
- data/app/models/atlas_engine/address_validation/suggestion.rb +97 -0
- data/app/models/atlas_engine/address_validation/token/comparator.rb +44 -0
- data/app/models/atlas_engine/address_validation/token/comparison.rb +76 -0
- data/app/models/atlas_engine/address_validation/token/sequence/comparator.rb +158 -0
- data/app/models/atlas_engine/address_validation/token/sequence/comparison.rb +166 -0
- data/app/models/atlas_engine/address_validation/token/sequence.rb +147 -0
- data/app/models/atlas_engine/address_validation/token/synonyms.rb +77 -0
- data/app/models/atlas_engine/address_validation/token.rb +113 -0
- data/app/models/atlas_engine/address_validation/validator.rb +147 -0
- data/app/models/atlas_engine/address_validation/validators/full_address/address_comparison.rb +97 -0
- data/app/models/atlas_engine/address_validation/validators/full_address/candidate_result.rb +164 -0
- data/app/models/atlas_engine/address_validation/validators/full_address/candidate_result_base.rb +46 -0
- data/app/models/atlas_engine/address_validation/validators/full_address/comparison_helper.rb +135 -0
- data/app/models/atlas_engine/address_validation/validators/full_address/components_to_validate.rb +88 -0
- data/app/models/atlas_engine/address_validation/validators/full_address/concern_builder.rb +127 -0
- data/app/models/atlas_engine/address_validation/validators/full_address/exclusions/exclusion_base.rb +23 -0
- data/app/models/atlas_engine/address_validation/validators/full_address/invalid_zip_concern_builder.rb +42 -0
- data/app/models/atlas_engine/address_validation/validators/full_address/invalid_zip_for_country_concern.rb +37 -0
- data/app/models/atlas_engine/address_validation/validators/full_address/invalid_zip_for_province_concern.rb +37 -0
- data/app/models/atlas_engine/address_validation/validators/full_address/no_candidate_result.rb +26 -0
- data/app/models/atlas_engine/address_validation/validators/full_address/number_comparison.rb +31 -0
- data/app/models/atlas_engine/address_validation/validators/full_address/postal_code_matcher.rb +60 -0
- data/app/models/atlas_engine/address_validation/validators/full_address/result_updater.rb +42 -0
- data/app/models/atlas_engine/address_validation/validators/full_address/suggestion_builder.rb +140 -0
- data/app/models/atlas_engine/address_validation/validators/full_address/unknown_address_concern.rb +30 -0
- data/app/models/atlas_engine/address_validation/validators/full_address/unknown_province_concern.rb +38 -0
- data/app/models/atlas_engine/address_validation/validators/full_address/unknown_zip_for_address_concern.rb +32 -0
- data/app/models/atlas_engine/address_validation/validators/full_address/unmatched_field_concern.rb +84 -0
- data/app/models/atlas_engine/address_validation/validators/full_address/unsupported_script_result.rb +22 -0
- data/app/models/atlas_engine/address_validation/validators/predicates/cache.rb +38 -0
- data/app/models/atlas_engine/address_validation/validators/predicates/city/present.rb +36 -0
- data/app/models/atlas_engine/address_validation/validators/predicates/country/exists.rb +34 -0
- data/app/models/atlas_engine/address_validation/validators/predicates/country/valid_for_zip.rb +60 -0
- data/app/models/atlas_engine/address_validation/validators/predicates/no_emojis.rb +38 -0
- data/app/models/atlas_engine/address_validation/validators/predicates/no_html_tags.rb +39 -0
- data/app/models/atlas_engine/address_validation/validators/predicates/no_url.rb +38 -0
- data/app/models/atlas_engine/address_validation/validators/predicates/not_exceed_max_length.rb +34 -0
- data/app/models/atlas_engine/address_validation/validators/predicates/not_exceed_max_token_count.rb +63 -0
- data/app/models/atlas_engine/address_validation/validators/predicates/phone/valid.rb +41 -0
- data/app/models/atlas_engine/address_validation/validators/predicates/predicate.rb +37 -0
- data/app/models/atlas_engine/address_validation/validators/predicates/province/exists.rb +43 -0
- data/app/models/atlas_engine/address_validation/validators/predicates/province/valid_for_country.rb +48 -0
- data/app/models/atlas_engine/address_validation/validators/predicates/street/building_number_in_address1.rb +45 -0
- data/app/models/atlas_engine/address_validation/validators/predicates/street/building_number_in_address1_or_address2.rb +43 -0
- data/app/models/atlas_engine/address_validation/validators/predicates/street/present.rb +35 -0
- data/app/models/atlas_engine/address_validation/validators/predicates/zip/present.rb +58 -0
- data/app/models/atlas_engine/address_validation/validators/predicates/zip/valid_for_country.rb +45 -0
- data/app/models/atlas_engine/address_validation/validators/predicates/zip/valid_for_province.rb +55 -0
- data/app/models/atlas_engine/address_validation/validators/predicates/zip/zip_base.rb +25 -0
- data/app/models/atlas_engine/address_validation/zip_truncator.rb +32 -0
- data/app/models/atlas_engine/application_record.rb +8 -0
- data/app/models/atlas_engine/coded_error.rb +18 -0
- data/app/models/atlas_engine/coded_errors.rb +17 -0
- data/app/models/atlas_engine/country_import.rb +44 -0
- data/app/models/atlas_engine/country_profile.rb +270 -0
- data/app/models/atlas_engine/country_profile_ingestion_subset.rb +42 -0
- data/app/models/atlas_engine/country_profile_subset_base.rb +22 -0
- data/app/models/atlas_engine/country_profile_validation_subset.rb +48 -0
- data/app/models/atlas_engine/country_repository.rb +110 -0
- data/app/models/atlas_engine/elasticsearch/client.rb +116 -0
- data/app/models/atlas_engine/elasticsearch/client_interface.rb +89 -0
- data/app/models/atlas_engine/elasticsearch/repository.rb +246 -0
- data/app/models/atlas_engine/elasticsearch/repository_interface.rb +82 -0
- data/app/models/atlas_engine/elasticsearch/response.rb +20 -0
- data/app/models/atlas_engine/event.rb +12 -0
- data/app/models/atlas_engine/field_decompounder.rb +36 -0
- data/app/models/atlas_engine/index_configuration_factory.rb +188 -0
- data/app/models/atlas_engine/post_address.rb +114 -0
- data/app/models/atlas_engine/post_address_importer.rb +34 -0
- data/app/models/atlas_engine/services/service_helper.rb +21 -0
- data/app/models/atlas_engine/services/validation.rb +65 -0
- data/app/models/atlas_engine/services/validation_eligibility.rb +18 -0
- data/app/models/atlas_engine/street.rb +34 -0
- data/app/tasks/maintenance/atlas_engine/elasticsearch_index_create_task.rb +106 -0
- data/app/tasks/maintenance/atlas_engine/geo_json_import_task.rb +29 -0
- data/app/views/atlas_engine/connectivity/index.html.erb +50 -0
- data/app/views/atlas_engine/country_imports/index.html.erb +49 -0
- data/app/views/atlas_engine/country_imports/show.html.erb +73 -0
- data/app/views/layouts/atlas_engine/application.html.erb +15 -0
- data/config/initializers/1.ruby_patches.rb +18 -0
- data/config/initializers/sorbet.rb +5 -0
- data/config/initializers/worldwide.rb +5 -0
- data/config/locales/internal/en.yml +14 -0
- data/config/routes.rb +17 -0
- data/db/data/address_synonyms/index_configurations/default.yml +141 -0
- data/db/data/country_profiles/default.yml +23 -0
- data/db/data/transcriber.yml +760 -0
- data/db/data/validation_pipelines/es.yml +58 -0
- data/db/data/validation_pipelines/es_street.yml +58 -0
- data/db/data/validation_pipelines/local.yml +60 -0
- data/db/migrate/20230919173037_create_atlas_engine_post_addresses.rb +25 -0
- data/db/migrate/20231117142735_add_building_and_unit_ranges_column.rb +7 -0
- data/db/migrate/20231117143536_create_atlas_engine_country_imports.rb +11 -0
- data/db/migrate/20231117145844_create_atlas_engine_events_table.rb +13 -0
- data/db/migrate/20231123153554_add_unique_index_to_atlas_engine_post_addresses.rb +14 -0
- data/db/migrate/20231123154658_add_index_to_post_addresses_on_source_id_locale_country_code.rb +12 -0
- data/lib/atlas_engine/engine.rb +10 -0
- data/lib/atlas_engine/version.rb +6 -0
- data/lib/atlas_engine.rb +66 -0
- data/lib/tasks/atlas_engine/address_importer.rake +20 -0
- metadata +553 -0
@@ -0,0 +1,34 @@
|
|
1
|
+
# typed: false
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "csv"
|
5
|
+
|
6
|
+
module AtlasEngine
|
7
|
+
class PostAddressImporter
|
8
|
+
def initialize(file)
|
9
|
+
@file = file
|
10
|
+
end
|
11
|
+
|
12
|
+
def import
|
13
|
+
CSV.foreach(@file, headers: true) do |row|
|
14
|
+
PostAddress.create!(
|
15
|
+
source_id: row["source_id"],
|
16
|
+
locale: row["locale"],
|
17
|
+
country_code: row["country_code"],
|
18
|
+
province_code: row["province_code"],
|
19
|
+
region1: row["region1"],
|
20
|
+
region2: row["region2"],
|
21
|
+
region3: row["region3"],
|
22
|
+
region4: row["region4"],
|
23
|
+
city: row["city"],
|
24
|
+
suburb: row["suburb"],
|
25
|
+
zip: row["zip"],
|
26
|
+
street: row["street"],
|
27
|
+
building_name: row["building_name"],
|
28
|
+
latitude: row["latitude"],
|
29
|
+
longitude: row["longitude"],
|
30
|
+
)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# typed: true
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module AtlasEngine
|
5
|
+
module Services
|
6
|
+
module ServiceHelper
|
7
|
+
def handle_metrics(request_type, country_code, using_session_token)
|
8
|
+
result = yield
|
9
|
+
|
10
|
+
ActiveSupport::Notifications.instrument("atlas.service.events", {
|
11
|
+
request_type: request_type,
|
12
|
+
country_code: country_code,
|
13
|
+
using_session_token: using_session_token,
|
14
|
+
result: result,
|
15
|
+
})
|
16
|
+
|
17
|
+
result
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# typed: true
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module AtlasEngine
|
5
|
+
module Services
|
6
|
+
class Validation
|
7
|
+
extend T::Sig
|
8
|
+
VALIDATE_ADDRESS = "validate_address"
|
9
|
+
|
10
|
+
class << self
|
11
|
+
extend T::Sig
|
12
|
+
include ServiceHelper
|
13
|
+
T.unsafe(self).include(AtlasEngine.validation_eligibility.constantize)
|
14
|
+
|
15
|
+
sig { params(request: AddressValidation::Request).returns(AddressValidation::Result) }
|
16
|
+
def validate_address(request)
|
17
|
+
country_code = request.address.country_code
|
18
|
+
handle_metrics(Validation::VALIDATE_ADDRESS, country_code, false) do
|
19
|
+
matching_strategy = if validation_enabled?(request.address)
|
20
|
+
serialize_strategy(request.matching_strategy, request.address)
|
21
|
+
else
|
22
|
+
AddressValidation::MatchingStrategies::Local
|
23
|
+
end
|
24
|
+
|
25
|
+
validator = AddressValidation::Validator.new(
|
26
|
+
address: request.address,
|
27
|
+
locale: request.locale,
|
28
|
+
matching_strategy: matching_strategy,
|
29
|
+
context: request.address.context.to_h,
|
30
|
+
)
|
31
|
+
result = validator.run
|
32
|
+
|
33
|
+
AddressValidation::StatsdEmitter.new(address: request.address, result: result).run
|
34
|
+
AddressValidation::LogEmitter.new(address: request.address, result: result).run
|
35
|
+
|
36
|
+
if Rails.configuration.x.captured_concerns.enabled
|
37
|
+
AddressValidation::ConcernProducer.add(result, request.address.context.to_h)
|
38
|
+
end
|
39
|
+
|
40
|
+
result
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
sig do
|
47
|
+
params(
|
48
|
+
request_matching_strategy: T.nilable(T.any(String, Symbol)),
|
49
|
+
address: AddressValidation::AbstractAddress,
|
50
|
+
).returns(AddressValidation::MatchingStrategies)
|
51
|
+
end
|
52
|
+
def serialize_strategy(request_matching_strategy, address)
|
53
|
+
requested_strategy = if request_matching_strategy.nil?
|
54
|
+
CountryProfile.for(T.must(address.country_code)).validation.default_matching_strategy
|
55
|
+
else
|
56
|
+
request_matching_strategy.to_s.downcase
|
57
|
+
end
|
58
|
+
|
59
|
+
serialized_strategy = AddressValidation::MatchingStrategies.try_deserialize(requested_strategy)
|
60
|
+
serialized_strategy.presence || AddressValidation::MatchingStrategies::Local
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# typed: true
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module AtlasEngine
|
5
|
+
module Services
|
6
|
+
module ValidationEligibility
|
7
|
+
extend T::Sig
|
8
|
+
|
9
|
+
sig { params(address: AddressValidation::AbstractAddress).returns(T::Boolean) }
|
10
|
+
def validation_enabled?(address)
|
11
|
+
return false if address.country_code.blank?
|
12
|
+
return true unless Rails.env.production? || Rails.env.test?
|
13
|
+
|
14
|
+
CountryProfile.for(T.must(address.country_code)).validation.enabled
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# typed: true
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module AtlasEngine
|
5
|
+
class Street
|
6
|
+
extend T::Sig
|
7
|
+
|
8
|
+
attr_reader :street
|
9
|
+
|
10
|
+
sig { params(street: String).void }
|
11
|
+
def initialize(street:)
|
12
|
+
@street = street
|
13
|
+
end
|
14
|
+
|
15
|
+
sig { returns(T.nilable(String)) }
|
16
|
+
def name
|
17
|
+
parsing[:name]
|
18
|
+
end
|
19
|
+
|
20
|
+
sig { returns(String) }
|
21
|
+
def with_stripped_name
|
22
|
+
return street if name.blank?
|
23
|
+
|
24
|
+
street.sub(name, T.must(name).gsub(/\s+/, ""))
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
sig { returns(T::Hash[Symbol, String]) }
|
30
|
+
def parsing
|
31
|
+
@parsing ||= AtlasEngine::ValidationTranscriber::StreetParser.new.parse(street: street)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
# typed: true
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module Maintenance
|
5
|
+
module AtlasEngine
|
6
|
+
class ElasticsearchIndexCreateTask < MaintenanceTasks::Task
|
7
|
+
include ::AtlasEngine::LogHelper
|
8
|
+
extend T::Sig
|
9
|
+
|
10
|
+
attribute :country_code, :string
|
11
|
+
attribute :locale, :string # optional (no locale implies index = country_code)
|
12
|
+
attribute :province_codes, :string # optional comma separated list of province codes
|
13
|
+
attribute :shard_override, :integer, default: nil
|
14
|
+
attribute :replica_override, :integer, default: nil
|
15
|
+
attribute :activate_index, :boolean, default: false unless Rails.env.production?
|
16
|
+
|
17
|
+
validates :country_code, presence: true
|
18
|
+
|
19
|
+
attr_writer :repository
|
20
|
+
|
21
|
+
after_complete :switch_index unless Rails.env.production?
|
22
|
+
|
23
|
+
sig { returns(T.nilable(ActiveRecord::Batches::BatchEnumerator)) }
|
24
|
+
def collection
|
25
|
+
@batch_number = 0
|
26
|
+
batch_size = 2000
|
27
|
+
|
28
|
+
sanitized_country_code = validate(T.must(country_code))
|
29
|
+
|
30
|
+
address_conditions = {
|
31
|
+
country_code: sanitized_country_code,
|
32
|
+
province_code: sanitized_province_codes,
|
33
|
+
locale: sanitized_locale,
|
34
|
+
}.compact_blank
|
35
|
+
|
36
|
+
record_count = ::AtlasEngine::PostAddress.where(address_conditions).size
|
37
|
+
raise "No records to process for country code: #{country_code}" if record_count.zero?
|
38
|
+
|
39
|
+
repository.create_next_index(ensure_clean: true)
|
40
|
+
|
41
|
+
::AtlasEngine::PostAddress.where(address_conditions).in_batches(of: batch_size)
|
42
|
+
end
|
43
|
+
|
44
|
+
sig { params(batch_of_post_address: ActiveRecord::Relation).void }
|
45
|
+
def process(batch_of_post_address)
|
46
|
+
log_info("Processing batch #{@batch_number} for repository #{repository.read_alias_name.upcase}.")
|
47
|
+
repository.save_records_backfill(batch_of_post_address)
|
48
|
+
@batch_number += 1
|
49
|
+
end
|
50
|
+
|
51
|
+
sig { returns(::AtlasEngine::CountryRepository) }
|
52
|
+
def repository
|
53
|
+
@repository ||= ::AtlasEngine::CountryRepository.new(
|
54
|
+
country_code: T.must(country_code),
|
55
|
+
repository_class: ::AtlasEngine.elasticsearch_repository.constantize,
|
56
|
+
locale: sanitized_locale,
|
57
|
+
index_configuration: index_configuration,
|
58
|
+
)
|
59
|
+
end
|
60
|
+
|
61
|
+
sig { void }
|
62
|
+
def switch_index
|
63
|
+
if activate_index
|
64
|
+
repository.switch_to_next_index
|
65
|
+
log_info("Switched index `#{repository.read_alias_name}` live.")
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
sig { params(country_code: String).returns(String) }
|
72
|
+
def validate(country_code)
|
73
|
+
region = Worldwide.region(code: country_code)
|
74
|
+
unless region.country?
|
75
|
+
raise ArgumentError, "Invalid country code: #{country_code}"
|
76
|
+
end
|
77
|
+
|
78
|
+
region.iso_code
|
79
|
+
end
|
80
|
+
|
81
|
+
sig { returns(T::Array[String]) }
|
82
|
+
def sanitized_province_codes
|
83
|
+
return [] if province_codes.blank?
|
84
|
+
|
85
|
+
T.must(province_codes).downcase.split(",").map(&:strip)
|
86
|
+
end
|
87
|
+
|
88
|
+
sig { returns(String) }
|
89
|
+
def sanitized_locale
|
90
|
+
locale.to_s.downcase
|
91
|
+
end
|
92
|
+
|
93
|
+
sig { returns(::AtlasEngine::IndexConfigurationFactory::IndexConfigurations) }
|
94
|
+
def index_configuration
|
95
|
+
::AtlasEngine::IndexConfigurationFactory.new(
|
96
|
+
country_code: T.must(country_code),
|
97
|
+
locale: sanitized_locale,
|
98
|
+
shard_override: shard_override,
|
99
|
+
replica_override: replica_override,
|
100
|
+
).index_configuration(
|
101
|
+
creating: true,
|
102
|
+
)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# typed: false
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module Maintenance
|
5
|
+
module AtlasEngine
|
6
|
+
class GeoJsonImportTask < MaintenanceTasks::Task
|
7
|
+
include ::AtlasEngine::HandlesBlob
|
8
|
+
|
9
|
+
no_collection
|
10
|
+
|
11
|
+
attribute :clear_records, :boolean, default: true
|
12
|
+
# ISO3166 two-letter country code.
|
13
|
+
attribute :country_code, :string
|
14
|
+
validates :country_code, presence: true
|
15
|
+
# Filename to import. When running in staging or production, the worker expects to find
|
16
|
+
# this file in the relevant GCS bucket, configured in `config/storage/{environment}.yml`
|
17
|
+
# It must be placed under `openaddress/` with the same filename.
|
18
|
+
attribute :geojson_file_path, :string
|
19
|
+
attribute :locale, :string
|
20
|
+
|
21
|
+
def process = ::AtlasEngine::AddressImporter::OpenAddress::GeoJsonImportLauncherJob.perform_later(
|
22
|
+
country_code:,
|
23
|
+
geojson_file_path: geojson_file_path.strip,
|
24
|
+
clear_records:,
|
25
|
+
locale:,
|
26
|
+
)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
<h2>Elasticsearch Indices</h2>
|
2
|
+
<div id="elasticsearch_indices">
|
3
|
+
<table class="table table-striped table-bordered">
|
4
|
+
<thead>
|
5
|
+
<tr>
|
6
|
+
<th>Name</th>
|
7
|
+
<th>Size</th>
|
8
|
+
<th>Document Count</th>
|
9
|
+
</tr>
|
10
|
+
</thead>
|
11
|
+
|
12
|
+
<tbody>
|
13
|
+
<% @indices&.each do |index| %>
|
14
|
+
<tr>
|
15
|
+
<td><%= index["index"] %></td>
|
16
|
+
<td><%= index["store.size"] %></td>
|
17
|
+
<td><%= index["docs.count"] %></td>
|
18
|
+
</tr>
|
19
|
+
<% end %>
|
20
|
+
</tbody>
|
21
|
+
</table>
|
22
|
+
</div>
|
23
|
+
|
24
|
+
<h2>Post Address Records</h2>
|
25
|
+
<div id="post_addresses">
|
26
|
+
<table class="table table-striped table-bordered">
|
27
|
+
<thead>
|
28
|
+
<tr>
|
29
|
+
<th>ID</th>
|
30
|
+
<th>Street</th>
|
31
|
+
<th>City</th>
|
32
|
+
<th>Zip</th>
|
33
|
+
<th>Province Code</th>
|
34
|
+
</tr>
|
35
|
+
</thead>
|
36
|
+
|
37
|
+
<tbody>
|
38
|
+
<% @post_addresses&.each do |address| %>
|
39
|
+
<tr>
|
40
|
+
<td><%= address.id %></td>
|
41
|
+
<td><%= address.street %></td>
|
42
|
+
<td><%= address.city %></td>
|
43
|
+
<td><%= address.zip %></td>
|
44
|
+
<td><%= address.province_code %></td>
|
45
|
+
</tr>
|
46
|
+
<% end %>
|
47
|
+
</tbody>
|
48
|
+
</table>
|
49
|
+
</div>
|
50
|
+
|
@@ -0,0 +1,49 @@
|
|
1
|
+
<h1>Country Imports</h1>
|
2
|
+
|
3
|
+
<div id="country_imports">
|
4
|
+
<table class="table table-striped table-bordered">
|
5
|
+
<thead>
|
6
|
+
<tr>
|
7
|
+
<th>ID</th>
|
8
|
+
<th>country</th>
|
9
|
+
<th>state</th>
|
10
|
+
<th>created_at</th>
|
11
|
+
<th>updated_at</th>
|
12
|
+
<th>actions</th>
|
13
|
+
</tr>
|
14
|
+
</thead>
|
15
|
+
|
16
|
+
<tbody>
|
17
|
+
<% @country_imports.each do |import| %>
|
18
|
+
<tr>
|
19
|
+
<td><%=link_to import.id, country_import_path(import.id) %></td>
|
20
|
+
<td><%= import.country_code %></td>
|
21
|
+
<td><%= import.state %></td>
|
22
|
+
<td><%= import.created_at%></td>
|
23
|
+
<td><%= import.updated_at %></td>
|
24
|
+
<% if import.in_progress? || import.pending? %>
|
25
|
+
<td><%= link_to "Interrupt", interrupt_country_import_path(import.id), class: "btn btn-danger" %></td>
|
26
|
+
<% else %>
|
27
|
+
<td><p>-</p></td>
|
28
|
+
<% end %>
|
29
|
+
</tr>
|
30
|
+
<% end %>
|
31
|
+
</tbody>
|
32
|
+
</table>
|
33
|
+
</div>
|
34
|
+
|
35
|
+
<div class="container">
|
36
|
+
<div class="span2">
|
37
|
+
<% if @page > 0 %>
|
38
|
+
<%= link_to "← Previous", country_imports_path(page: @page - 1), type: "button", class: "btn btn-primary btn-block" %>
|
39
|
+
<% else %>
|
40
|
+
<%= link_to "← Previous", country_imports_path(page: @page - 1), type: "button", class: "btn btn-primary btn-block disabled" %>
|
41
|
+
<% end %>
|
42
|
+
|
43
|
+
<% if AtlasEngine::CountryImport.count > ((@page+1)*AtlasEngine::CountryImport::PAGE_SIZE) %>
|
44
|
+
<%= link_to "Next →", country_imports_path(page: @page + 1),type: "button", class:"btn btn-primary btn-block"%>
|
45
|
+
<% else %>
|
46
|
+
<%= link_to "Next →", country_imports_path(page: @page + 1),type: "button", class:"btn btn-primary btn-block disabled"%>
|
47
|
+
<% end %>
|
48
|
+
</div>
|
49
|
+
</div>
|
@@ -0,0 +1,73 @@
|
|
1
|
+
<head>
|
2
|
+
<meta http-equiv="refresh" content="15">
|
3
|
+
</head>
|
4
|
+
<h1><%= "#{t('admin.events.country_import.title')} #{@country_import&.id}" %></h1>
|
5
|
+
<br>
|
6
|
+
|
7
|
+
<% if @country_import&.in_progress? || @country_import&.pending? %>
|
8
|
+
<%= link_to "Interrupt", interrupt_country_import_path(@country_import.id), class: "btn btn-danger" %>
|
9
|
+
<br>
|
10
|
+
<br>
|
11
|
+
<% end %>
|
12
|
+
|
13
|
+
<div id="country_imports">
|
14
|
+
<table class="table table-striped table-bordered">
|
15
|
+
<tr>
|
16
|
+
<th><%= t('admin.events.country_import.country') %></th>
|
17
|
+
<td>
|
18
|
+
<%=@country_import&.country_code %>
|
19
|
+
</td>
|
20
|
+
</tr>
|
21
|
+
<tr>
|
22
|
+
<th><%= t('admin.events.country_import.state') %></th>
|
23
|
+
<td>
|
24
|
+
<%=@country_import&.state %>
|
25
|
+
</td>
|
26
|
+
</tr>
|
27
|
+
<tr>
|
28
|
+
<th><%= t('admin.events.country_import.created_at') %></th>
|
29
|
+
<td>
|
30
|
+
<% unless @country_import.nil? %>
|
31
|
+
<%="#{time_ago_in_words(@country_import&.created_at)} ago (#{@country_import&.created_at})"%>
|
32
|
+
<% end %>
|
33
|
+
</td>
|
34
|
+
</tr>
|
35
|
+
<tr>
|
36
|
+
<th><%= t('admin.events.country_import.updated_at') %></th>
|
37
|
+
<td>
|
38
|
+
<% unless @country_import.nil? %>
|
39
|
+
<%="#{time_ago_in_words(@country_import&.updated_at)} ago (#{@country_import&.updated_at})"%>
|
40
|
+
<% end %>
|
41
|
+
</td>
|
42
|
+
</tr>
|
43
|
+
</tbody>
|
44
|
+
</table>
|
45
|
+
<h1><%= t('admin.events.events.title') %></h1>
|
46
|
+
<br>
|
47
|
+
<div id="country_imports">
|
48
|
+
<table class="table table-striped table-bordered">
|
49
|
+
<thead>
|
50
|
+
<tr>
|
51
|
+
<th><%= t('admin.events.events.created_at') %></th>
|
52
|
+
<th><%= t('admin.events.events.message') %></th>
|
53
|
+
<th><%= t('admin.events.events.additional_params') %></th>
|
54
|
+
</tr>
|
55
|
+
</thead>
|
56
|
+
<tbody>
|
57
|
+
<% @events.each do |event| %>
|
58
|
+
<tr>
|
59
|
+
<td>
|
60
|
+
<%="#{time_ago_in_words(event.created_at)} ago (#{event.created_at})"%>
|
61
|
+
</td>
|
62
|
+
<td>
|
63
|
+
<%=event.message %>
|
64
|
+
</td>
|
65
|
+
<% if event.additional_params %>
|
66
|
+
<td><%= event.additional_params %></td>
|
67
|
+
<% else %>
|
68
|
+
<td><p>-</p></td>
|
69
|
+
<% end %>
|
70
|
+
</tr>
|
71
|
+
<% end %>
|
72
|
+
</tbody>
|
73
|
+
</table>
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# typed: true
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module Enumerable
|
5
|
+
extend T::Sig
|
6
|
+
|
7
|
+
raise "Enumerable#stable_sort_by is already defined" if method_defined?(:stable_sort_by)
|
8
|
+
|
9
|
+
sig do
|
10
|
+
params(
|
11
|
+
block: T.proc.params(arg0: T.untyped).returns(T.any(Comparable, T::Array[BasicObject])),
|
12
|
+
)
|
13
|
+
.returns(T::Array[T.untyped])
|
14
|
+
end
|
15
|
+
def stable_sort_by(&block)
|
16
|
+
sort_by.with_index { |x, i| [yield(x), i] }
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
en:
|
2
|
+
admin:
|
3
|
+
events:
|
4
|
+
country_import:
|
5
|
+
title: "Country Import"
|
6
|
+
country: "country:"
|
7
|
+
state: "state:"
|
8
|
+
created_at: "created_at:"
|
9
|
+
updated_at: "updated_at:"
|
10
|
+
events:
|
11
|
+
title: "Events"
|
12
|
+
created_at: "created_at"
|
13
|
+
message: "message"
|
14
|
+
additional_params: "additional params"
|
data/config/routes.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# typed: false
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
AtlasEngine::Engine.routes.draw do
|
5
|
+
mount MaintenanceTasks::Engine => "/maintenance_tasks"
|
6
|
+
if Rails.env.local?
|
7
|
+
mount GraphiQL::Rails::Engine, at: "/graphiql", graphql_path: "/graphql"
|
8
|
+
end
|
9
|
+
post "/graphql", to: "graphql#execute"
|
10
|
+
get "/connectivity", to: "connectivity#index"
|
11
|
+
|
12
|
+
resources :country_imports do
|
13
|
+
member do
|
14
|
+
get "interrupt"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|