vert-core 1.0.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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +14 -0
- data/README.md +126 -0
- data/lib/vert/authorization/controller_methods.rb +84 -0
- data/lib/vert/authorization/dynamic_policy.rb +156 -0
- data/lib/vert/authorization/permission_resolver.rb +253 -0
- data/lib/vert/authorization/policy_finder.rb +72 -0
- data/lib/vert/clients/document_service_client.rb +104 -0
- data/lib/vert/concerns/auditable.rb +24 -0
- data/lib/vert/concerns/company_scoped.rb +48 -0
- data/lib/vert/concerns/current_attributes.rb +53 -0
- data/lib/vert/concerns/document_storeable.rb +180 -0
- data/lib/vert/concerns/multi_tenant.rb +45 -0
- data/lib/vert/concerns/soft_deletable.rb +46 -0
- data/lib/vert/concerns/uuid_primary_key.rb +42 -0
- data/lib/vert/configuration.rb +65 -0
- data/lib/vert/generators/install_generator.rb +66 -0
- data/lib/vert/generators/rls_migration_generator.rb +57 -0
- data/lib/vert/generators/templates/application_record.rb.tt +8 -0
- data/lib/vert/generators/templates/create_outbox_events.rb.tt +24 -0
- data/lib/vert/generators/templates/create_rls_functions.rb.tt +27 -0
- data/lib/vert/generators/templates/current.rb.tt +10 -0
- data/lib/vert/generators/templates/enable_rls_on_tables.rb.tt +39 -0
- data/lib/vert/generators/templates/health_controller.rb.tt +5 -0
- data/lib/vert/generators/templates/initializer.rb.tt +39 -0
- data/lib/vert/generators/templates/outbox_event.rb.tt +11 -0
- data/lib/vert/health/checker.rb +119 -0
- data/lib/vert/health/routes.rb +44 -0
- data/lib/vert/outbox/event.rb +68 -0
- data/lib/vert/outbox/publisher.rb +105 -0
- data/lib/vert/outbox/publisher_job.rb +30 -0
- data/lib/vert/railtie.rb +54 -0
- data/lib/vert/rls/connection_handler.rb +56 -0
- data/lib/vert/rls/consumer_context.rb +31 -0
- data/lib/vert/rls/context_middleware.rb +37 -0
- data/lib/vert/rls/job_context.rb +56 -0
- data/lib/vert/version.rb +5 -0
- data/lib/vert.rb +58 -0
- data/vert.gemspec +43 -0
- metadata +223 -0
data/lib/vert/railtie.rb
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Vert
|
|
4
|
+
class Railtie < Rails::Railtie
|
|
5
|
+
config.vert = ActiveSupport::OrderedOptions.new
|
|
6
|
+
|
|
7
|
+
initializer "vert.middleware" do |app|
|
|
8
|
+
if Vert.config.enable_rls
|
|
9
|
+
app.middleware.use Vert::Rls::ContextMiddleware
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
initializer "vert.sidekiq" do
|
|
14
|
+
if defined?(Sidekiq) && Vert.config.enable_rls
|
|
15
|
+
Sidekiq.configure_server do |config|
|
|
16
|
+
config.server_middleware do |chain|
|
|
17
|
+
chain.add Vert::Rls::JobMiddleware
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
Sidekiq.configure_client do |config|
|
|
21
|
+
config.client_middleware do |chain|
|
|
22
|
+
chain.add Vert::Rls::JobClientMiddleware
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
config.to_prepare do
|
|
29
|
+
if Vert.config.enable_rls && defined?(ApplicationController)
|
|
30
|
+
ApplicationController.include(Vert::Rls::ControllerContext)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
initializer "vert.routes" do |app|
|
|
35
|
+
next unless Vert.config.enable_health && Vert.config.auto_mount_health_routes
|
|
36
|
+
next if app.routes.named_routes.key?(:health)
|
|
37
|
+
|
|
38
|
+
app.routes.append do
|
|
39
|
+
Vert::Health::Routes.mount(self)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
generators do
|
|
44
|
+
require_relative "generators/install_generator"
|
|
45
|
+
require_relative "generators/rls_migration_generator"
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
console do
|
|
49
|
+
puts "Vert v#{Vert::VERSION} loaded"
|
|
50
|
+
puts " Config: Vert.config"
|
|
51
|
+
puts " Health: Vert::Health.check_all (when enable_health)"
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Vert
|
|
4
|
+
module Rls
|
|
5
|
+
class ConnectionHandler
|
|
6
|
+
class << self
|
|
7
|
+
def set_context(tenant_id:, company_id: nil, user_id: nil)
|
|
8
|
+
return unless tenant_id.present?
|
|
9
|
+
connection = ActiveRecord::Base.connection
|
|
10
|
+
connection.execute(ActiveRecord::Base.sanitize_sql(["SET LOCAL app.current_tenant_id = %s", tenant_id]))
|
|
11
|
+
connection.execute(ActiveRecord::Base.sanitize_sql(["SET LOCAL app.current_company_id = %s", company_id])) if company_id.present?
|
|
12
|
+
connection.execute(ActiveRecord::Base.sanitize_sql(["SET LOCAL app.current_user_id = %s", user_id])) if user_id.present?
|
|
13
|
+
Vert::Current.rls_configured = true
|
|
14
|
+
rescue StandardError => e
|
|
15
|
+
Rails.logger.error("[Vert::RLS] #{e.message}") if defined?(Rails)
|
|
16
|
+
raise
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def reset_context
|
|
20
|
+
return unless Vert::Current.rls_configured
|
|
21
|
+
connection = ActiveRecord::Base.connection
|
|
22
|
+
connection.execute("RESET app.current_tenant_id")
|
|
23
|
+
connection.execute("RESET app.current_company_id")
|
|
24
|
+
connection.execute("RESET app.current_user_id")
|
|
25
|
+
Vert::Current.rls_configured = false
|
|
26
|
+
rescue StandardError => e
|
|
27
|
+
Rails.logger.error("[Vert::RLS] #{e.message}") if defined?(Rails)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def with_context(tenant_id:, company_id: nil, user_id: nil)
|
|
31
|
+
previous = Vert::Current.serialize
|
|
32
|
+
set_context(tenant_id: tenant_id, company_id: company_id, user_id: user_id)
|
|
33
|
+
Vert::Current.set_context(tenant_id: tenant_id, company_id: company_id, user_id: user_id)
|
|
34
|
+
yield
|
|
35
|
+
ensure
|
|
36
|
+
reset_context
|
|
37
|
+
Vert::Current.deserialize(previous)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def create_functions_sql
|
|
41
|
+
<<~SQL
|
|
42
|
+
CREATE OR REPLACE FUNCTION current_tenant_id() RETURNS uuid AS $$
|
|
43
|
+
SELECT NULLIF(current_setting('app.current_tenant_id', true), '')::uuid;
|
|
44
|
+
$$ LANGUAGE SQL STABLE;
|
|
45
|
+
CREATE OR REPLACE FUNCTION current_company_id() RETURNS uuid AS $$
|
|
46
|
+
SELECT NULLIF(current_setting('app.current_company_id', true), '')::uuid;
|
|
47
|
+
$$ LANGUAGE SQL STABLE;
|
|
48
|
+
CREATE OR REPLACE FUNCTION current_user_id() RETURNS uuid AS $$
|
|
49
|
+
SELECT NULLIF(current_setting('app.current_user_id', true), '')::uuid;
|
|
50
|
+
$$ LANGUAGE SQL STABLE;
|
|
51
|
+
SQL
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Vert
|
|
4
|
+
module Rls
|
|
5
|
+
module ConsumerContext
|
|
6
|
+
extend ActiveSupport::Concern
|
|
7
|
+
|
|
8
|
+
def work_with_params(message, delivery_info, metadata)
|
|
9
|
+
h = metadata[:headers] || {}
|
|
10
|
+
Vert::Current.set_context(
|
|
11
|
+
tenant_id: h["tenant_id"] || h[:tenant_id],
|
|
12
|
+
user_id: h["user_id"] || h[:user_id],
|
|
13
|
+
company_id: h["company_id"] || h[:company_id],
|
|
14
|
+
request_id: h["request_id"] || h[:request_id] || SecureRandom.uuid
|
|
15
|
+
)
|
|
16
|
+
if Vert.config.enable_rls && Vert::Current.tenant_id.present?
|
|
17
|
+
ConnectionHandler.set_context(tenant_id: Vert::Current.tenant_id, company_id: Vert::Current.company_id, user_id: Vert::Current.user_id)
|
|
18
|
+
end
|
|
19
|
+
super
|
|
20
|
+
ensure
|
|
21
|
+
Vert::Current.reset_all
|
|
22
|
+
ConnectionHandler.reset_context if Vert.config.enable_rls
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
class BaseConsumer
|
|
27
|
+
include Sneakers::Worker if defined?(Sneakers::Worker)
|
|
28
|
+
include ConsumerContext if defined?(Sneakers::Worker)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Vert
|
|
4
|
+
module Rls
|
|
5
|
+
class ContextMiddleware
|
|
6
|
+
def initialize(app)
|
|
7
|
+
@app = app
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def call(env)
|
|
11
|
+
response = @app.call(env)
|
|
12
|
+
response
|
|
13
|
+
ensure
|
|
14
|
+
Vert::Rls::ConnectionHandler.reset_context if Vert.config.enable_rls
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
module ControllerContext
|
|
19
|
+
extend ActiveSupport::Concern
|
|
20
|
+
|
|
21
|
+
included do
|
|
22
|
+
after_action :configure_rls_context, if: -> { Vert.config.enable_rls }
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
|
|
27
|
+
def configure_rls_context
|
|
28
|
+
return unless Vert::Current.tenant_id.present?
|
|
29
|
+
Vert::Rls::ConnectionHandler.set_context(
|
|
30
|
+
tenant_id: Vert::Current.tenant_id,
|
|
31
|
+
company_id: Vert::Current.company_id,
|
|
32
|
+
user_id: Vert::Current.user_id
|
|
33
|
+
)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Vert
|
|
4
|
+
module Rls
|
|
5
|
+
module JobContext
|
|
6
|
+
extend ActiveSupport::Concern
|
|
7
|
+
|
|
8
|
+
class_methods do
|
|
9
|
+
def perform_async(*args)
|
|
10
|
+
super(*args, __vert_context__: Vert::Current.serialize)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def perform_in(interval, *args)
|
|
14
|
+
super(interval, *args, __vert_context__: Vert::Current.serialize)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def perform_at(timestamp, *args)
|
|
18
|
+
super(timestamp, *args, __vert_context__: Vert::Current.serialize)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def perform(*args)
|
|
23
|
+
context = args.last.is_a?(Hash) && (args.last.delete(:__vert_context__) || args.last.delete("__vert_context__"))
|
|
24
|
+
Vert::Current.deserialize(context) if context
|
|
25
|
+
Vert::Rls::ConnectionHandler.set_context(tenant_id: Vert::Current.tenant_id, company_id: Vert::Current.company_id, user_id: Vert::Current.user_id) if Vert.config.enable_rls && Vert::Current.tenant_id.present?
|
|
26
|
+
|
|
27
|
+
clean = args.last.is_a?(Hash) ? (args[0..-2] + [args.last.except(:__vert_context__, "__vert_context__")]).reject { |a| a.respond_to?(:empty?) && a.empty? } : args
|
|
28
|
+
super(*clean)
|
|
29
|
+
ensure
|
|
30
|
+
Vert::Current.reset_all
|
|
31
|
+
Vert::Rls::ConnectionHandler.reset_context if Vert.config.enable_rls
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
class JobMiddleware
|
|
36
|
+
def call(_worker, job, _queue)
|
|
37
|
+
context = job.delete("__vert_context__")
|
|
38
|
+
if context
|
|
39
|
+
Vert::Current.deserialize(context)
|
|
40
|
+
Vert::Rls::ConnectionHandler.set_context(tenant_id: Vert::Current.tenant_id, company_id: Vert::Current.company_id, user_id: Vert::Current.user_id) if Vert.config.enable_rls && Vert::Current.tenant_id.present?
|
|
41
|
+
end
|
|
42
|
+
yield
|
|
43
|
+
ensure
|
|
44
|
+
Vert::Current.reset_all
|
|
45
|
+
Vert::Rls::ConnectionHandler.reset_context if Vert.config.enable_rls
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
class JobClientMiddleware
|
|
50
|
+
def call(_worker_class, job, _queue, _redis_pool)
|
|
51
|
+
job["__vert_context__"] = Vert::Current.serialize
|
|
52
|
+
yield
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
data/lib/vert/version.rb
ADDED
data/lib/vert.rb
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "vert/version"
|
|
4
|
+
require_relative "vert/configuration"
|
|
5
|
+
|
|
6
|
+
# Concerns (sempre carregados; inclua no model conforme necessário)
|
|
7
|
+
require_relative "vert/concerns/current_attributes"
|
|
8
|
+
require_relative "vert/concerns/uuid_primary_key"
|
|
9
|
+
require_relative "vert/concerns/auditable"
|
|
10
|
+
require_relative "vert/concerns/soft_deletable"
|
|
11
|
+
require_relative "vert/concerns/multi_tenant"
|
|
12
|
+
require_relative "vert/concerns/company_scoped"
|
|
13
|
+
require_relative "vert/concerns/document_storeable"
|
|
14
|
+
|
|
15
|
+
# Clients
|
|
16
|
+
require_relative "vert/clients/document_service_client"
|
|
17
|
+
|
|
18
|
+
# Outbox
|
|
19
|
+
require_relative "vert/outbox/event"
|
|
20
|
+
require_relative "vert/outbox/publisher"
|
|
21
|
+
require_relative "vert/outbox/publisher_job"
|
|
22
|
+
|
|
23
|
+
# RLS
|
|
24
|
+
require_relative "vert/rls/context_middleware"
|
|
25
|
+
require_relative "vert/rls/job_context"
|
|
26
|
+
require_relative "vert/rls/consumer_context"
|
|
27
|
+
require_relative "vert/rls/connection_handler"
|
|
28
|
+
|
|
29
|
+
# Health
|
|
30
|
+
require_relative "vert/health/checker"
|
|
31
|
+
require_relative "vert/health/routes"
|
|
32
|
+
|
|
33
|
+
# Authorization
|
|
34
|
+
require_relative "vert/authorization/permission_resolver"
|
|
35
|
+
require_relative "vert/authorization/dynamic_policy"
|
|
36
|
+
require_relative "vert/authorization/policy_finder"
|
|
37
|
+
require_relative "vert/authorization/controller_methods"
|
|
38
|
+
|
|
39
|
+
# Railtie
|
|
40
|
+
require_relative "vert/railtie" if defined?(Rails::Railtie)
|
|
41
|
+
|
|
42
|
+
module Vert
|
|
43
|
+
class Error < StandardError; end
|
|
44
|
+
class TenantNotSetError < Error; end
|
|
45
|
+
class CompanyNotSetError < Error; end
|
|
46
|
+
|
|
47
|
+
class << self
|
|
48
|
+
def configure
|
|
49
|
+
yield(configuration)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def configuration
|
|
53
|
+
@configuration ||= Vert::Configuration.new
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
alias config configuration
|
|
57
|
+
end
|
|
58
|
+
end
|
data/vert.gemspec
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "lib/vert/version"
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |spec|
|
|
6
|
+
spec.name = "vert-core"
|
|
7
|
+
spec.version = Vert::VERSION
|
|
8
|
+
spec.authors = ["Vert Team"]
|
|
9
|
+
spec.email = ["dev@vert.dev"]
|
|
10
|
+
|
|
11
|
+
spec.summary = "Generic core library for Rails microservices"
|
|
12
|
+
spec.description = "Optional patterns for Rails apps: multi-tenancy, RLS, outbox, health checks, auditing, soft delete, UUID primary keys, and document storage client. All features are configurable via initializer."
|
|
13
|
+
spec.homepage = "https://github.com/edinaldo-novti/vert"
|
|
14
|
+
spec.license = "MIT"
|
|
15
|
+
spec.required_ruby_version = ">= 3.2.0"
|
|
16
|
+
|
|
17
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
|
18
|
+
spec.metadata["source_code_uri"] = spec.homepage
|
|
19
|
+
spec.metadata["changelog_uri"] = "#{spec.homepage}/blob/main/CHANGELOG.md"
|
|
20
|
+
|
|
21
|
+
spec.files = Dir.chdir(__dir__) do
|
|
22
|
+
Dir.glob("**/*").reject do |f|
|
|
23
|
+
File.directory?(f) ||
|
|
24
|
+
(File.expand_path(f) == __FILE__) ||
|
|
25
|
+
f.start_with?(*%w[bin/ test/ spec/ features/ .git .circleci appveyor Gemfile])
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
spec.bindir = "exe"
|
|
29
|
+
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
|
30
|
+
spec.require_paths = ["lib"]
|
|
31
|
+
|
|
32
|
+
spec.add_dependency "activesupport", ">= 7.0"
|
|
33
|
+
spec.add_dependency "activerecord", ">= 7.0"
|
|
34
|
+
spec.add_dependency "discard", "~> 1.3"
|
|
35
|
+
spec.add_dependency "bunny", "~> 2.22"
|
|
36
|
+
spec.add_dependency "sidekiq", ">= 7.0"
|
|
37
|
+
|
|
38
|
+
spec.add_development_dependency "rake", "~> 13.0"
|
|
39
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
|
40
|
+
spec.add_development_dependency "rubocop", "~> 1.21"
|
|
41
|
+
spec.add_development_dependency "rubocop-rails", "~> 2.0"
|
|
42
|
+
spec.add_development_dependency "rubocop-rspec", "~> 2.0"
|
|
43
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: vert-core
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Vert Team
|
|
8
|
+
bindir: exe
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: activesupport
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '7.0'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - ">="
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '7.0'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: activerecord
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - ">="
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '7.0'
|
|
33
|
+
type: :runtime
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - ">="
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '7.0'
|
|
40
|
+
- !ruby/object:Gem::Dependency
|
|
41
|
+
name: discard
|
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - "~>"
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '1.3'
|
|
47
|
+
type: :runtime
|
|
48
|
+
prerelease: false
|
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - "~>"
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '1.3'
|
|
54
|
+
- !ruby/object:Gem::Dependency
|
|
55
|
+
name: bunny
|
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - "~>"
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: '2.22'
|
|
61
|
+
type: :runtime
|
|
62
|
+
prerelease: false
|
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - "~>"
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: '2.22'
|
|
68
|
+
- !ruby/object:Gem::Dependency
|
|
69
|
+
name: sidekiq
|
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
|
71
|
+
requirements:
|
|
72
|
+
- - ">="
|
|
73
|
+
- !ruby/object:Gem::Version
|
|
74
|
+
version: '7.0'
|
|
75
|
+
type: :runtime
|
|
76
|
+
prerelease: false
|
|
77
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
78
|
+
requirements:
|
|
79
|
+
- - ">="
|
|
80
|
+
- !ruby/object:Gem::Version
|
|
81
|
+
version: '7.0'
|
|
82
|
+
- !ruby/object:Gem::Dependency
|
|
83
|
+
name: rake
|
|
84
|
+
requirement: !ruby/object:Gem::Requirement
|
|
85
|
+
requirements:
|
|
86
|
+
- - "~>"
|
|
87
|
+
- !ruby/object:Gem::Version
|
|
88
|
+
version: '13.0'
|
|
89
|
+
type: :development
|
|
90
|
+
prerelease: false
|
|
91
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
92
|
+
requirements:
|
|
93
|
+
- - "~>"
|
|
94
|
+
- !ruby/object:Gem::Version
|
|
95
|
+
version: '13.0'
|
|
96
|
+
- !ruby/object:Gem::Dependency
|
|
97
|
+
name: rspec
|
|
98
|
+
requirement: !ruby/object:Gem::Requirement
|
|
99
|
+
requirements:
|
|
100
|
+
- - "~>"
|
|
101
|
+
- !ruby/object:Gem::Version
|
|
102
|
+
version: '3.0'
|
|
103
|
+
type: :development
|
|
104
|
+
prerelease: false
|
|
105
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
106
|
+
requirements:
|
|
107
|
+
- - "~>"
|
|
108
|
+
- !ruby/object:Gem::Version
|
|
109
|
+
version: '3.0'
|
|
110
|
+
- !ruby/object:Gem::Dependency
|
|
111
|
+
name: rubocop
|
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
|
113
|
+
requirements:
|
|
114
|
+
- - "~>"
|
|
115
|
+
- !ruby/object:Gem::Version
|
|
116
|
+
version: '1.21'
|
|
117
|
+
type: :development
|
|
118
|
+
prerelease: false
|
|
119
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
120
|
+
requirements:
|
|
121
|
+
- - "~>"
|
|
122
|
+
- !ruby/object:Gem::Version
|
|
123
|
+
version: '1.21'
|
|
124
|
+
- !ruby/object:Gem::Dependency
|
|
125
|
+
name: rubocop-rails
|
|
126
|
+
requirement: !ruby/object:Gem::Requirement
|
|
127
|
+
requirements:
|
|
128
|
+
- - "~>"
|
|
129
|
+
- !ruby/object:Gem::Version
|
|
130
|
+
version: '2.0'
|
|
131
|
+
type: :development
|
|
132
|
+
prerelease: false
|
|
133
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
134
|
+
requirements:
|
|
135
|
+
- - "~>"
|
|
136
|
+
- !ruby/object:Gem::Version
|
|
137
|
+
version: '2.0'
|
|
138
|
+
- !ruby/object:Gem::Dependency
|
|
139
|
+
name: rubocop-rspec
|
|
140
|
+
requirement: !ruby/object:Gem::Requirement
|
|
141
|
+
requirements:
|
|
142
|
+
- - "~>"
|
|
143
|
+
- !ruby/object:Gem::Version
|
|
144
|
+
version: '2.0'
|
|
145
|
+
type: :development
|
|
146
|
+
prerelease: false
|
|
147
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
148
|
+
requirements:
|
|
149
|
+
- - "~>"
|
|
150
|
+
- !ruby/object:Gem::Version
|
|
151
|
+
version: '2.0'
|
|
152
|
+
description: 'Optional patterns for Rails apps: multi-tenancy, RLS, outbox, health
|
|
153
|
+
checks, auditing, soft delete, UUID primary keys, and document storage client. All
|
|
154
|
+
features are configurable via initializer.'
|
|
155
|
+
email:
|
|
156
|
+
- dev@vert.dev
|
|
157
|
+
executables: []
|
|
158
|
+
extensions: []
|
|
159
|
+
extra_rdoc_files: []
|
|
160
|
+
files:
|
|
161
|
+
- CHANGELOG.md
|
|
162
|
+
- README.md
|
|
163
|
+
- lib/vert.rb
|
|
164
|
+
- lib/vert/authorization/controller_methods.rb
|
|
165
|
+
- lib/vert/authorization/dynamic_policy.rb
|
|
166
|
+
- lib/vert/authorization/permission_resolver.rb
|
|
167
|
+
- lib/vert/authorization/policy_finder.rb
|
|
168
|
+
- lib/vert/clients/document_service_client.rb
|
|
169
|
+
- lib/vert/concerns/auditable.rb
|
|
170
|
+
- lib/vert/concerns/company_scoped.rb
|
|
171
|
+
- lib/vert/concerns/current_attributes.rb
|
|
172
|
+
- lib/vert/concerns/document_storeable.rb
|
|
173
|
+
- lib/vert/concerns/multi_tenant.rb
|
|
174
|
+
- lib/vert/concerns/soft_deletable.rb
|
|
175
|
+
- lib/vert/concerns/uuid_primary_key.rb
|
|
176
|
+
- lib/vert/configuration.rb
|
|
177
|
+
- lib/vert/generators/install_generator.rb
|
|
178
|
+
- lib/vert/generators/rls_migration_generator.rb
|
|
179
|
+
- lib/vert/generators/templates/application_record.rb.tt
|
|
180
|
+
- lib/vert/generators/templates/create_outbox_events.rb.tt
|
|
181
|
+
- lib/vert/generators/templates/create_rls_functions.rb.tt
|
|
182
|
+
- lib/vert/generators/templates/current.rb.tt
|
|
183
|
+
- lib/vert/generators/templates/enable_rls_on_tables.rb.tt
|
|
184
|
+
- lib/vert/generators/templates/health_controller.rb.tt
|
|
185
|
+
- lib/vert/generators/templates/initializer.rb.tt
|
|
186
|
+
- lib/vert/generators/templates/outbox_event.rb.tt
|
|
187
|
+
- lib/vert/health/checker.rb
|
|
188
|
+
- lib/vert/health/routes.rb
|
|
189
|
+
- lib/vert/outbox/event.rb
|
|
190
|
+
- lib/vert/outbox/publisher.rb
|
|
191
|
+
- lib/vert/outbox/publisher_job.rb
|
|
192
|
+
- lib/vert/railtie.rb
|
|
193
|
+
- lib/vert/rls/connection_handler.rb
|
|
194
|
+
- lib/vert/rls/consumer_context.rb
|
|
195
|
+
- lib/vert/rls/context_middleware.rb
|
|
196
|
+
- lib/vert/rls/job_context.rb
|
|
197
|
+
- lib/vert/version.rb
|
|
198
|
+
- vert.gemspec
|
|
199
|
+
homepage: https://github.com/edinaldo-novti/vert
|
|
200
|
+
licenses:
|
|
201
|
+
- MIT
|
|
202
|
+
metadata:
|
|
203
|
+
homepage_uri: https://github.com/edinaldo-novti/vert
|
|
204
|
+
source_code_uri: https://github.com/edinaldo-novti/vert
|
|
205
|
+
changelog_uri: https://github.com/edinaldo-novti/vert/blob/main/CHANGELOG.md
|
|
206
|
+
rdoc_options: []
|
|
207
|
+
require_paths:
|
|
208
|
+
- lib
|
|
209
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
210
|
+
requirements:
|
|
211
|
+
- - ">="
|
|
212
|
+
- !ruby/object:Gem::Version
|
|
213
|
+
version: 3.2.0
|
|
214
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
215
|
+
requirements:
|
|
216
|
+
- - ">="
|
|
217
|
+
- !ruby/object:Gem::Version
|
|
218
|
+
version: '0'
|
|
219
|
+
requirements: []
|
|
220
|
+
rubygems_version: 3.6.9
|
|
221
|
+
specification_version: 4
|
|
222
|
+
summary: Generic core library for Rails microservices
|
|
223
|
+
test_files: []
|