elia_ruby 0.1.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.
@@ -0,0 +1,89 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Elia
4
+ module Mcc
5
+ # Serializer for MCC codes and related objects
6
+ #
7
+ # Provides consistent JSON/Hash representations for API responses.
8
+ class Serializer
9
+ DEFAULT_CODE_OPTIONS = {
10
+ include_all_descriptions: false,
11
+ include_categories: true,
12
+ include_range: true,
13
+ }.freeze
14
+
15
+ # Serializes a Code object
16
+ #
17
+ # @param code [Code] the code to serialize
18
+ # @param options [Hash] serialization options
19
+ # @option options [Boolean] :include_all_descriptions (false) include all source descriptions
20
+ # @option options [Boolean] :include_categories (true) include category data
21
+ # @option options [Boolean] :include_range (true) include range data
22
+ # @return [Hash] the serialized code
23
+ def self.serialize_code(code, options = {})
24
+ options = DEFAULT_CODE_OPTIONS.merge(options)
25
+ result = base_code_hash(code)
26
+ result.merge!(all_descriptions_hash(code)) if options[:include_all_descriptions]
27
+ result[:categories] = code.categories.map(&:id) if options[:include_categories]
28
+ result[:range] = code.range&.name if options[:include_range]
29
+ result
30
+ end
31
+
32
+ def self.base_code_hash(code)
33
+ { mcc: code.mcc, description: code.description,
34
+ stripe_code: code.stripe_code, irs_reportable: code.irs_reportable?, }
35
+ end
36
+
37
+ def self.all_descriptions_hash(code)
38
+ { iso_description: code.iso_description, usda_description: code.usda_description,
39
+ stripe_description: code.stripe_description, visa_description: code.visa_description,
40
+ visa_clearing_name: code.visa_clearing_name, mastercard_description: code.mastercard_description,
41
+ amex_description: code.amex_description, alipay_description: code.alipay_description,
42
+ irs_description: code.irs_description, }
43
+ end
44
+
45
+ private_class_method :base_code_hash, :all_descriptions_hash
46
+
47
+ # Serializes a Category object
48
+ #
49
+ # @param category [Category] the category to serialize
50
+ # @param options [Hash] serialization options
51
+ # @return [Hash] the serialized category
52
+ def self.serialize_category(category, options = {})
53
+ result = {
54
+ id: category.id,
55
+ name: category.name,
56
+ description: category.description,
57
+ }
58
+
59
+ result[:codes] = category.codes if options[:include_codes]
60
+
61
+ result
62
+ end
63
+
64
+ # Serializes a Range object
65
+ #
66
+ # @param range [Range] the range to serialize
67
+ # @param options [Hash] serialization options
68
+ # @return [Hash] the serialized range
69
+ def self.serialize_range(range, _options = {})
70
+ {
71
+ start_code: range.start_code,
72
+ end_code: range.end_code,
73
+ name: range.name,
74
+ description: range.description,
75
+ reserved: range.reserved?,
76
+ }
77
+ end
78
+
79
+ # Serializes a collection of codes
80
+ #
81
+ # @param codes [Array<Code>] the codes to serialize
82
+ # @param options [Hash] serialization options
83
+ # @return [Array<Hash>] the serialized codes
84
+ def self.serialize_collection(codes, options = {})
85
+ codes.map { |code| serialize_code(code, options) }
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,102 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Elia
4
+ module Mcc
5
+ # Standalone validator for MCC codes
6
+ #
7
+ # Can be used independently of ActiveModel for basic validation.
8
+ #
9
+ # @example Basic usage
10
+ # validator = Elia::Mcc::Validator.new
11
+ # validator.valid?("5411") # => true
12
+ # validator.valid?("XXXX") # => false
13
+ #
14
+ # @example With category restrictions
15
+ # validator = Elia::Mcc::Validator.new(deny_categories: [:gambling, :adult])
16
+ # validator.valid?("7995") # => false (gambling)
17
+ class Validator
18
+ # Default error messages
19
+ MESSAGES = {
20
+ invalid_format: "must be a valid 4-digit MCC code",
21
+ not_found: "is not a recognized MCC code",
22
+ denied_category: "is in a denied category",
23
+ }.freeze
24
+
25
+ # @return [Hash] validation options
26
+ attr_reader :options
27
+
28
+ # Creates a new Validator instance
29
+ #
30
+ # @param options [Hash] validation options
31
+ # @option options [Boolean] :strict (true) require code to exist in registry
32
+ # @option options [Array<Symbol>] :deny_categories categories to reject
33
+ # @option options [Array<Symbol>] :allow_categories only allow these categories
34
+ def initialize(options = {})
35
+ @options = {
36
+ strict: true,
37
+ deny_categories: [],
38
+ allow_categories: nil,
39
+ }.merge(options)
40
+ end
41
+
42
+ # Validates the given value
43
+ #
44
+ # @param value [String, Integer, nil] the value to validate
45
+ # @return [Array<String>] error messages (empty if valid)
46
+ def validate(value)
47
+ errors = []
48
+
49
+ return errors if value.nil?
50
+
51
+ # Check format
52
+ unless valid_format?(value)
53
+ errors << MESSAGES[:invalid_format]
54
+ return errors
55
+ end
56
+
57
+ # Check if code exists (strict mode)
58
+ if options[:strict]
59
+ code = Elia::Mcc.find(value)
60
+ if code.nil?
61
+ errors << MESSAGES[:not_found]
62
+ return errors
63
+ end
64
+
65
+ # Check category restrictions
66
+ if options[:deny_categories].any?
67
+ denied = options[:deny_categories].any? { |cat| code.in_category?(cat) }
68
+ errors << MESSAGES[:denied_category] if denied
69
+ end
70
+
71
+ if options[:allow_categories]
72
+ allowed = options[:allow_categories].any? { |cat| code.in_category?(cat) }
73
+ errors << MESSAGES[:denied_category] unless allowed
74
+ end
75
+ end
76
+
77
+ errors
78
+ end
79
+
80
+ # Returns whether the value is valid
81
+ #
82
+ # @param value [String, Integer, nil] the value to validate
83
+ # @return [Boolean] true if valid
84
+ def valid?(value)
85
+ validate(value).empty?
86
+ end
87
+
88
+ private
89
+
90
+ # Checks if the value has a valid MCC format
91
+ #
92
+ # @param value [String, Integer, nil] the value to check
93
+ # @return [Boolean] true if the format is valid
94
+ def valid_format?(value)
95
+ return false if value.nil?
96
+
97
+ normalized = value.to_s.strip
98
+ normalized.match?(/\A\d{1,4}\z/)
99
+ end
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Elia
4
+ module Mcc
5
+ VERSION = "0.1.0"
6
+ end
7
+ end
data/lib/elia/mcc.rb ADDED
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Elia
4
+ # MCC (Merchant Category Code) module provides tools for working with
5
+ # payment industry merchant category codes, including validation,
6
+ # categorization, and risk assessment.
7
+ module Mcc
8
+ class << self
9
+ # Returns the configuration object for the Mcc module
10
+ #
11
+ # @return [Configuration] the configuration instance
12
+ def configuration
13
+ @configuration ||= Configuration.new
14
+ end
15
+
16
+ # Yields the configuration object for block-based configuration
17
+ #
18
+ # @yield [Configuration] the configuration instance
19
+ # @return [Configuration] the configuration instance
20
+ def configure
21
+ yield(configuration) if block_given?
22
+ configuration
23
+ end
24
+
25
+ # Resets the configuration to defaults and clears the collection cache
26
+ #
27
+ # @return [Configuration] a new configuration instance
28
+ def reset!
29
+ @configuration = Configuration.new
30
+ @collection = nil
31
+ @configuration
32
+ end
33
+
34
+ alias reset_configuration! reset!
35
+
36
+ # Delegate query methods to Collection
37
+ delegate :all, :find, :find!, :[], :where, :in_range, :search,
38
+ :in_category, :valid?, :count, :size, :reload!,
39
+ to: :collection
40
+
41
+ # Returns all ISO 18245 ranges
42
+ #
43
+ # @return [Array<Range>] all ranges
44
+ def ranges
45
+ collection.all_ranges
46
+ end
47
+
48
+ # Returns all risk categories
49
+ #
50
+ # @return [Array<Category>] all categories
51
+ def categories
52
+ collection.all_categories
53
+ end
54
+
55
+ private
56
+
57
+ # Returns the collection instance, creating it if necessary
58
+ #
59
+ # @return [Collection] the collection instance
60
+ def collection
61
+ @collection ||= Collection.new
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Elia
4
+ VERSION = "0.1.0"
5
+ end
data/lib/elia_ruby.rb ADDED
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "zeitwerk"
4
+ require "active_support"
5
+ require "active_support/core_ext/module/delegation"
6
+ require "active_support/core_ext/object/blank"
7
+
8
+ # Define the Elia module at the top level
9
+ module Elia
10
+ class Error < StandardError; end
11
+ end
12
+
13
+ require_relative "elia_ruby/version"
14
+
15
+ # Set up Zeitwerk loader for Elia::Mcc namespace
16
+ loader = Zeitwerk::Loader.new
17
+ loader.tag = "elia_mcc"
18
+ loader.push_dir(File.expand_path("elia", __dir__), namespace: Elia)
19
+
20
+ # Ignore files that don't follow Zeitwerk conventions
21
+ loader.ignore(File.expand_path("elia/mcc/version.rb", __dir__))
22
+ loader.ignore(File.expand_path("elia/mcc/errors.rb", __dir__))
23
+ loader.ignore(File.expand_path("elia/mcc/railtie.rb", __dir__))
24
+ loader.ignore(File.expand_path("elia/mcc/active_model_validator.rb", __dir__))
25
+ loader.ignore(File.expand_path("elia/mcc/data", __dir__))
26
+
27
+ loader.setup
28
+
29
+ # Load files that don't follow Zeitwerk conventions manually
30
+ require_relative "elia/mcc/version"
31
+ require_relative "elia/mcc/errors"
32
+ require_relative "elia/mcc"
33
+
34
+ # Load the Railtie if Rails is present
35
+ require_relative "elia/mcc/railtie" if defined?(Rails::Railtie)
metadata ADDED
@@ -0,0 +1,98 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: elia_ruby
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Elia Pay
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2026-01-28 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '6.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '6.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: zeitwerk
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.6'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.6'
41
+ description: A comprehensive library for working with Merchant Category Codes (MCC),
42
+ including validation, categorization, and risk assessment.
43
+ email: support@eliapay.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - LICENSE.txt
49
+ - README.md
50
+ - lib/elia/mcc.rb
51
+ - lib/elia/mcc/active_model_validator.rb
52
+ - lib/elia/mcc/category.rb
53
+ - lib/elia/mcc/code.rb
54
+ - lib/elia/mcc/collection.rb
55
+ - lib/elia/mcc/configuration.rb
56
+ - lib/elia/mcc/data/.gitkeep
57
+ - lib/elia/mcc/data/mcc_codes.yml
58
+ - lib/elia/mcc/data/ranges.yml
59
+ - lib/elia/mcc/data/risk_categories.yml
60
+ - lib/elia/mcc/errors.rb
61
+ - lib/elia/mcc/railtie.rb
62
+ - lib/elia/mcc/range.rb
63
+ - lib/elia/mcc/serializer.rb
64
+ - lib/elia/mcc/validator.rb
65
+ - lib/elia/mcc/version.rb
66
+ - lib/elia_ruby.rb
67
+ - lib/elia_ruby/version.rb
68
+ homepage: https://github.com/eliapay/elia-ruby
69
+ licenses:
70
+ - MIT
71
+ metadata:
72
+ bug_tracker_uri: https://github.com/eliapay/elia-ruby/issues
73
+ changelog_uri: https://github.com/eliapay/elia-ruby/blob/main/CHANGELOG.md
74
+ documentation_uri: https://github.com/eliapay/elia-ruby#readme
75
+ github_repo: ssh://github.com/eliapay/elia-ruby
76
+ homepage_uri: https://github.com/eliapay/elia-ruby
77
+ source_code_uri: https://github.com/eliapay/elia-ruby
78
+ rubygems_mfa_required: 'true'
79
+ post_install_message:
80
+ rdoc_options: []
81
+ require_paths:
82
+ - lib
83
+ required_ruby_version: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ version: 2.7.0
88
+ required_rubygems_version: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
93
+ requirements: []
94
+ rubygems_version: 3.5.22
95
+ signing_key:
96
+ specification_version: 4
97
+ summary: MCC (Merchant Category Code) library for payment processing
98
+ test_files: []