eventush 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +28 -0
  3. data/Rakefile +22 -0
  4. data/app/consumers/barong/model/label_updated_consumer.rb +25 -0
  5. data/app/consumers/peatio/model/deposit_created_consumer.rb +23 -0
  6. data/app/controllers/concerns/exception_handlers.rb +19 -0
  7. data/app/controllers/concerns/jwt_payload.rb +19 -0
  8. data/app/controllers/concerns/response.rb +25 -0
  9. data/app/controllers/event/api/v2/admin/base_controller.rb +22 -0
  10. data/app/controllers/event/api/v2/admin/events_controller.rb +59 -0
  11. data/app/controllers/event/application_controller.rb +9 -0
  12. data/app/helpers/event/application_helper.rb +4 -0
  13. data/app/helpers/event/event_helper.rb +4 -0
  14. data/app/models/concerns/currency.rb +26 -0
  15. data/app/models/event/application_record.rb +5 -0
  16. data/app/models/event/event.rb +82 -0
  17. data/app/models/event/participant.rb +83 -0
  18. data/app/services/barong/management_api_v2/client.rb +33 -0
  19. data/app/services/event_api_listener.rb +120 -0
  20. data/app/services/management_api_v2/client.rb +73 -0
  21. data/app/services/management_api_v2/exception.rb +25 -0
  22. data/app/services/peatio/management_api_v2/client.rb +27 -0
  23. data/config/initializers/active_model.rb +13 -0
  24. data/config/initializers/api_pagination.rb +33 -0
  25. data/config/initializers/inflections.rb +18 -0
  26. data/config/routes.rb +12 -0
  27. data/db/migrate/20200825103859_create_events.rb +24 -0
  28. data/lib/event.rb +10 -0
  29. data/lib/event/engine.rb +17 -0
  30. data/lib/event/version.rb +3 -0
  31. data/lib/tasks/auto_annotate_models.rake +59 -0
  32. data/lib/tasks/event_api.rake +9 -0
  33. data/lib/tasks/event_tasks.rake +4 -0
  34. data/spec/controllers/event/api/v2/admin/metadata_controller_spec.rb +72 -0
  35. data/spec/dummy/Rakefile +6 -0
  36. data/spec/dummy/app/assets/config/manifest.js +3 -0
  37. data/spec/dummy/app/assets/stylesheets/application.css +15 -0
  38. data/spec/dummy/app/channels/application_cable/channel.rb +4 -0
  39. data/spec/dummy/app/channels/application_cable/connection.rb +4 -0
  40. data/spec/dummy/app/controllers/application_controller.rb +2 -0
  41. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  42. data/spec/dummy/app/javascript/packs/application.js +15 -0
  43. data/spec/dummy/app/jobs/application_job.rb +7 -0
  44. data/spec/dummy/app/mailers/application_mailer.rb +4 -0
  45. data/spec/dummy/app/models/application_record.rb +3 -0
  46. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  47. data/spec/dummy/app/views/layouts/mailer.html.erb +13 -0
  48. data/spec/dummy/app/views/layouts/mailer.text.erb +1 -0
  49. data/spec/dummy/bin/rails +4 -0
  50. data/spec/dummy/bin/rake +4 -0
  51. data/spec/dummy/bin/setup +33 -0
  52. data/spec/dummy/config.ru +5 -0
  53. data/spec/dummy/config/application.rb +30 -0
  54. data/spec/dummy/config/application.yml +42 -0
  55. data/spec/dummy/config/boot.rb +5 -0
  56. data/spec/dummy/config/cable.yml +10 -0
  57. data/spec/dummy/config/database.yml +17 -0
  58. data/spec/dummy/config/environment.rb +5 -0
  59. data/spec/dummy/config/environments/development.rb +62 -0
  60. data/spec/dummy/config/environments/production.rb +112 -0
  61. data/spec/dummy/config/environments/test.rb +48 -0
  62. data/spec/dummy/config/initializers/application_controller_renderer.rb +8 -0
  63. data/spec/dummy/config/initializers/assets.rb +12 -0
  64. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  65. data/spec/dummy/config/initializers/content_security_policy.rb +28 -0
  66. data/spec/dummy/config/initializers/cookies_serializer.rb +5 -0
  67. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  68. data/spec/dummy/config/initializers/inflections.rb +18 -0
  69. data/spec/dummy/config/initializers/mime_types.rb +4 -0
  70. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  71. data/spec/dummy/config/locales/en.yml +33 -0
  72. data/spec/dummy/config/puma.rb +38 -0
  73. data/spec/dummy/config/routes.rb +3 -0
  74. data/spec/dummy/config/spring.rb +6 -0
  75. data/spec/dummy/config/storage.yml +34 -0
  76. data/spec/dummy/db/schema.rb +37 -0
  77. data/spec/dummy/public/404.html +67 -0
  78. data/spec/dummy/public/422.html +67 -0
  79. data/spec/dummy/public/500.html +66 -0
  80. data/spec/dummy/public/apple-touch-icon-precomposed.png +0 -0
  81. data/spec/dummy/public/apple-touch-icon.png +0 -0
  82. data/spec/dummy/public/favicon.ico +0 -0
  83. data/spec/dummy/tmp/development_secret.txt +1 -0
  84. data/spec/factories/event/events.rb +22 -0
  85. data/spec/factories/event/participants.rb +21 -0
  86. data/spec/factories/event/sequences.rb +26 -0
  87. data/spec/models/event/event_spec.rb +24 -0
  88. data/spec/models/event/participant_spec.rb +23 -0
  89. data/spec/rails_helper.rb +72 -0
  90. data/spec/routing/metadastore/metadata_routing_spec.rb +29 -0
  91. data/spec/spec_helper.rb +96 -0
  92. data/spec/support/api_helper.rb +46 -0
  93. data/spec/support/auth_helper.rb +15 -0
  94. data/spec/support/rspec_matchers.rb +17 -0
  95. metadata +352 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 0feb5fb9467f7a4034840be08df5de6483e5de034a81c791dddc64c5ca4f5964
