auction_fun_core 0.8.5
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/.editorconfig +12 -0
- data/.env.development.template +7 -0
- data/.env.test.template +7 -0
- data/.rspec +3 -0
- data/.standard.yml +3 -0
- data/.tool-versions +5 -0
- data/CHANGELOG.md +145 -0
- data/CODE_OF_CONDUCT.md +84 -0
- data/LICENSE.txt +21 -0
- data/Procfile +4 -0
- data/README.md +141 -0
- data/Rakefile +13 -0
- data/auction_fun_core.gemspec +57 -0
- data/config/app.rb +5 -0
- data/config/application.rb +37 -0
- data/config/boot.rb +15 -0
- data/db/migrate/20240216200926_enable_postgres_extensions.rb +13 -0
- data/db/migrate/20240217115734_create_users.rb +28 -0
- data/db/migrate/20240220140151_create_custom_types.rb +11 -0
- data/db/migrate/20240220140254_create_staffs.rb +20 -0
- data/db/migrate/20240229142933_create_custom_types.rb +13 -0
- data/db/migrate/20240229143000_create_auctions.rb +29 -0
- data/db/migrate/20240304144422_create_bids.rb +19 -0
- data/db/seeds.rb +116 -0
- data/i18n/en-US/contracts/contracts.en-US.yml +72 -0
- data/i18n/en-US/mail/user_context/registration.en-US.yml +11 -0
- data/i18n/pt-BR/contracts/contracts.pt-BR.yml +72 -0
- data/i18n/pt-BR/mail/user_context/registration.pt-BR.yml +12 -0
- data/lib/auction_fun_core/business/configuration.rb +18 -0
- data/lib/auction_fun_core/business/token_generator.rb +17 -0
- data/lib/auction_fun_core/commands/auction_context/create_auction.rb +19 -0
- data/lib/auction_fun_core/commands/auction_context/delete_auction.rb +15 -0
- data/lib/auction_fun_core/commands/auction_context/update_auction.rb +18 -0
- data/lib/auction_fun_core/commands/bid_context/create_bid.rb +19 -0
- data/lib/auction_fun_core/commands/bid_context/delete_bid.rb +15 -0
- data/lib/auction_fun_core/commands/bid_context/update_bid.rb +18 -0
- data/lib/auction_fun_core/commands/staff_context/create_staff.rb +19 -0
- data/lib/auction_fun_core/commands/user_context/create_user.rb +19 -0
- data/lib/auction_fun_core/contracts/application_contract.rb +55 -0
- data/lib/auction_fun_core/contracts/auction_context/create_contract.rb +101 -0
- data/lib/auction_fun_core/contracts/auction_context/processor/finish_contract.rb +27 -0
- data/lib/auction_fun_core/contracts/auction_context/processor/pause_contract.rb +34 -0
- data/lib/auction_fun_core/contracts/auction_context/processor/start_contract.rb +46 -0
- data/lib/auction_fun_core/contracts/auction_context/processor/unpause_contract.rb +34 -0
- data/lib/auction_fun_core/contracts/bid_context/create_bid_closed_contract.rb +79 -0
- data/lib/auction_fun_core/contracts/bid_context/create_bid_penny_contract.rb +69 -0
- data/lib/auction_fun_core/contracts/bid_context/create_bid_standard_contract.rb +68 -0
- data/lib/auction_fun_core/contracts/staff_context/authentication_contract.rb +47 -0
- data/lib/auction_fun_core/contracts/staff_context/registration_contract.rb +52 -0
- data/lib/auction_fun_core/contracts/user_context/authentication_contract.rb +47 -0
- data/lib/auction_fun_core/contracts/user_context/email_confirmation_contract.rb +40 -0
- data/lib/auction_fun_core/contracts/user_context/phone_confirmation_contract.rb +40 -0
- data/lib/auction_fun_core/contracts/user_context/registration_contract.rb +63 -0
- data/lib/auction_fun_core/entities/auction.rb +17 -0
- data/lib/auction_fun_core/entities/bid.rb +10 -0
- data/lib/auction_fun_core/entities/staff.rb +21 -0
- data/lib/auction_fun_core/entities/user.rb +37 -0
- data/lib/auction_fun_core/events/app.rb +27 -0
- data/lib/auction_fun_core/events/listener.rb +89 -0
- data/lib/auction_fun_core/operations/auction_context/create_operation.rb +77 -0
- data/lib/auction_fun_core/operations/auction_context/processor/finish_operation.rb +61 -0
- data/lib/auction_fun_core/operations/auction_context/processor/pause_operation.rb +57 -0
- data/lib/auction_fun_core/operations/auction_context/processor/start_operation.rb +84 -0
- data/lib/auction_fun_core/operations/auction_context/processor/unpause_operation.rb +57 -0
- data/lib/auction_fun_core/operations/base.rb +11 -0
- data/lib/auction_fun_core/operations/bid_context/create_bid_closed_operation.rb +64 -0
- data/lib/auction_fun_core/operations/bid_context/create_bid_penny_operation.rb +64 -0
- data/lib/auction_fun_core/operations/bid_context/create_bid_standard_operation.rb +74 -0
- data/lib/auction_fun_core/operations/staff_context/authentication_operation.rb +52 -0
- data/lib/auction_fun_core/operations/staff_context/registration_operation.rb +76 -0
- data/lib/auction_fun_core/operations/user_context/authentication_operation.rb +52 -0
- data/lib/auction_fun_core/operations/user_context/email_confirmation_operation.rb +67 -0
- data/lib/auction_fun_core/operations/user_context/phone_confirmation_operation.rb +67 -0
- data/lib/auction_fun_core/operations/user_context/registration_operation.rb +105 -0
- data/lib/auction_fun_core/relations/auctions.rb +119 -0
- data/lib/auction_fun_core/relations/bids.rb +28 -0
- data/lib/auction_fun_core/relations/staffs.rb +27 -0
- data/lib/auction_fun_core/relations/users.rb +26 -0
- data/lib/auction_fun_core/repos/auction_context/auction_repository.rb +42 -0
- data/lib/auction_fun_core/repos/bid_context/bid_repository.rb +27 -0
- data/lib/auction_fun_core/repos/staff_context/staff_repository.rb +64 -0
- data/lib/auction_fun_core/repos/user_context/user_repository.rb +78 -0
- data/lib/auction_fun_core/services/mail/templates/layout.html.erb +72 -0
- data/lib/auction_fun_core/services/mail/templates/user_context/registration.html.erb +170 -0
- data/lib/auction_fun_core/services/mail/user_context/registration_mailer.rb +25 -0
- data/lib/auction_fun_core/version.rb +8 -0
- data/lib/auction_fun_core/workers/application_job.rb +22 -0
- data/lib/auction_fun_core/workers/operations/auction_context/processor/finish_operation_job.rb +32 -0
- data/lib/auction_fun_core/workers/operations/auction_context/processor/start_operation_job.rb +32 -0
- data/lib/auction_fun_core/workers/services/mail/user_context/registration_mailer_job.rb +40 -0
- data/lib/auction_fun_core.rb +21 -0
- data/lib/tasks/database.rake +87 -0
- data/system/providers/background_job.rb +15 -0
- data/system/providers/core.rb +35 -0
- data/system/providers/db.rb +26 -0
- data/system/providers/events.rb +13 -0
- data/system/providers/logger.rb +11 -0
- data/system/providers/mail.rb +25 -0
- data/system/providers/persistence.rb +18 -0
- data/system/providers/settings.rb +26 -0
- metadata +400 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module AuctionFunCore
|
|
4
|
+
module Contracts
|
|
5
|
+
module UserContext
|
|
6
|
+
# Contract class responsible for validating the confirmation token for phone number.
|
|
7
|
+
class PhoneConfirmationContract < ApplicationContract
|
|
8
|
+
I18N_SCOPE = "contracts.errors.custom.default"
|
|
9
|
+
|
|
10
|
+
option :user_repository, default: proc { Repos::UserContext::UserRepository.new }
|
|
11
|
+
|
|
12
|
+
params do
|
|
13
|
+
required(:phone_confirmation_token)
|
|
14
|
+
|
|
15
|
+
before(:value_coercer) do |result|
|
|
16
|
+
result.to_h.compact
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Validation for token_confirmation_token.
|
|
21
|
+
# Searches for the user in the database from the phone_confirmation_token
|
|
22
|
+
rule do |context:|
|
|
23
|
+
next if schema_error?(:phone_confirmation_token)
|
|
24
|
+
|
|
25
|
+
context[:user] ||= user_repository.by_phone_confirmation_token(values[:phone_confirmation_token])
|
|
26
|
+
|
|
27
|
+
next if context[:user].present?
|
|
28
|
+
|
|
29
|
+
key(:phone_confirmation_token).failure(I18n.t("not_found", scope: I18N_SCOPE))
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
rule do |context:|
|
|
33
|
+
next if context[:user].blank? || context[:user].active?
|
|
34
|
+
|
|
35
|
+
key(:base).failure(I18n.t("inactive_account", scope: I18N_SCOPE))
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module AuctionFunCore
|
|
4
|
+
module Contracts
|
|
5
|
+
module UserContext
|
|
6
|
+
# Contract class to create new users.
|
|
7
|
+
class RegistrationContract < ApplicationContract
|
|
8
|
+
I18N_SCOPE = "contracts.errors.custom.default"
|
|
9
|
+
|
|
10
|
+
option :user_repository, default: proc { Repos::UserContext::UserRepository.new }
|
|
11
|
+
|
|
12
|
+
# @param [Hash] opts Sets an allowed list of parameters, as well as some initial validations.
|
|
13
|
+
params do
|
|
14
|
+
required(:name)
|
|
15
|
+
required(:email)
|
|
16
|
+
required(:phone)
|
|
17
|
+
required(:password)
|
|
18
|
+
required(:password_confirmation)
|
|
19
|
+
|
|
20
|
+
before(:value_coercer) do |result|
|
|
21
|
+
result.to_h.compact
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Normalize and add default values
|
|
25
|
+
after(:value_coercer) do |result|
|
|
26
|
+
result.update(email: result[:email].strip.downcase) if result[:email]
|
|
27
|
+
result.update(phone: result[:phone].tr_s("^0-9", "")) if result[:phone]
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
rule(:name).validate(:name_format)
|
|
32
|
+
|
|
33
|
+
# Validation for email.
|
|
34
|
+
# It must validate the format and uniqueness in the database.
|
|
35
|
+
rule(:email).validate(:email_format)
|
|
36
|
+
rule(:email) do
|
|
37
|
+
# Email should be unique on database
|
|
38
|
+
if !rule_error?(:email) && user_repository.exists?(email: value)
|
|
39
|
+
key.failure(I18n.t(:taken, scope: I18N_SCOPE))
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Validation for phone.
|
|
44
|
+
# It must validate the format and uniqueness in the database.
|
|
45
|
+
rule(:phone).validate(:phone_format)
|
|
46
|
+
rule(:phone) do
|
|
47
|
+
if !rule_error?(:phone) && user_repository.exists?(phone: value)
|
|
48
|
+
key.failure(I18n.t(:taken, scope: I18N_SCOPE))
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Validation for password.
|
|
53
|
+
# Check if the confirmation matches the password.
|
|
54
|
+
rule(:password).validate(:password_format)
|
|
55
|
+
rule(:password, :password_confirmation) do
|
|
56
|
+
if !rule_error?(:password) && values[:password] != values[:password_confirmation]
|
|
57
|
+
key(:password_confirmation).failure(I18n.t(:password_confirmation, scope: I18N_SCOPE))
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module AuctionFunCore
|
|
4
|
+
module Entities
|
|
5
|
+
# Auction Relations class. This return simple objects with attribute readers
|
|
6
|
+
# to represent data in your auction.
|
|
7
|
+
class Auction < ROM::Struct
|
|
8
|
+
def initial_bid
|
|
9
|
+
Money.new(initial_bid_cents, initial_bid_currency)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def minimal_bid
|
|
13
|
+
Money.new(minimal_bid_cents, minimal_bid_currency)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module AuctionFunCore
|
|
4
|
+
module Entities
|
|
5
|
+
# Staff Relations class. This return simple objects with attribute readers
|
|
6
|
+
# to represent data in your staff.
|
|
7
|
+
class Staff < ROM::Struct
|
|
8
|
+
def active?
|
|
9
|
+
active
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def inactive?
|
|
13
|
+
!active
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def info
|
|
17
|
+
attributes.except(:password_digest)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module AuctionFunCore
|
|
4
|
+
module Entities
|
|
5
|
+
# User Relations class. This return simple objects with attribute readers
|
|
6
|
+
# to represent data in your user.
|
|
7
|
+
class User < ROM::Struct
|
|
8
|
+
def active?
|
|
9
|
+
active
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def inactive?
|
|
13
|
+
!active
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def confirmed?
|
|
17
|
+
confirmed_at.present?
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def email_confirmed?
|
|
21
|
+
email_confirmation_at.present?
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def phone_confirmed?
|
|
25
|
+
phone_confirmation_at.present?
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def info
|
|
29
|
+
attributes.except(:password_digest)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def balance
|
|
33
|
+
Money.new(balance_cents, balance_currency)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module AuctionFunCore
|
|
4
|
+
module Events
|
|
5
|
+
# Event class to register business events on system.
|
|
6
|
+
# @see https://dry-rb.org/gems/dry-events/main/
|
|
7
|
+
class App
|
|
8
|
+
# @!parser include Dry::Events::Publisher[:app]
|
|
9
|
+
include Dry::Events::Publisher[:app]
|
|
10
|
+
|
|
11
|
+
register_event("auctions.created")
|
|
12
|
+
register_event("auctions.started")
|
|
13
|
+
register_event("auctions.finished")
|
|
14
|
+
register_event("auctions.paused")
|
|
15
|
+
register_event("auctions.unpaused")
|
|
16
|
+
|
|
17
|
+
register_event("bids.created")
|
|
18
|
+
|
|
19
|
+
register_event("staffs.authentication")
|
|
20
|
+
register_event("staffs.registration")
|
|
21
|
+
|
|
22
|
+
register_event("users.authentication")
|
|
23
|
+
register_event("users.registration")
|
|
24
|
+
register_event("users.confirmation")
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module AuctionFunCore
|
|
4
|
+
module Events
|
|
5
|
+
# Event class that can listen business events.
|
|
6
|
+
# @see https://dry-rb.org/gems/dry-events/main/#event-listeners
|
|
7
|
+
class Listener
|
|
8
|
+
# Listener for to *auctions.created* event.
|
|
9
|
+
# @param auction [ROM::Struct::Auction] the auction object
|
|
10
|
+
def on_auctions_created(auction)
|
|
11
|
+
logger("Create auction with: #{auction.to_h}")
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Listener for to *auctions.started* event.
|
|
15
|
+
# @param auction [ROM::Struct::Auction] the auction object
|
|
16
|
+
def on_auctions_started(auction)
|
|
17
|
+
logger("Started auction with: #{auction.to_h}")
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Listener for to *auctions.finished* event.
|
|
21
|
+
# @param auction [ROM::Struct::Auction] the auction object
|
|
22
|
+
def on_auctions_finished(auction)
|
|
23
|
+
logger("Finished auction: #{auction.to_h}")
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Listener for to *auctions.paused* event.
|
|
27
|
+
# @param event [ROM::Struct::Auction] the auction object
|
|
28
|
+
def on_auctions_paused(auction)
|
|
29
|
+
logger("Paused auction with: #{auction.to_h}")
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Listener for to *auctions.unpaused* event.
|
|
33
|
+
# @param event [ROM::Struct::Auction] the auction object
|
|
34
|
+
def on_auctions_unpaused(auction)
|
|
35
|
+
logger("Unpaused auction with: #{auction.to_h}")
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Listener for to *bids.created* event.
|
|
39
|
+
# @param event [Integer] Auction ID
|
|
40
|
+
def on_bids_created(bid)
|
|
41
|
+
logger("Create bid with: #{bid.to_h}")
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Listener for to *staffs.authentication* event.
|
|
45
|
+
# @param attributes [Hash] Authentication attributes
|
|
46
|
+
# @option staff_id [Integer] Staff ID
|
|
47
|
+
# @option time [DateTime] Authentication time
|
|
48
|
+
def on_staffs_authentication(attributes)
|
|
49
|
+
logger("Staff #{attributes[:staff_id]} authenticated on: #{attributes[:time].iso8601}")
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Listener for to *staffs.registration* event.
|
|
53
|
+
# @param user [ROM::Struct::Staff] the staff object
|
|
54
|
+
def on_staffs_registration(staff)
|
|
55
|
+
logger("New registered staff: #{staff.to_h}")
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Listener for to *users.registration* event.
|
|
59
|
+
# @param user [ROM::Struct::User] the user object
|
|
60
|
+
def on_users_registration(user)
|
|
61
|
+
logger("New registered user: #{user.to_h}")
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# Listener for to *users.authentication* event.
|
|
65
|
+
# @param attributes [Hash] Authentication attributes
|
|
66
|
+
# @option user_id [Integer] User ID
|
|
67
|
+
# @option time [DateTime] Authentication time
|
|
68
|
+
def on_users_authentication(attributes)
|
|
69
|
+
logger("User #{attributes[:user_id]} authenticated on: #{attributes[:time].iso8601}")
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Listener for to *users.confirmation* event.
|
|
73
|
+
# @param attributes [Hash] Confirmation attributes
|
|
74
|
+
# @option user_id [Integer] User ID
|
|
75
|
+
# @option time [DateTime] Authentication time
|
|
76
|
+
def on_users_confirmation(attributes)
|
|
77
|
+
logger("User #{attributes[:user_id]} confirmed at: #{attributes[:time].iso8601}")
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
private
|
|
81
|
+
|
|
82
|
+
# Append message to system log.
|
|
83
|
+
# @param message [String] the message
|
|
84
|
+
def logger(message)
|
|
85
|
+
Application[:logger].info(message)
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module AuctionFunCore
|
|
4
|
+
module Operations
|
|
5
|
+
module AuctionContext
|
|
6
|
+
##
|
|
7
|
+
# Operation class for creating auctions.
|
|
8
|
+
#
|
|
9
|
+
class CreateOperation < AuctionFunCore::Operations::Base
|
|
10
|
+
include Import["repos.auction_context.auction_repository"]
|
|
11
|
+
include Import["contracts.auction_context.create_contract"]
|
|
12
|
+
include Import["workers.operations.auction_context.processor.start_operation_job"]
|
|
13
|
+
|
|
14
|
+
# @todo Add custom doc
|
|
15
|
+
def self.call(attributes, &block)
|
|
16
|
+
operation = new.call(attributes)
|
|
17
|
+
|
|
18
|
+
return operation unless block
|
|
19
|
+
|
|
20
|
+
Dry::Matcher::ResultMatcher.call(operation, &block)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def call(attributes)
|
|
24
|
+
values = yield validate(attributes)
|
|
25
|
+
|
|
26
|
+
auction_repository.transaction do |_t|
|
|
27
|
+
@auction = yield persist(values)
|
|
28
|
+
yield scheduled_start_auction(@auction)
|
|
29
|
+
yield publish_auctions_created(@auction)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
Success(@auction)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
private
|
|
36
|
+
|
|
37
|
+
# Calls the auction creation contract class to perform the validation
|
|
38
|
+
# of the informed attributes.
|
|
39
|
+
# @param attrs [Hash] auction attributes
|
|
40
|
+
# @return [Dry::Monads::Result::Success, Dry::Monads::Result::Failure]
|
|
41
|
+
def validate(attrs)
|
|
42
|
+
contract = create_contract.call(attrs)
|
|
43
|
+
|
|
44
|
+
return Failure(contract.errors.to_h) if contract.failure?
|
|
45
|
+
|
|
46
|
+
Success(contract.to_h)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Calls the auction repository class to persist the attributes in the database.
|
|
50
|
+
# @param result [Hash] Auction validated attributes
|
|
51
|
+
# @return [ROM::Struct::Auction]
|
|
52
|
+
def persist(result)
|
|
53
|
+
Success(auction_repository.create(result))
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Triggers the publication of event *auctions.created*.
|
|
57
|
+
# @param auction [Hash] Auction persisted attributes
|
|
58
|
+
# @return [Dry::Monads::Result::Success]
|
|
59
|
+
def publish_auctions_created(auction)
|
|
60
|
+
Application[:event].publish("auctions.created", auction.to_h)
|
|
61
|
+
|
|
62
|
+
Success()
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Calls the background job class that will schedule the start of the auction.
|
|
66
|
+
# Added a small delay to perform operations (such as sending broadcasts and/or other operations).
|
|
67
|
+
# @param auction [ROM::Struct::Auction]
|
|
68
|
+
# @return [String] sidekiq jid
|
|
69
|
+
def scheduled_start_auction(auction)
|
|
70
|
+
perform_at = auction.started_at
|
|
71
|
+
|
|
72
|
+
Success(start_operation_job.class.perform_at(perform_at, auction.id))
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module AuctionFunCore
|
|
4
|
+
module Operations
|
|
5
|
+
module AuctionContext
|
|
6
|
+
module Processor
|
|
7
|
+
##
|
|
8
|
+
# Operation class for dispatch finish auction.
|
|
9
|
+
# By default, this change auction status from 'running' to 'finished'.
|
|
10
|
+
#
|
|
11
|
+
class FinishOperation < AuctionFunCore::Operations::Base
|
|
12
|
+
include Import["repos.auction_context.auction_repository"]
|
|
13
|
+
include Import["contracts.auction_context.processor.finish_contract"]
|
|
14
|
+
|
|
15
|
+
# @todo Add custom doc
|
|
16
|
+
def self.call(auction_id, &block)
|
|
17
|
+
operation = new.call(auction_id)
|
|
18
|
+
|
|
19
|
+
return operation unless block
|
|
20
|
+
|
|
21
|
+
Dry::Matcher::ResultMatcher.call(operation, &block)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# It only performs the basic processing of completing an auction.
|
|
25
|
+
# It just changes the status at the database level and triggers the finished event.
|
|
26
|
+
# @param auction_id [Integer] Auction ID
|
|
27
|
+
# @return [Dry::Monads::Result::Success, Dry::Monads::Result::Failure]
|
|
28
|
+
def call(auction_id)
|
|
29
|
+
yield validate(auction_id: auction_id)
|
|
30
|
+
|
|
31
|
+
auction_repository.transaction do |_t|
|
|
32
|
+
@auction, _ = auction_repository.update(auction_id, status: "finished")
|
|
33
|
+
|
|
34
|
+
publish_auction_finish_event(@auction)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
Success(@auction)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
private
|
|
41
|
+
|
|
42
|
+
# Calls the finish contract class to perform the validation
|
|
43
|
+
# of the informed attributes.
|
|
44
|
+
# @param attributes [Hash] auction attributes
|
|
45
|
+
# @return [Dry::Monads::Result::Success, Dry::Monads::Result::Failure]
|
|
46
|
+
def validate(attributes)
|
|
47
|
+
contract = finish_contract.call(attributes)
|
|
48
|
+
|
|
49
|
+
return Failure(contract.errors.to_h) if contract.failure?
|
|
50
|
+
|
|
51
|
+
Success(contract.to_h)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def publish_auction_finish_event(auction)
|
|
55
|
+
Application[:event].publish("auctions.finished", auction.to_h)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module AuctionFunCore
|
|
4
|
+
module Operations
|
|
5
|
+
module AuctionContext
|
|
6
|
+
module Processor
|
|
7
|
+
##
|
|
8
|
+
# Operation class for dispatch pause auction.
|
|
9
|
+
# By default, this change auction status from 'running' to 'paused'.
|
|
10
|
+
#
|
|
11
|
+
class PauseOperation < AuctionFunCore::Operations::Base
|
|
12
|
+
include Import["repos.auction_context.auction_repository"]
|
|
13
|
+
include Import["contracts.auction_context.processor.pause_contract"]
|
|
14
|
+
|
|
15
|
+
# @todo Add custom doc
|
|
16
|
+
def self.call(attributes, &block)
|
|
17
|
+
operation = new.call(attributes)
|
|
18
|
+
|
|
19
|
+
return operation unless block
|
|
20
|
+
|
|
21
|
+
Dry::Matcher::ResultMatcher.call(operation, &block)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def call(attributes)
|
|
25
|
+
attrs = yield validate(attributes)
|
|
26
|
+
|
|
27
|
+
auction_repository.transaction do |_t|
|
|
28
|
+
@auction, _ = auction_repository.update(attrs[:auction_id], status: "paused")
|
|
29
|
+
|
|
30
|
+
publish_auction_pause_event(@auction)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
Success(attrs[:auction_id])
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
private
|
|
37
|
+
|
|
38
|
+
# Calls the finish contract class to perform the validation
|
|
39
|
+
# of the informed attributes.
|
|
40
|
+
# @param attrs [Hash] auction attributes
|
|
41
|
+
# @return [Dry::Monads::Result::Success, Dry::Monads::Result::Failure]
|
|
42
|
+
def validate(attributes)
|
|
43
|
+
contract = pause_contract.call(attributes)
|
|
44
|
+
|
|
45
|
+
return Failure(contract.errors.to_h) if contract.failure?
|
|
46
|
+
|
|
47
|
+
Success(contract.to_h)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def publish_auction_pause_event(auction)
|
|
51
|
+
Application[:event].publish("auctions.paused", auction.to_h)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module AuctionFunCore
|
|
4
|
+
module Operations
|
|
5
|
+
module AuctionContext
|
|
6
|
+
module Processor
|
|
7
|
+
##
|
|
8
|
+
# Operation class for dispatch start auction.
|
|
9
|
+
# By default, this change auction status from 'scheduled' to 'running'
|
|
10
|
+
# and schedule a job to execute the auction finalization when auction is not penny.
|
|
11
|
+
class StartOperation < AuctionFunCore::Operations::Base
|
|
12
|
+
include Import["repos.auction_context.auction_repository"]
|
|
13
|
+
include Import["contracts.auction_context.processor.start_contract"]
|
|
14
|
+
include Import["workers.operations.auction_context.processor.finish_operation_job"]
|
|
15
|
+
|
|
16
|
+
# @todo Add custom doc
|
|
17
|
+
def self.call(attributes, &block)
|
|
18
|
+
operation = new.call(attributes)
|
|
19
|
+
|
|
20
|
+
return operation unless block
|
|
21
|
+
|
|
22
|
+
Dry::Matcher::ResultMatcher.call(operation, &block)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# @param [Hash] attributes needed to start a auction
|
|
26
|
+
# @option opts [String] :auction_id auction id
|
|
27
|
+
# @option opts [String] :auction_kind auction kind
|
|
28
|
+
# @option opts [Integer] :stopwatch auction stopwatch
|
|
29
|
+
# @return [ROM::Struct::Auction] auction object
|
|
30
|
+
def call(attributes)
|
|
31
|
+
attrs = yield validate(attributes)
|
|
32
|
+
|
|
33
|
+
auction_repository.transaction do |_t|
|
|
34
|
+
@auction, _ = auction_repository.update(attrs[:auction_id], update_params(attrs))
|
|
35
|
+
|
|
36
|
+
yield publish_auction_start_event(@auction)
|
|
37
|
+
yield scheduled_finished_auction(@auction)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
Success(@auction)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
private
|
|
44
|
+
|
|
45
|
+
# Calls the start contract class to perform the validation
|
|
46
|
+
# of the informed attributes.
|
|
47
|
+
# @param attributes [Hash] auction attributes
|
|
48
|
+
# @return [Dry::Monads::Result::Success, Dry::Monads::Result::Failure]
|
|
49
|
+
def validate(attributes)
|
|
50
|
+
contract = start_contract.call(attributes)
|
|
51
|
+
|
|
52
|
+
return Failure(contract.errors.to_h) if contract.failure?
|
|
53
|
+
|
|
54
|
+
Success(contract.to_h)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Updates the status of the auction and depending on the type of auction,
|
|
58
|
+
# it already sets the final date.
|
|
59
|
+
# @param attrs [Hash] auction attributes
|
|
60
|
+
# @return [Hash]
|
|
61
|
+
def update_params(attrs)
|
|
62
|
+
return {status: "running"} unless attrs[:kind] == "penny"
|
|
63
|
+
|
|
64
|
+
{status: "running", finished_at: attrs[:stopwatch].seconds.from_now}
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def publish_auction_start_event(auction)
|
|
68
|
+
Success(Application[:event].publish("auctions.started", auction.to_h))
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Calls the background job class that will schedule the finish of the auction.
|
|
72
|
+
# Added a small delay to perform operations (such as sending broadcasts and/or other operations).
|
|
73
|
+
# @param auction [ROM::Struct::Auction]
|
|
74
|
+
# @return [String] sidekiq jid
|
|
75
|
+
def scheduled_finished_auction(auction)
|
|
76
|
+
return Success() if auction.kind == "penny"
|
|
77
|
+
|
|
78
|
+
Success(finish_operation_job.class.perform_at(auction.finished_at, auction.id))
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module AuctionFunCore
|
|
4
|
+
module Operations
|
|
5
|
+
module AuctionContext
|
|
6
|
+
module Processor
|
|
7
|
+
##
|
|
8
|
+
# Operation class for dispatch unpause auction.
|
|
9
|
+
# By default, this change auction status from 'paused' to 'running'.
|
|
10
|
+
#
|
|
11
|
+
class UnpauseOperation < AuctionFunCore::Operations::Base
|
|
12
|
+
include Import["repos.auction_context.auction_repository"]
|
|
13
|
+
include Import["contracts.auction_context.processor.unpause_contract"]
|
|
14
|
+
|
|
15
|
+
# @todo Add custom doc
|
|
16
|
+
def self.call(attributes, &block)
|
|
17
|
+
operation = new.call(attributes)
|
|
18
|
+
|
|
19
|
+
return operation unless block
|
|
20
|
+
|
|
21
|
+
Dry::Matcher::ResultMatcher.call(operation, &block)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def call(attributes)
|
|
25
|
+
attrs = yield validate(attributes)
|
|
26
|
+
|
|
27
|
+
auction_repository.transaction do |_t|
|
|
28
|
+
@auction, _ = auction_repository.update(attrs[:auction_id], status: "running")
|
|
29
|
+
|
|
30
|
+
publish_auction_unpause_event(@auction)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
Success(attrs[:auction_id])
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
private
|
|
37
|
+
|
|
38
|
+
# Calls the unpause contract class to perform the validation
|
|
39
|
+
# of the informed attributes.
|
|
40
|
+
# @param attrs [Hash] auction attributes
|
|
41
|
+
# @return [Dry::Monads::Result::Success, Dry::Monads::Result::Failure]
|
|
42
|
+
def validate(attributes)
|
|
43
|
+
contract = unpause_contract.call(attributes)
|
|
44
|
+
|
|
45
|
+
return Failure(contract.errors.to_h) if contract.failure?
|
|
46
|
+
|
|
47
|
+
Success(contract.to_h)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def publish_auction_unpause_event(auction)
|
|
51
|
+
Application[:event].publish("auctions.unpaused", auction.to_h)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|