path-reporting 0.1.1

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 9d921c4f5d8a011b077006a44cb6800d3f9d63329b46d750626aa9ff9fd17859
4
+ data.tar.gz: 1828887be14dbb2b8cbbe5a382e36e14800fce6d5b306764234e0f1f974729ac
5
+ SHA512:
6
+ metadata.gz: 213c4dffd2afaaf7589ce520aa6cbe78d9ecf998ef0528fe9f35e1539d0b547a292a5ec0c42cd9f6031b25ab31628baca91356abbcb0eda2ebbc6a4a7e702bd5
7
+ data.tar.gz: 624e433365f0b3099c3c2d5e3eed73ca6aa2ba7648fd4df7590ebd578dc0752e1cea64a1b30073fe34b3d1386ca7dcde1683237db61e90d65981e3290c0504a0
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,30 @@
1
+ AllCops:
2
+ TargetRubyVersion: 3.0
3
+
4
+ Style/StringLiterals:
5
+ Enabled: true
6
+ EnforcedStyle: double_quotes
7
+
8
+ Style/StringLiteralsInInterpolation:
9
+ Enabled: true
10
+ EnforcedStyle: double_quotes
11
+
12
+ Metrics/BlockLength:
13
+ IgnoredMethods:
14
+ # rspec tests are expected to be long
15
+ - describe
16
+ - context
17
+
18
+ Metrics/MethodLength:
19
+ IgnoredMethods:
20
+ # `record` is long because we format it to be more readable
21
+ - record
22
+ # `scrub_pii` is long both to be more readable and also because it
23
+ # is difficult to break up reasonably and keep it easy to understand
24
+ - scrub_pii
25
+
26
+ Metrics/ParameterLists:
27
+ Max: 7
28
+
29
+ Layout/LineLength:
30
+ Max: 200
data/.yardopts ADDED
@@ -0,0 +1 @@
1
+ --no-private --plugin rspec
data/Gemfile ADDED
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ # Specify your gem's dependencies in reporting.gemspec
6
+ gemspec
7
+
8
+ gem "rake", "~> 13.0"
9
+
10
+ gem "rspec", "~> 3.0"
11
+
12
+ gem "rubocop", "~> 1.21"
13
+ gem "rubocop-rake", "~> 0.6.0"
14
+ gem "rubocop-rspec", "~> 2.10"
15
+
16
+ gem "amplitude-api", "~> 0.4.1"
17
+
18
+ group :development, :test do
19
+ gem "yard", "~> 0.9.27"
20
+ gem "yard-rspec", "~> 0.1"
21
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,77 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ path-reporting (0.1.1)
5
+ amplitude-api
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ amplitude-api (0.4.1)
11
+ faraday (>= 1.0, < 3.0)
12
+ ast (2.4.2)
13
+ diff-lcs (1.5.0)
14
+ faraday (2.2.0)
15
+ faraday-net_http (~> 2.0)
16
+ ruby2_keywords (>= 0.0.4)
17
+ faraday-net_http (2.0.2)
18
+ parallel (1.22.1)
19
+ parser (3.1.1.0)
20
+ ast (~> 2.4.1)
21
+ rainbow (3.1.1)
22
+ rake (13.0.6)
23
+ regexp_parser (2.3.0)
24
+ rexml (3.2.5)
25
+ rspec (3.11.0)
26
+ rspec-core (~> 3.11.0)
27
+ rspec-expectations (~> 3.11.0)
28
+ rspec-mocks (~> 3.11.0)
29
+ rspec-core (3.11.0)
30
+ rspec-support (~> 3.11.0)
31
+ rspec-expectations (3.11.0)
32
+ diff-lcs (>= 1.2.0, < 2.0)
33
+ rspec-support (~> 3.11.0)
34
+ rspec-mocks (3.11.1)
35
+ diff-lcs (>= 1.2.0, < 2.0)
36
+ rspec-support (~> 3.11.0)
37
+ rspec-support (3.11.0)
38
+ rubocop (1.26.1)
39
+ parallel (~> 1.10)
40
+ parser (>= 3.1.0.0)
41
+ rainbow (>= 2.2.2, < 4.0)
42
+ regexp_parser (>= 1.8, < 3.0)
43
+ rexml
44
+ rubocop-ast (>= 1.16.0, < 2.0)
45
+ ruby-progressbar (~> 1.7)
46
+ unicode-display_width (>= 1.4.0, < 3.0)
47
+ rubocop-ast (1.17.0)
48
+ parser (>= 3.1.1.0)
49
+ rubocop-rake (0.6.0)
50
+ rubocop (~> 1.0)
51
+ rubocop-rspec (2.10.0)
52
+ rubocop (~> 1.19)
53
+ ruby-progressbar (1.11.0)
54
+ ruby2_keywords (0.0.5)
55
+ unicode-display_width (1.8.0)
56
+ webrick (1.7.0)
57
+ yard (0.9.27)
58
+ webrick (~> 1.7.0)
59
+ yard-rspec (0.1)
60
+ yard
61
+
62
+ PLATFORMS
63
+ arm64-darwin-21
64
+
65
+ DEPENDENCIES
66
+ amplitude-api (~> 0.4.1)
67
+ path-reporting!
68
+ rake (~> 13.0)
69
+ rspec (~> 3.0)
70
+ rubocop (~> 1.21)
71
+ rubocop-rake (~> 0.6.0)
72
+ rubocop-rspec (~> 2.10)
73
+ yard (~> 0.9.27)
74
+ yard-rspec (~> 0.1)
75
+
76
+ BUNDLED WITH
77
+ 2.3.10
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # Reporting
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/reporting`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Install the gem and add to the application's Gemfile by executing:
10
+
11
+ $ bundle add path-reporting
12
+
13
+ If bundler is not being used to manage dependencies, install the gem by executing:
14
+
15
+ $ gem install path-reporting
16
+
17
+ ## Usage
18
+
19
+ TODO: Write usage instructions here
20
+
21
+ ## Development
22
+
23
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
24
+
25
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
26
+
27
+ ## Contributing
28
+
29
+ Bug reports and pull requests are welcome on GitHub at https://github.com/pathccm/reporting.
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ require "rubocop/rake_task"
9
+
10
+ RuboCop::RakeTask.new
11
+
12
+ task default: %i[spec rubocop]
@@ -0,0 +1,92 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "channels/amplitude"
4
+ require_relative "channels/console"
5
+ require_relative "../types/trigger"
6
+ require_relative "../types/user_type"
7
+
8
+ module Path
9
+ module Reporting
10
+ class Analytics
11
+ def initialize(config)
12
+ @config = config
13
+ end
14
+
15
+ # Get clients for reporting events based on environment
16
+ def clients
17
+ if @clients.nil?
18
+ @clients = {
19
+ amplitude: setup_amplitude,
20
+ console: setup_console
21
+ }
22
+ end
23
+
24
+ @clients
25
+ end
26
+
27
+ def setup_amplitude
28
+ # Amplitude reporting for metrics
29
+ return Path::Reporting::Analytics::Channels::Amplitude.new @config if @config.amplitude_enabled?
30
+
31
+ nil
32
+ end
33
+
34
+ def setup_console
35
+ return Path::Reporting::Analytics::Channels::Console.new @config if @config.console_enabled?
36
+
37
+ nil
38
+ end
39
+
40
+ def format_event_name(product_code:, product_area:, name:)
41
+ formatted_code = product_code.gsub(" ", "_").upcase
42
+ formatted_area = product_area.split(" ").each(&:capitalize!).join("")
43
+ formatted_desc = name.capitalize.gsub(" ", "_")
44
+ "#{formatted_code}_#{formatted_area}_#{formatted_desc}"
45
+ end
46
+
47
+ def record(
48
+ product_code:,
49
+ product_area:,
50
+ name:,
51
+ user:,
52
+ user_type: UserType.PATIENT,
53
+ trigger: Trigger.INTERACTION,
54
+ metadata: {}
55
+ )
56
+ throw Error("No user provided when reporting analytics") unless user
57
+ throw Error("Invalid UserType #{user_type}") unless UserType.valid?(user_type)
58
+ throw Error("Invalid Trigger #{trigger}") unless Trigger.valid?(trigger)
59
+
60
+ all_succeeded = true
61
+ exceptions = {}
62
+ clients.each do |_reporter, client|
63
+ next if client.nil?
64
+
65
+ begin
66
+ event_name = format_event_name(product_code: product_code, product_area: product_area, name: name)
67
+ client.record(
68
+ name: event_name,
69
+ user: user,
70
+ user_type: user_type,
71
+ metadata: metadata,
72
+ trigger: trigger
73
+ )
74
+ exceptions[client.channel_name] = nil
75
+ rescue StandardError => e
76
+ all_succeeded = false
77
+ exceptions[client.channel_name] = e
78
+ end
79
+ end
80
+
81
+ {
82
+ all_succeeded: all_succeeded,
83
+ exceptions: exceptions
84
+ }
85
+ end
86
+
87
+ def reset!
88
+ @clients = nil
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,115 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "amplitude-api"
4
+
5
+ # See https://developers.amplitude.com/docs/http-api-v2#schemauploadrequestbody
6
+ API_METADATA_TO_ELEVATE = [
7
+ "device_id",
8
+ "app_version",
9
+ "platform",
10
+ "os_name",
11
+ "os_version",
12
+ "device_brand",
13
+ "device_manufacturer",
14
+ "device_model",
15
+ "carrier",
16
+ "country",
17
+ "region",
18
+ # We do not elevate city because at that level it is possibly PII
19
+ "dma",
20
+ "language",
21
+ "price",
22
+ "quantity",
23
+ "revenue",
24
+ "productId",
25
+ "revenueType",
26
+ # We do not elevate lat/long/IP because it is PII (IP at least for analytics)
27
+ "event_id",
28
+ "session_id",
29
+ "insert_id",
30
+ "plan"
31
+ ].freeze
32
+
33
+ # Amplitue is not HIPAA compliant, so there are a number of PII things we want
34
+ # to make sure to filter out. These are keys (all lowercase) that are things
35
+ # we want to filter. Lowercased matching keys in data are obfuscated.
36
+ DISALLOWED_METADATA_PII_KEYS = %w[
37
+ email
38
+ name
39
+ first_name
40
+ firstname
41
+ last_name
42
+ lastname
43
+ zip
44
+ ssn
45
+ dob
46
+ address
47
+ phone
48
+ contactinfo
49
+ patient_chart_id
50
+ ].freeze
51
+
52
+ # Don't clean to infinity (and beyond)
53
+ MAX_METADATA_DEPTH = 4
54
+
55
+ module Path
56
+ module Reporting
57
+ class Analytics
58
+ module Channels
59
+ # Amplitude analytics is our primary analytics channel for production
60
+ class Amplitude
61
+ attr_reader :channel_name
62
+
63
+ def initialize(config)
64
+ @channel_name = "Amplitude"
65
+ @config = config
66
+
67
+ config.amplitude_config.each do |key, value|
68
+ AmplitudeAPI.config.instance_variable_set("@#{key}", value)
69
+ end
70
+ end
71
+
72
+ def record(name:, user:, user_type:, trigger:, metadata: {})
73
+ user = user.dup
74
+ metadata = metadata.dup
75
+ user[:user_type] = user_type
76
+ metadata[:trigger] = trigger
77
+
78
+ event_props = {
79
+ user_id: user[:id].to_s,
80
+ user_properties: scrub_pii(user),
81
+ event_type: name,
82
+ event_properties: scrub_pii(metadata)
83
+ }
84
+ API_METADATA_TO_ELEVATE.each do |key|
85
+ event_props[key] = metadata[key] if metadata.key? key
86
+ end
87
+
88
+ AmplitudeAPI.track AmplitudeAPI::Event.new event_props
89
+ end
90
+
91
+ def scrub_pii(data, depth: 0)
92
+ return "[DATA]" if depth > MAX_METADATA_DEPTH
93
+
94
+ case data
95
+ when Hash
96
+ data = data.dup
97
+ # Replace any disallowed keys, and recurse for allowed values
98
+ data.each do |key, val|
99
+ data[key] = if DISALLOWED_METADATA_PII_KEYS.include? key.to_s
100
+ "XXXXXXXX"
101
+ else
102
+ scrub_pii(val, depth: depth + 1)
103
+ end
104
+ end
105
+ when Array
106
+ return data.map { |item| scrub_pii(item, depth: depth + 1) }
107
+ end
108
+
109
+ data
110
+ end
111
+ end
112
+ end
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Path
4
+ module Reporting
5
+ class Analytics
6
+ module Channels
7
+ class Console
8
+ attr_reader :channel_name
9
+
10
+ def initialize(config)
11
+ @channel_name = "Console"
12
+ @config = config
13
+ end
14
+
15
+ def record(name:, user:, user_type:, trigger:, metadata: {})
16
+ @config.console_logger.info("[#{trigger}]:#{name} - #{user.inspect} (#{user_type}) #{metadata.nil? ? "" : metadata.inspect}")
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Path
4
+ module Reporting
5
+ class Analytics
6
+ class Configuration
7
+ attr_accessor :console_enabled
8
+ attr_reader :amplitude_config, :console_logger
9
+
10
+ def initialize
11
+ @console_enabled = false
12
+ @console_logger = nil
13
+ @amplitude_enabled = false
14
+ @amplitude_config = nil
15
+ end
16
+
17
+ def logger=(logger)
18
+ @console_enabled = !logger.nil?
19
+ @console_logger = logger
20
+ end
21
+
22
+ alias console= logger=
23
+
24
+ def console_enabled?
25
+ @console_enabled && @console_logger
26
+ end
27
+
28
+ def amplitude_config=(conf)
29
+ @amplitude_enabled = !conf.nil?
30
+ @amplitude_config = conf
31
+ end
32
+
33
+ alias amplitude= amplitude_config=
34
+
35
+ def amplitude_enabled?
36
+ @amplitude_enabled && @amplitude_config
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "analytics/configuration"
4
+
5
+ module Path
6
+ module Reporting
7
+ # @!attribute [r] analytics
8
+ # @return [Analytics::Configuration] the configuration for analytics reporting
9
+ class Configuration
10
+ attr_reader :analytics
11
+
12
+ # Create a new configuration. Sub configuration's will be used by the
13
+ # various reporting sections.
14
+ # @see Analytics::Configuration
15
+ def initialize
16
+ @analytics = Analytics::Configuration.new
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Path
4
+ module Reporting
5
+ VERSION = "0.1.1"
6
+ end
7
+ end
data/lib/reporting.rb ADDED
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "analytics/analytics"
4
+ require_relative "configuration"
5
+ require_relative "reporting/version"
6
+
7
+ # Path is just a wrapper module so we can group any path specific gems under
8
+ # this module heading
9
+ module Path
10
+ # The `Reporting` module is our general, all-purpose reporting tool for
11
+ # analytics, metrics, performance, and any other data. This module is
12
+ # meant to be a one-stop shop for all of our ruby code to import and have
13
+ # everything they need to track all the things
14
+ module Reporting
15
+ class Error < StandardError; end
16
+
17
+ class << self
18
+ # Initialize our reporting setup. This is required to call before
19
+ # the module is ready to use.
20
+ #
21
+ # To configure this module, pass in a block that accepts a {Configuration}
22
+ # parameter. Using this parameter you can setup any reporting systems
23
+ # that you need.
24
+ #
25
+ # Each sub-type of reporting will have its own configuration. For example,
26
+ # to configure analytics reporting, you can use the `analytics` property
27
+ # on the {Configuration} object passed in, which will be an instance of
28
+ # {Analytics::Configuration}.
29
+ #
30
+ # @example Basic analytics setup
31
+ # Path::Reporting.init do |config|
32
+ # config.analytics.logger = Rails.logger
33
+ # end
34
+ # @example If no configuration is needed, you still need to call this method
35
+ # Path::Reporting.init
36
+ # @yieldparam config [Configuration] the Configuration object to set any and all configuration on
37
+ # @return [self]
38
+ # @see Configuration
39
+ # @see Analytics::Configuration
40
+ def init
41
+ @initialized = true
42
+ @config = Configuration.new
43
+ yield(@config) if block_given?
44
+
45
+ @analytics = Path::Reporting::Analytics.new @config.analytics
46
+ self
47
+ end
48
+
49
+ # @raise [Error] if the Path:Reporting module has not been initialized
50
+ # @return [Analytics] the configured analytics reporting module
51
+ def analytics
52
+ raise Error, "Must call init on Path::Reporting library before using" unless @initialized
53
+
54
+ @analyitcs
55
+ end
56
+
57
+ # Resets the module to an uninitialized state. Mostly used for testing
58
+ # @private
59
+ def reset!
60
+ @initialized = false
61
+ @config = nil
62
+ @analyitcs = nil
63
+ self
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Path
4
+ module Reporting
5
+ class Trigger
6
+ class << self
7
+ INTERACTION = "Interaction"
8
+ PAGE_VIEW = "Page view"
9
+ AUTOMATION = "Automation"
10
+
11
+ def triggers
12
+ [
13
+ INTERACTION,
14
+ PAGE_VIEW,
15
+ AUTOMATION
16
+ ]
17
+ end
18
+
19
+ def valid?(maybe_trigger)
20
+ triggers.includes? maybe_trigger
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Path
4
+ module Reporting
5
+ class UserType
6
+ class << self
7
+ PATIENT = "Patient"
8
+ PROVIDER = "Provider"
9
+ INSURER = "Insurer"
10
+ OPERATOR = "Operator"
11
+ DEVELOPER = "Developer"
12
+ SYSTEM = "System"
13
+
14
+ def types
15
+ [
16
+ PATIENT,
17
+ PROVIDER,
18
+ INSURER,
19
+ OPERATOR,
20
+ DEVELOPER,
21
+ SYSTEM
22
+ ]
23
+ end
24
+
25
+ def valid?(maybe_type)
26
+ types.includes? maybe_type
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
data/reporting.gemspec ADDED
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/reporting/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "path-reporting"
7
+ spec.version = Path::Reporting::VERSION
8
+ spec.authors = ["Alexis Hushbeck"]
9
+ spec.email = ["alexis.hushbeck@pathccm.com"]
10
+
11
+ spec.summary = "Reporting gem for Path Mental Health"
12
+ spec.homepage = "https://github.com/pathccm/reporting"
13
+ spec.required_ruby_version = ">= 3.0.3"
14
+
15
+ spec.metadata["homepage_uri"] = spec.homepage
16
+ spec.metadata["source_code_uri"] = "https://github.com/pathccm/reporting"
17
+ spec.metadata["changelog_uri"] = "https://github.com/pathccm/reporting/commits"
18
+
19
+ # Specify which files should be added to the gem when it is released.
20
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
21
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
22
+ `git ls-files -z`.split("\x0").reject do |f|
23
+ (f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
24
+ end
25
+ end
26
+ spec.bindir = "exe"
27
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
28
+ spec.require_paths = ["lib"]
29
+
30
+ # Uncomment to register a new dependency of your gem
31
+ spec.add_dependency "amplitude-api"
32
+ spec.add_development_dependency "yard"
33
+
34
+ # For more information and examples about making a new gem, check out our
35
+ # guide at: https://bundler.io/guides/creating_gem.html
36
+ end
data/sig/reporting.rbs ADDED
@@ -0,0 +1,4 @@
1
+ module Reporting
2
+ VERSION: String
3
+ # See the writing guide of rbs: https://github.com/ruby/rbs#guides
4
+ end
metadata ADDED
@@ -0,0 +1,91 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: path-reporting
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Alexis Hushbeck
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2022-04-28 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: amplitude-api
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: yard
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description:
42
+ email:
43
+ - alexis.hushbeck@pathccm.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - ".rspec"
49
+ - ".rubocop.yml"
50
+ - ".yardopts"
51
+ - Gemfile
52
+ - Gemfile.lock
53
+ - README.md
54
+ - Rakefile
55
+ - lib/analytics/analytics.rb
56
+ - lib/analytics/channels/amplitude.rb
57
+ - lib/analytics/channels/console.rb
58
+ - lib/analytics/configuration.rb
59
+ - lib/configuration.rb
60
+ - lib/reporting.rb
61
+ - lib/reporting/version.rb
62
+ - lib/types/trigger.rb
63
+ - lib/types/user_type.rb
64
+ - reporting.gemspec
65
+ - sig/reporting.rbs
66
+ homepage: https://github.com/pathccm/reporting
67
+ licenses: []
68
+ metadata:
69
+ homepage_uri: https://github.com/pathccm/reporting
70
+ source_code_uri: https://github.com/pathccm/reporting
71
+ changelog_uri: https://github.com/pathccm/reporting/commits
72
+ post_install_message:
73
+ rdoc_options: []
74
+ require_paths:
75
+ - lib
76
+ required_ruby_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: 3.0.3
81
+ required_rubygems_version: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ requirements: []
87
+ rubygems_version: 3.3.10
88
+ signing_key:
89
+ specification_version: 4
90
+ summary: Reporting gem for Path Mental Health
91
+ test_files: []