eventush 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.
- checksums.yaml +7 -0
- data/README.md +28 -0
- data/Rakefile +22 -0
- data/app/consumers/barong/model/label_updated_consumer.rb +25 -0
- data/app/consumers/peatio/model/deposit_created_consumer.rb +23 -0
- data/app/controllers/concerns/exception_handlers.rb +19 -0
- data/app/controllers/concerns/jwt_payload.rb +19 -0
- data/app/controllers/concerns/response.rb +25 -0
- data/app/controllers/event/api/v2/admin/base_controller.rb +22 -0
- data/app/controllers/event/api/v2/admin/events_controller.rb +59 -0
- data/app/controllers/event/application_controller.rb +9 -0
- data/app/helpers/event/application_helper.rb +4 -0
- data/app/helpers/event/event_helper.rb +4 -0
- data/app/models/concerns/currency.rb +26 -0
- data/app/models/event/application_record.rb +5 -0
- data/app/models/event/event.rb +82 -0
- data/app/models/event/participant.rb +83 -0
- data/app/services/barong/management_api_v2/client.rb +33 -0
- data/app/services/event_api_listener.rb +120 -0
- data/app/services/management_api_v2/client.rb +73 -0
- data/app/services/management_api_v2/exception.rb +25 -0
- data/app/services/peatio/management_api_v2/client.rb +27 -0
- data/config/initializers/active_model.rb +13 -0
- data/config/initializers/api_pagination.rb +33 -0
- data/config/initializers/inflections.rb +18 -0
- data/config/routes.rb +12 -0
- data/db/migrate/20200825103859_create_events.rb +24 -0
- data/lib/event.rb +10 -0
- data/lib/event/engine.rb +17 -0
- data/lib/event/version.rb +3 -0
- data/lib/tasks/auto_annotate_models.rake +59 -0
- data/lib/tasks/event_api.rake +9 -0
- data/lib/tasks/event_tasks.rake +4 -0
- data/spec/controllers/event/api/v2/admin/metadata_controller_spec.rb +72 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/config/manifest.js +3 -0
- data/spec/dummy/app/assets/stylesheets/application.css +15 -0
- data/spec/dummy/app/channels/application_cable/channel.rb +4 -0
- data/spec/dummy/app/channels/application_cable/connection.rb +4 -0
- data/spec/dummy/app/controllers/application_controller.rb +2 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/javascript/packs/application.js +15 -0
- data/spec/dummy/app/jobs/application_job.rb +7 -0
- data/spec/dummy/app/mailers/application_mailer.rb +4 -0
- data/spec/dummy/app/models/application_record.rb +3 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/app/views/layouts/mailer.html.erb +13 -0
- data/spec/dummy/app/views/layouts/mailer.text.erb +1 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/bin/setup +33 -0
- data/spec/dummy/config.ru +5 -0
- data/spec/dummy/config/application.rb +30 -0
- data/spec/dummy/config/application.yml +42 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/cable.yml +10 -0
- data/spec/dummy/config/database.yml +17 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +62 -0
- data/spec/dummy/config/environments/production.rb +112 -0
- data/spec/dummy/config/environments/test.rb +48 -0
- data/spec/dummy/config/initializers/application_controller_renderer.rb +8 -0
- data/spec/dummy/config/initializers/assets.rb +12 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/content_security_policy.rb +28 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +5 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +18 -0
- data/spec/dummy/config/initializers/mime_types.rb +4 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +33 -0
- data/spec/dummy/config/puma.rb +38 -0
- data/spec/dummy/config/routes.rb +3 -0
- data/spec/dummy/config/spring.rb +6 -0
- data/spec/dummy/config/storage.yml +34 -0
- data/spec/dummy/db/schema.rb +37 -0
- data/spec/dummy/public/404.html +67 -0
- data/spec/dummy/public/422.html +67 -0
- data/spec/dummy/public/500.html +66 -0
- data/spec/dummy/public/apple-touch-icon-precomposed.png +0 -0
- data/spec/dummy/public/apple-touch-icon.png +0 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/tmp/development_secret.txt +1 -0
- data/spec/factories/event/events.rb +22 -0
- data/spec/factories/event/participants.rb +21 -0
- data/spec/factories/event/sequences.rb +26 -0
- data/spec/models/event/event_spec.rb +24 -0
- data/spec/models/event/participant_spec.rb +23 -0
- data/spec/rails_helper.rb +72 -0
- data/spec/routing/metadastore/metadata_routing_spec.rb +29 -0
- data/spec/spec_helper.rb +96 -0
- data/spec/support/api_helper.rb +46 -0
- data/spec/support/auth_helper.rb +15 -0
- data/spec/support/rspec_matchers.rb +17 -0
- metadata +352 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
module Barong
|
|
2
|
+
module ManagementAPIV2
|
|
3
|
+
class Client < ::ManagementAPIV2::Client
|
|
4
|
+
def initialize(*)
|
|
5
|
+
super ENV.fetch('BARONG_URL'), Rails.configuration.x.barong_management_api_v2_configuration
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def otp_sign(request_params = {})
|
|
9
|
+
self.action = :otp_sign
|
|
10
|
+
params = request_params.slice(:user_uid, :otp_code, :jwt)
|
|
11
|
+
request(:post, 'otp/sign', params)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def get_user_info(request_params={})
|
|
15
|
+
self.action = :read_users
|
|
16
|
+
params = request_params.slice(:uid, :extended, :jwt)
|
|
17
|
+
request(:post, "users/get", params)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def update_label(request_params = {})
|
|
21
|
+
self.action = :write_labels
|
|
22
|
+
params = request_params.slice(:user_uid, :key, :value, :jwt, :replace)
|
|
23
|
+
request(:put, 'labels', params)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def create_label(request_params = {})
|
|
27
|
+
self.action = :write_labels
|
|
28
|
+
params = request_params.slice(:user_uid, :key, :value, :jwt)
|
|
29
|
+
request(:post, 'labels', params)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'bunny'
|
|
4
|
+
|
|
5
|
+
class EventAPIListener
|
|
6
|
+
def initialize(application, event_category, event_name)
|
|
7
|
+
@application = application
|
|
8
|
+
@event_category = event_category
|
|
9
|
+
@event_name = event_name
|
|
10
|
+
Kernel.at_exit { unlisten }
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def call
|
|
14
|
+
consumer # Eager load consumer to early detect errors.
|
|
15
|
+
listen
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
def event_api_jwt_env(suffix)
|
|
21
|
+
ENV["#{@application.upcase}_EVENT_API_JWT_#{suffix}"]
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def event_api_jwt_env_to_int(suffix)
|
|
25
|
+
event_api_jwt_env(suffix).to_s.squish.yield_self { |n| n.to_i if n.present? }
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def listen
|
|
29
|
+
unlisten
|
|
30
|
+
@bunny_session = Bunny::Session.new(rabbitmq_credentials).tap(&:start)
|
|
31
|
+
@bunny_channel = @bunny_session.channel
|
|
32
|
+
exchange_name = [@application, 'events', @event_category].join('.')
|
|
33
|
+
exchange = @bunny_channel.direct(exchange_name)
|
|
34
|
+
queue = @bunny_channel.queue('', auto_delete: true, durable: true)
|
|
35
|
+
.bind(exchange, routing_key: @event_name)
|
|
36
|
+
Rails.logger.info { "Listening for #{exchange_name}.#{@event_name}." }
|
|
37
|
+
queue.subscribe(block: true, &method(:handle_message))
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def unlisten
|
|
41
|
+
Rails.logger.info { 'No longer listening for events.' } if @bunny_session || @bunny_channel
|
|
42
|
+
@bunny_channel&.work_pool&.kill
|
|
43
|
+
@bunny_session&.stop
|
|
44
|
+
ensure
|
|
45
|
+
@bunny_channel = nil
|
|
46
|
+
@bunny_session = nil
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def jwt_public_key
|
|
50
|
+
pem = Base64.urlsafe_decode64(event_api_jwt_env('PUBLIC_KEY'))
|
|
51
|
+
OpenSSL::PKey.read(pem)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def token_verification_options
|
|
55
|
+
# We set option only if it is not blank.
|
|
56
|
+
{ verify_jti: true,
|
|
57
|
+
iss: event_api_jwt_env('ISSUER').to_s.squish.presence,
|
|
58
|
+
verify_iss: event_api_jwt_env('ISSUER').present?,
|
|
59
|
+
aud: event_api_jwt_env('AUDIENCE').to_s.squish.presence,
|
|
60
|
+
verify_aud: event_api_jwt_env('AUDIENCE').present?,
|
|
61
|
+
sub: event_api_jwt_env('SUBJECT'),
|
|
62
|
+
verify_sub: event_api_jwt_env('SUBJECT').present? }
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def algorithm_verification_options
|
|
66
|
+
{ algorithms: [ENV.fetch("#{@application.upcase}_EVENT_API_JWT_ALGORITHM")] }
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def timing_verification_options
|
|
70
|
+
{ verify_expiration: true, verify_not_before: true, verify_iat: true,
|
|
71
|
+
leeway: event_api_jwt_env_to_int('DEFAULT_LEEWAY'),
|
|
72
|
+
iat_leeway: event_api_jwt_env_to_int('ISSUED_AT_LEEWAY'),
|
|
73
|
+
exp_leeway: event_api_jwt_env_to_int('EXPIRATION_LEEWAY'),
|
|
74
|
+
nbf_leeway: event_api_jwt_env_to_int('NOT_BEFORE_LEEWAY') }
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def rabbitmq_credentials
|
|
78
|
+
@application.upcase.yield_self do |_app|
|
|
79
|
+
if ENV['EVENT_API_RABBITMQ_URL'].present?
|
|
80
|
+
ENV['EVENT_API_RABBITMQ_URL']
|
|
81
|
+
else
|
|
82
|
+
{ host: ENV.fetch('EVENT_API_RABBITMQ_HOST'),
|
|
83
|
+
port: ENV.fetch('EVENT_API_RABBITMQ_PORT'),
|
|
84
|
+
username: ENV.fetch('EVENT_API_RABBITMQ_USERNAME'),
|
|
85
|
+
password: ENV.fetch('EVENT_API_RABBITMQ_PASSWORD') }
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def handle_message(_delivery_info, _metadata, payload)
|
|
91
|
+
result = verify_jwt(payload)
|
|
92
|
+
|
|
93
|
+
raise "Failed to verify signature from #{@application}." \
|
|
94
|
+
unless result[:verified].include?(@application.to_sym)
|
|
95
|
+
consumer.call(result[:payload].fetch(:event))
|
|
96
|
+
rescue StandardError => e
|
|
97
|
+
Rails.logger.error { e.inspect }
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def consumer
|
|
101
|
+
[@application, @event_category, @event_name.tr('.', '_') + '_consumer']
|
|
102
|
+
.map { |x| x.tr('.', '_') }
|
|
103
|
+
.join('/')
|
|
104
|
+
.camelize
|
|
105
|
+
.constantize
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def verify_jwt(payload)
|
|
109
|
+
options = token_verification_options.merge(timing_verification_options)
|
|
110
|
+
.merge(algorithm_verification_options)
|
|
111
|
+
JWT::Multisig.verify_jwt JSON.parse(payload), { @application.to_sym => jwt_public_key },
|
|
112
|
+
options.compact
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
class << self
|
|
116
|
+
def call(*args)
|
|
117
|
+
new(*args).call
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
end
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'securerandom'
|
|
4
|
+
|
|
5
|
+
module ManagementAPIV2
|
|
6
|
+
class Client
|
|
7
|
+
|
|
8
|
+
attr_reader :action
|
|
9
|
+
|
|
10
|
+
def initialize(root_url, security_configuration)
|
|
11
|
+
@root_api_url = root_url
|
|
12
|
+
@security_configuration = security_configuration
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def request(request_method, request_path, request_parameters, options = {})
|
|
16
|
+
options = { jwt: false }.merge(options)
|
|
17
|
+
raise ArgumentError, "Request method is not supported: #{request_method.inspect}." unless request_method.in?(%i[post put])
|
|
18
|
+
|
|
19
|
+
request_parameters = generate_jwt(payload(request_parameters)) unless options[:jwt]
|
|
20
|
+
|
|
21
|
+
begin
|
|
22
|
+
http_client
|
|
23
|
+
.public_send(request_method, build_path(request_path), request_parameters)
|
|
24
|
+
.tap { |response| raise ManagementAPIV2::Exception.new(response) unless response.success? }
|
|
25
|
+
.body
|
|
26
|
+
.symbolize_keys
|
|
27
|
+
|
|
28
|
+
rescue Faraday::Error => e
|
|
29
|
+
raise ManagementAPIV2::Exception.new
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def build_path(path)
|
|
34
|
+
"api/v2/management/#{path}"
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def http_client
|
|
38
|
+
Faraday.new(url: @root_api_url) do |conn|
|
|
39
|
+
conn.request :json
|
|
40
|
+
conn.response :json
|
|
41
|
+
conn.adapter Faraday.default_adapter
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def keychain(field)
|
|
46
|
+
{}.tap do |h|
|
|
47
|
+
@security_configuration[:keychain].each do |id, key|
|
|
48
|
+
next unless action
|
|
49
|
+
next unless id.in?(action[:required_signatures])
|
|
50
|
+
h[id] = key[field]
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def payload(data = {})
|
|
56
|
+
{
|
|
57
|
+
data: data,
|
|
58
|
+
iat: Time.now.to_i,
|
|
59
|
+
exp: Time.now.to_i + ENV.fetch('JWT_EXPIRE_DATE', 60).to_i,
|
|
60
|
+
jti: SecureRandom.hex(12),
|
|
61
|
+
iss: 'applogic'
|
|
62
|
+
}
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def generate_jwt(payload)
|
|
66
|
+
JWT::Multisig.generate_jwt(payload, keychain(:value), keychain(:algorithm))
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def action=(value)
|
|
70
|
+
@action = @security_configuration[:actions].fetch(value)
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ManagementAPIV2
|
|
4
|
+
class Exception < StandardError
|
|
5
|
+
attr_accessor :status
|
|
6
|
+
|
|
7
|
+
def initialize(response_or_ex="External services error")
|
|
8
|
+
@status = 503
|
|
9
|
+
if response_or_ex.respond_to?(:body)
|
|
10
|
+
@status = 422
|
|
11
|
+
body = response_or_ex.body || {}
|
|
12
|
+
|
|
13
|
+
if body.fetch("error", false)
|
|
14
|
+
super body.fetch("error")
|
|
15
|
+
elsif body.fetch("errors", false)
|
|
16
|
+
super Array(body.fetch("errors")).first
|
|
17
|
+
else
|
|
18
|
+
super response_or_ex.body
|
|
19
|
+
end
|
|
20
|
+
else
|
|
21
|
+
super response_or_ex
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
module Peatio
|
|
2
|
+
module ManagementAPIV2
|
|
3
|
+
class Client < ::ManagementAPIV2::Client
|
|
4
|
+
def initialize(*)
|
|
5
|
+
super ENV.fetch('PEATIO_URL'), Rails.configuration.x.peatio_management_api_v2_configuration
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def create_transfer(request_params={})
|
|
9
|
+
self.action = :write_transfers
|
|
10
|
+
params = request_params.slice(:key, :category, :description, :operations)
|
|
11
|
+
request(:post, "transfers/new", params, {})
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def balance(request_params={})
|
|
15
|
+
self.action = :read_accounts
|
|
16
|
+
params = request_params.slice(:uid, :currency)
|
|
17
|
+
request(:post, "/accounts/balance", params, {})
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def currency(request_params={})
|
|
21
|
+
self.action = :read_currencies
|
|
22
|
+
params = request_params.slice(:code)
|
|
23
|
+
request(:post, "/currencies/#{params[:code]}", {})
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
Module.new do
|
|
4
|
+
def api_messages
|
|
5
|
+
map do |attr, err|
|
|
6
|
+
if err.start_with?("_")
|
|
7
|
+
[attr, err]
|
|
8
|
+
else
|
|
9
|
+
[err, attr]
|
|
10
|
+
end.join
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end.tap { |m| ActiveSupport.on_load(:active_record) { ActiveModel::Errors.include(m) } }
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "api-pagination"
|
|
4
|
+
require "pagy/countless"
|
|
5
|
+
require "pagy/extras/overflow"
|
|
6
|
+
|
|
7
|
+
ApiPagination.configure do |config|
|
|
8
|
+
# If you have more than one gem included, you can choose a paginator.
|
|
9
|
+
config.paginator = :pagy # or :will_ApiPagination.paginate
|
|
10
|
+
|
|
11
|
+
# By default, this is set to 'Total'
|
|
12
|
+
# config.total_header = 'X-Total'
|
|
13
|
+
|
|
14
|
+
# By default, this is set to 'Per-Page'
|
|
15
|
+
# config.per_page_header = 'X-Per-Page'
|
|
16
|
+
|
|
17
|
+
# Optional: set this to add a header with the current page number.
|
|
18
|
+
config.page_header = "Page"
|
|
19
|
+
|
|
20
|
+
# Optional: set this to add other response format. Useful with tools that define :jsonapi format
|
|
21
|
+
# config.response_formats = [:json, :xml, :jsonapi]
|
|
22
|
+
|
|
23
|
+
# Optional: what parameter should be used to set the page option
|
|
24
|
+
config.page_param = :page
|
|
25
|
+
|
|
26
|
+
# Optional: what parameter should be used to set the per page option
|
|
27
|
+
config.per_page_param = :limit
|
|
28
|
+
|
|
29
|
+
# Optional: Include the total and last_page link header
|
|
30
|
+
# By default, this is set to true
|
|
31
|
+
# Note: When using kaminari, this prevents the count call to the database
|
|
32
|
+
# config.include_total = false
|
|
33
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# Be sure to restart your server when you modify this file.
|
|
3
|
+
|
|
4
|
+
# Add new inflection rules using the following format. Inflections
|
|
5
|
+
# are locale specific, and you may define rules for as many different
|
|
6
|
+
# locales as you wish. All of these examples are active by default:
|
|
7
|
+
# ActiveSupport::Inflector.inflections(:en) do |inflect|
|
|
8
|
+
# inflect.plural /^(ox)$/i, '\1en'
|
|
9
|
+
# inflect.singular /^(ox)en/i, '\1'
|
|
10
|
+
# inflect.irregular 'person', 'people'
|
|
11
|
+
# inflect.uncountable %w( fish sheep )
|
|
12
|
+
# end
|
|
13
|
+
|
|
14
|
+
# These inflection rules are supported but not enabled by default:
|
|
15
|
+
ActiveSupport::Inflector.inflections(:en) do |inflect|
|
|
16
|
+
inflect.acronym "API"
|
|
17
|
+
inflect.acronym "JWT"
|
|
18
|
+
end
|
data/config/routes.rb
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
class CreateEvents < ActiveRecord::Migration[6.0]
|
|
2
|
+
def change
|
|
3
|
+
create_table "events", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
|
|
4
|
+
t.string :name, null: false
|
|
5
|
+
t.string :trigger_key, null: false
|
|
6
|
+
t.string :trigger_value, null: false
|
|
7
|
+
t.decimal :amount, null: false
|
|
8
|
+
t.string :currency_id, null: false
|
|
9
|
+
t.integer :state, null: false
|
|
10
|
+
t.string :creator_uid, null: false
|
|
11
|
+
t.string :description
|
|
12
|
+
|
|
13
|
+
t.timestamps
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
create_table "event_participants", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
|
|
17
|
+
t.references :event, null: false
|
|
18
|
+
t.string :uid, null: false
|
|
19
|
+
t.string :transfer_keys, limit: 1000
|
|
20
|
+
|
|
21
|
+
t.timestamps
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
data/lib/event.rb
ADDED
data/lib/event/engine.rb
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Event
|
|
4
|
+
class Engine < ::Rails::Engine
|
|
5
|
+
isolate_namespace Event
|
|
6
|
+
|
|
7
|
+
config.generators do |generators|
|
|
8
|
+
generators.test_framework :rspec
|
|
9
|
+
generators.fixture_replacement :factory_bot
|
|
10
|
+
generators.factory_bot dir: "spec/factories"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
initializer "metadata.factories", after: "factory_bot.set_factory_paths" do
|
|
14
|
+
FactoryBot.definition_file_paths << File.expand_path("../../spec/factories", __dir__) if defined?(FactoryBot)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# NOTE: only doing this in development as some production environments (Heroku)
|
|
2
|
+
# NOTE: are sensitive to local FS writes, and besides -- it's just not proper
|
|
3
|
+
# NOTE: to have a dev-mode tool do its thing in production.
|
|
4
|
+
if Rails.env.development?
|
|
5
|
+
require 'annotate'
|
|
6
|
+
task :set_annotation_options do
|
|
7
|
+
# You can override any of these by setting an environment variable of the
|
|
8
|
+
# same name.
|
|
9
|
+
Annotate.set_defaults(
|
|
10
|
+
'active_admin' => 'false',
|
|
11
|
+
'additional_file_patterns' => [],
|
|
12
|
+
'routes' => 'false',
|
|
13
|
+
'models' => 'true',
|
|
14
|
+
'position_in_routes' => 'after',
|
|
15
|
+
'position_in_class' => 'after',
|
|
16
|
+
'position_in_test' => 'after',
|
|
17
|
+
'position_in_fixture' => 'after',
|
|
18
|
+
'position_in_factory' => 'after',
|
|
19
|
+
'position_in_serializer' => 'after',
|
|
20
|
+
'show_foreign_keys' => 'true',
|
|
21
|
+
'show_complete_foreign_keys' => 'false',
|
|
22
|
+
'show_indexes' => 'true',
|
|
23
|
+
'simple_indexes' => 'false',
|
|
24
|
+
'model_dir' => 'app/models',
|
|
25
|
+
'root_dir' => '',
|
|
26
|
+
'include_version' => 'false',
|
|
27
|
+
'require' => '',
|
|
28
|
+
'exclude_tests' => 'false',
|
|
29
|
+
'exclude_fixtures' => 'false',
|
|
30
|
+
'exclude_factories' => 'false',
|
|
31
|
+
'exclude_serializers' => 'false',
|
|
32
|
+
'exclude_scaffolds' => 'true',
|
|
33
|
+
'exclude_controllers' => 'true',
|
|
34
|
+
'exclude_helpers' => 'true',
|
|
35
|
+
'exclude_sti_subclasses' => 'false',
|
|
36
|
+
'ignore_model_sub_dir' => 'false',
|
|
37
|
+
'ignore_columns' => nil,
|
|
38
|
+
'ignore_routes' => nil,
|
|
39
|
+
'ignore_unknown_models' => 'false',
|
|
40
|
+
'hide_limit_column_types' => 'integer,bigint,boolean',
|
|
41
|
+
'hide_default_column_types' => 'json,jsonb,hstore',
|
|
42
|
+
'skip_on_db_migrate' => 'false',
|
|
43
|
+
'format_bare' => 'true',
|
|
44
|
+
'format_rdoc' => 'false',
|
|
45
|
+
'format_yard' => 'false',
|
|
46
|
+
'format_markdown' => 'false',
|
|
47
|
+
'sort' => 'false',
|
|
48
|
+
'force' => 'false',
|
|
49
|
+
'frozen' => 'false',
|
|
50
|
+
'classified_sort' => 'true',
|
|
51
|
+
'trace' => 'false',
|
|
52
|
+
'wrapper_open' => nil,
|
|
53
|
+
'wrapper_close' => nil,
|
|
54
|
+
'with_comment' => 'true'
|
|
55
|
+
)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
Annotate.load_tasks
|
|
59
|
+
end
|