eventush 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
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,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,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
|
+
#
|