4
+ data.tar.gz: '00056189f5098b5863a4e43c5ed4de2dddbd652ba157341116e05188a8a52ca3'
5
+ SHA512:
6
+ metadata.gz: 13ead9bca1ce3c13a631ab0ff9605c498b648b4eed2878dd7227e77fd1d86e9d385ae8935c5a3d2022531dfa047efcaed6bcc9844bef9cf46a6e83e504458196
7
+ data.tar.gz: c7139a3c48815536dba5443599f96ac037d07944c32ce9d7be6b5ee465f97802547a258b7b21e0eed5f3dd55db380a92682219215cb1854cc4ee8175a10c30e3
data/README.md ADDED
@@ -0,0 +1,28 @@
1
+ # Metadatastore
2
+ Short description and motivation.
3
+
4
+ ## Usage
5
+ How to use my plugin.
6
+
7
+ ## Installation
8
+ Add this line to your application's Gemfile:
9
+
10
+ ```ruby
11
+ gem 'event'
12
+ ```
13
+
14
+ And then execute:
15
+ ```bash
16
+ $ bundle
17
+ ```
18
+
19
+ Or install it yourself as:
20
+ ```bash
21
+ $ gem install event
22
+ ```
23
+
24
+ ## Contributing
25
+ Contribution directions go here.
26
+
27
+ ## License
28
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,22 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'Event'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.md')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+ APP_RAKEFILE = File.expand_path("spec/dummy/Rakefile", __dir__)
18
+ load 'rails/tasks/engine.rake'
19
+
20
+ load 'rails/tasks/statistics.rake'
21
+
22
+ require 'bundler/gem_tasks'
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Barong
4
+ module Model
5
+ class LabelUpdatedConsumer
6
+
7
+ def call(event)
8
+ key = event[:record][:key]
9
+ value = event[:record][:value]
10
+ user = event[:record][:user]
11
+ Event::Event.where(trigger_key: key, trigger_value: value).each do |event|
12
+ next if event.participants.exists?(uid: user[:uid])
13
+
14
+ event.participants.create!(uid: user[:uid])
15
+ end
16
+ end
17
+
18
+ class << self
19
+ def call(event)
20
+ new.call(event)
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Peatio
4
+ module Model
5
+ class DepositCreatedConsumer
6
+
7
+ def call(event)
8
+ user = event[:record][:user]
9
+ Event::Event.where(trigger_key: 'deposit', trigger_value: 'created').each do |event|
10
+ next if event.participants.exists?(uid: user[:uid])
11
+
12
+ event.participants.create!(uid: user[:uid])
13
+ end
14
+ end
15
+
16
+ class << self
17
+ def call(event)
18
+ new.call(event)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ExceptionHandlers
4
+ def self.included(base)
5
+ base.instance_eval do
6
+
7
+ rescue_from ActiveRecord::RecordInvalid do |e|
8
+ record = e.record
9
+ class_name = record.model_name.singular
10
+ errors = record.errors.api_messages.map { |err| "#{class_name}.#{err}" }
11
+ errors_response(errors)
12
+ end
13
+
14
+ rescue_from ActiveRecord::RecordNotFound do |_e|
15
+ error_response("record.not_found", 404)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JWTPayload
4
+ def jwt_payload
5
+ @jwt_payload ||= request.env.fetch("jwt.payload", {}).symbolize_keys
6
+ end
7
+
8
+ def uid
9
+ jwt_payload[:uid]
10
+ end
11
+
12
+ def email
13
+ jwt_payload[:email]
14
+ end
15
+
16
+ def role
17
+ jwt_payload[:role]
18
+ end
19
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Response
4
+ def json_response(object, status=:ok)
5
+ render json: object, status: status
6
+ end
7
+
8
+ def error_response(error, status=422)
9
+ data = "#{controller_namespace}.#{error}"
10
+ json_response({errors: [data]}, status)
11
+ end
12
+
13
+ def errors_response(errors, status=422)
14
+ data = errors.map { |error| "#{controller_namespace}.#{error}" }
15
+ json_response({errors: data}, status)
16
+ end
17
+
18
+ def not_found
19
+ render plain: "404 Not Found", status: 404
20
+ end
21
+
22
+ def controller_namespace
23
+ self.class.module_parent.name.split("::").last.underscore
24
+ end
25
+ end
@@ -0,0 +1,22 @@
1
+ # encoding: UTF-8
2
+ # frozen_string_literal: true
3
+
4
+ module Event
5
+ module API
6
+ module V2
7
+ module Admin
8
+ class BaseController < ApplicationController
9
+ include JWTPayload
10
+
11
+ ADMIN_ROLES = %w[superadmin admin accountant compliance support technical].freeze
12
+
13
+ # before_action :authorize_admin!
14
+
15
+ def authorize_admin!
16
+ not_found unless role.to_s.in?(ADMIN_ROLES)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Event
4
+ module API
5
+ module V2
6
+ module Admin
7
+ class EventsController < BaseController
8
+ # GET /admin/events
9
+ def index
10
+ ransack_params = {
11
+ state_in: params[:state],
12
+ currency_id_eq: params[:currency_id],
13
+ name_cont_all: params[:name]
14
+ }
15
+
16
+ sales = Event.ransack(ransack_params)
17
+ json_response(paginate(sales.result), 200)
18
+ end
19
+
20
+ # GET /admin/events/:id
21
+ def show
22
+ json_response(Event.find(params[:id]), 200)
23
+ end
24
+
25
+ # POST /admin/events
26
+ def create
27
+ event = nil
28
+ ActiveRecord::Base.transaction do
29
+ event =Event.create!(events_params)
30
+ end
31
+
32
+ json_response(event, 201)
33
+ end
34
+
35
+ # GET admin/events/history
36
+ def history
37
+ event = Event.find(params[:event_id])
38
+
39
+ json_response(event.participants, 201)
40
+ end
41
+
42
+ # PUT /admin/events/:id
43
+ def update
44
+ event = Event.find(params[:id])
45
+ event.update!(events_params)
46
+
47
+ json_response(event, 200)
48
+ end
49
+
50
+ private
51
+
52
+ def events_params
53
+ params.permit(:name, :description, :currency_id, :amount, :creator_uid, :state, :trigger_key, :trigger_value)
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,9 @@
1
+ module Event
2
+ class ApplicationController < ActionController::Base
3
+ include Response
4
+ include ExceptionHandlers
5
+ include Rails::Pagination
6
+
7
+ skip_before_action :verify_authenticity_token
8
+ end
9
+ end
@@ -0,0 +1,4 @@
1
+ module Event
2
+ module ApplicationHelper
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module Event
2
+ module EventHelper
3
+ end
4
+ end
@@ -0,0 +1,26 @@
1
+ # encoding: UTF-8
2
+ # frozen_string_literal: true
3
+
4
+ module Currency
5
+ extend ActiveSupport::Concern
6
+
7
+ TOKENS_AMOUNT_PRECISION = 4
8
+ RATIO_PRECISION = 4
9
+ COMMISSION_PRECISION = 6
10
+
11
+ LIABILITY_CODES = {
12
+ fiat: { main: 201, locked: 211 },
13
+ coin: { main: 202, locked: 212 }
14
+ }
15
+
16
+ REVENUE_CODES = {
17
+ fiat: { main: 301 },
18
+ coin: { main: 302 }
19
+ }
20
+
21
+ def fetch_currency(code)
22
+ Rails.cache.fetch("currency_#{code}", expires_in: 1.day) do
23
+ Peatio::ManagementAPIV2::Client.new.currency(code: code)
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,5 @@
1
+ module Event
2
+ class ApplicationRecord < ActiveRecord::Base
3
+ self.abstract_class = true
4
+ end
5
+ end
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'enumerize'
4
+
5
+ module Event
6
+ class Event < ApplicationRecord
7
+ self.table_name = 'events'
8
+
9
+ # == Constants ============================================================
10
+
11
+ extend Enumerize
12
+ STATE = {active: 100, disabled: -100}
13
+
14
+ # == Attributes ===========================================================
15
+
16
+ enumerize :state, in: STATE, scope: true
17
+
18
+ # == Extensions ===========================================================
19
+
20
+ # == Relationships ========================================================
21
+
22
+ has_many :participants
23
+
24
+ # == Validations ==========================================================
25
+
26
+ validates :name, :amount, :creator_uid, :state, :trigger_key,
27
+ :trigger_value, :currency_id, presence: {
28
+ message: ->(_, _data) { "missing_" }
29
+ }
30
+
31
+ validates :amount,
32
+ numericality: {
33
+ greater_than: 0,
34
+ message: ->(_, _data) { "non_positive_" }
35
+ }
36
+
37
+ validate :creator_validate?
38
+
39
+ # == Scopes ===============================================================
40
+
41
+ # == Callbacks ============================================================
42
+
43
+ before_validation(on: :create) do
44
+ self.currency_id = currency_id.try(:downcase)
45
+ self.state ||= 'active'
46
+ end
47
+
48
+ # == Class Methods ========================================================
49
+
50
+ # == Instance Methods =====================================================
51
+
52
+ def creator_validate?
53
+ begin
54
+ if Peatio::ManagementAPIV2::Client.new.balance(
55
+ uid: creator_uid,
56
+ currency: currency_id)[:balance].to_d <= 0
57
+ errors.add(:creator_uid, 'creator_uid_insufficient_balance')
58
+ end
59
+
60
+ rescue ManagementAPIV2::Exception
61
+ errors.add(:creator_uid, 'creator_uid_balance_checking_failed')
62
+ end
63
+ end
64
+ end
65
+ end
66
+
67
+ # == Schema Information
68
+ #
69
+ # Table name: events
70
+ #
71
+ # id :bigint not null, primary key
72
+ # amount :decimal(10, ) not null
73
+ # creator_uid :string(255) not null
74
+ # description :string(255)
75
+ # name :string(255) not null
76
+ # state :integer not null
77
+ # trigger_key :string(255) not null
78
+ # trigger_value :string(255) not null
79
+ # created_at :datetime not null
80
+ # updated_at :datetime not null
81
+ # currency_id :string(255) not null
82
+ #
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Event
4
+ class Participant < ApplicationRecord
5
+
6
+ include Currency
7
+
8
+ # == Constants ============================================================
9
+
10
+ # == Attributes ===========================================================
11
+
12
+ # == Extensions ===========================================================
13
+
14
+ serialize :transfer_keys, Array
15
+
16
+ # == Relationships ========================================================
17
+
18
+ belongs_to :event
19
+
20
+ # == Validations ==========================================================
21
+
22
+ # == Scopes ===============================================================
23
+
24
+ # == Callbacks ============================================================
25
+
26
+ after_create :transfer_amount
27
+
28
+ # == Class Methods ========================================================
29
+
30
+ # == Instance Methods =====================================================
31
+
32
+ def transfer_amount
33
+ perform_transfer(transfer_params)
34
+ save!
35
+ end
36
+
37
+ def transfer_params
38
+ currency = fetch_currency(event.currency_id)
39
+ .fetch(:type)
40
+ .to_sym
41
+
42
+ operations =
43
+ [
44
+ { # Debit owner main liabilities & credit user main liabilities with base currency.
45
+ currency: event.currency_id,
46
+ amount: event.amount,
47
+ account_src: {code: Currency::LIABILITY_CODES[currency][:main],
48
+ uid: event.creator_uid},
49
+ account_dst: {code: Currency::LIABILITY_CODES[currency][:main],
50
+ uid: uid}
51
+ }
52
+ ]
53
+
54
+ {
55
+ key: "event-#{self.id}",
56
+ category: :purchases,
57
+ description: "Event deposit participant prize #{uid}",
58
+ operations: operations
59
+ }
60
+ end
61
+
62
+ def perform_transfer(transfer_params)
63
+ Peatio::ManagementAPIV2::Client.new.create_transfer(transfer_params)
64
+ transfer_keys << transfer_params[:key]
65
+ end
66
+ end
67
+ end
68
+
69
+ # == Schema Information
70
+ #
71
+ # Table name: event_participants
72
+ #
73
+ # id :bigint not null, primary key
74
+ # transfer_keys :string(1000)
75
+ # uid :string(255) not null
76
+ # created_at :datetime not null
77
+ # updated_at :datetime not null
78
+ # event_id :bigint not null
79
+ #
80
+ # Indexes
81
+ #
82
+ # index_event_participants_on_event_id (event_id)
83
+ #