auction_fun_core 0.8.7 → 0.8.9
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 +4 -4
- data/.standard.yml +2 -0
- data/CHANGELOG.md +23 -0
- data/Procfile +1 -0
- data/README.md +34 -32
- data/Rakefile +1 -1
- data/i18n/en-US/contracts/contracts.en-US.yml +3 -0
- data/i18n/en-US/mail/application.en-US.yml +7 -0
- data/i18n/en-US/mail/auction_context/pre_auction/auction_start_reminder.en-US.yml +11 -0
- data/i18n/pt-BR/contracts/contracts.pt-BR.yml +3 -0
- data/i18n/pt-BR/mail/application.pt-BR.yml +7 -0
- data/i18n/pt-BR/mail/auction_context/pre_auction/auction_start_reminder.pt-BR.yml +11 -0
- data/lib/auction_fun_core/business/configuration.rb +31 -0
- data/lib/auction_fun_core/business/token_generator.rb +19 -1
- data/lib/auction_fun_core/contracts/application_contract.rb +9 -1
- data/lib/auction_fun_core/contracts/auction_context/create_contract.rb +35 -20
- data/lib/auction_fun_core/contracts/auction_context/post_auction/participant_contract.rb +23 -1
- data/lib/auction_fun_core/contracts/auction_context/post_auction/winner_contract.rb +22 -1
- data/lib/auction_fun_core/contracts/auction_context/pre_auction/auction_start_reminder_contract.rb +48 -0
- data/lib/auction_fun_core/contracts/auction_context/processor/finish/closed_contract.rb +19 -7
- data/lib/auction_fun_core/contracts/auction_context/processor/finish/penny_contract.rb +19 -7
- data/lib/auction_fun_core/contracts/auction_context/processor/finish/standard_contract.rb +19 -7
- data/lib/auction_fun_core/contracts/auction_context/processor/pause_contract.rb +16 -4
- data/lib/auction_fun_core/contracts/auction_context/processor/start_contract.rb +17 -5
- data/lib/auction_fun_core/contracts/auction_context/processor/unpause_contract.rb +16 -4
- data/lib/auction_fun_core/contracts/bid_context/create_bid_closed_contract.rb +20 -11
- data/lib/auction_fun_core/contracts/bid_context/create_bid_penny_contract.rb +18 -9
- data/lib/auction_fun_core/contracts/bid_context/create_bid_standard_contract.rb +19 -10
- data/lib/auction_fun_core/contracts/staff_context/authentication_contract.rb +18 -4
- data/lib/auction_fun_core/contracts/staff_context/registration_contract.rb +20 -8
- data/lib/auction_fun_core/contracts/user_context/authentication_contract.rb +18 -4
- data/lib/auction_fun_core/contracts/user_context/email_confirmation_contract.rb +17 -2
- data/lib/auction_fun_core/contracts/user_context/phone_confirmation_contract.rb +17 -2
- data/lib/auction_fun_core/contracts/user_context/registration_contract.rb +26 -8
- data/lib/auction_fun_core/entities/auction.rb +48 -4
- data/lib/auction_fun_core/entities/bid.rb +3 -2
- data/lib/auction_fun_core/entities/staff.rb +15 -2
- data/lib/auction_fun_core/entities/user.rb +31 -2
- data/lib/auction_fun_core/events/app.rb +8 -2
- data/lib/auction_fun_core/events/listener.rb +19 -16
- data/lib/auction_fun_core/operations/auction_context/create_operation.rb +25 -9
- data/lib/auction_fun_core/operations/auction_context/post_auction/participant_operation.rb +36 -3
- data/lib/auction_fun_core/operations/auction_context/post_auction/winner_operation.rb +36 -2
- data/lib/auction_fun_core/operations/auction_context/pre_auction/auction_start_reminder_operation.rb +96 -0
- data/lib/auction_fun_core/operations/auction_context/processor/finish/closed_operation.rb +82 -10
- data/lib/auction_fun_core/operations/auction_context/processor/finish/penny_operation.rb +81 -10
- data/lib/auction_fun_core/operations/auction_context/processor/finish/standard_operation.rb +81 -12
- data/lib/auction_fun_core/operations/auction_context/processor/pause_operation.rb +36 -1
- data/lib/auction_fun_core/operations/auction_context/processor/unpause_operation.rb +36 -1
- data/lib/auction_fun_core/relations/auctions.rb +178 -97
- data/lib/auction_fun_core/relations/bids.rb +18 -0
- data/lib/auction_fun_core/repos/auction_context/auction_repository.rb +40 -11
- data/lib/auction_fun_core/repos/bid_context/bid_repository.rb +27 -5
- data/lib/auction_fun_core/repos/staff_context/staff_repository.rb +63 -21
- data/lib/auction_fun_core/repos/user_context/user_repository.rb +69 -25
- data/lib/auction_fun_core/services/mail/auction_context/post_auction/participant_mailer.rb +7 -1
- data/lib/auction_fun_core/services/mail/auction_context/post_auction/winner_mailer.rb +7 -1
- data/lib/auction_fun_core/services/mail/auction_context/pre_auction/auction_start_reminder_mailer.rb +35 -0
- data/lib/auction_fun_core/services/mail/templates/auction_context/post_auction/participant.html.erb +1 -1
- data/lib/auction_fun_core/services/mail/templates/auction_context/post_auction/winner.html.erb +1 -1
- data/lib/auction_fun_core/services/mail/templates/auction_context/pre_auction/auction_start_reminder.html.erb +192 -0
- data/lib/auction_fun_core/services/mail/user_context/registration_mailer.rb +6 -0
- data/lib/auction_fun_core/version.rb +1 -1
- data/lib/auction_fun_core/workers/application_job.rb +10 -0
- data/lib/auction_fun_core/workers/operations/auction_context/post_auction/participant_operation_job.rb +7 -2
- data/lib/auction_fun_core/workers/operations/auction_context/post_auction/winner_operation_job.rb +6 -2
- data/lib/auction_fun_core/workers/operations/auction_context/pre_auction/auction_start_reminder_operation_job.rb +44 -0
- data/lib/auction_fun_core/workers/operations/auction_context/processor/finish/closed_operation_job.rb +6 -3
- data/lib/auction_fun_core/workers/operations/auction_context/processor/finish/penny_operation_job.rb +6 -3
- data/lib/auction_fun_core/workers/operations/auction_context/processor/finish/standard_operation_job.rb +6 -2
- data/lib/auction_fun_core/workers/operations/auction_context/processor/start_operation_job.rb +6 -3
- data/lib/auction_fun_core/workers/services/mail/auction_context/post_auction/participant_mailer_job.rb +12 -7
- data/lib/auction_fun_core/workers/services/mail/auction_context/post_auction/winner_mailer_job.rb +11 -5
- data/lib/auction_fun_core/workers/services/mail/auction_context/pre_auction/auction_start_reminder_mailer_job.rb +48 -0
- data/lib/auction_fun_core/workers/services/mail/user_context/registration_mailer_job.rb +8 -6
- data/system/providers/background_job.rb +6 -0
- metadata +10 -2
data/lib/auction_fun_core/contracts/auction_context/pre_auction/auction_start_reminder_contract.rb
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module AuctionFunCore
|
|
4
|
+
module Contracts
|
|
5
|
+
module AuctionContext
|
|
6
|
+
module PreAuction
|
|
7
|
+
# The AuctionStartReminderContract class validates the scheduled reminder for the auction start.
|
|
8
|
+
# It checks if the auction associated with the provided auction ID has not started yet and validates accordingly.
|
|
9
|
+
#
|
|
10
|
+
# @example Validating auction reminder
|
|
11
|
+
# contract = AuctionFunCore::Contracts::AuctionContext::PreAuction::AuctionStartReminderContract.new
|
|
12
|
+
# attributes = { auction_id: 123 }
|
|
13
|
+
# result = contract.call(attributes)
|
|
14
|
+
# if result.success?
|
|
15
|
+
# puts "Reminder setup is valid."
|
|
16
|
+
# else
|
|
17
|
+
# puts "Failed to validate reminder: #{result.errors.to_h}"
|
|
18
|
+
# end
|
|
19
|
+
#
|
|
20
|
+
class AuctionStartReminderContract < Contracts::ApplicationContract
|
|
21
|
+
# Scope for internationalization (i18n) entries specific to errors in this contract.
|
|
22
|
+
I18N_SCOPE = "contracts.errors.custom.auction_context.pre_auction.auction_start_reminder"
|
|
23
|
+
|
|
24
|
+
# Default repository initialization to retrieve auction data.
|
|
25
|
+
option :auction_repository, default: proc { Repos::AuctionContext::AuctionRepository.new }
|
|
26
|
+
|
|
27
|
+
# Defines the necessary parameters and their types.
|
|
28
|
+
params do
|
|
29
|
+
required(:auction_id).filled(:integer)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Validation rule to ensure the referenced auction exists.
|
|
33
|
+
rule(:auction_id) do |context:|
|
|
34
|
+
context[:auction] ||= auction_repository.by_id(value)
|
|
35
|
+
key.failure(I18n.t("contracts.errors.custom.not_found")) unless context[:auction]
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Additional validation to confirm the auction has not started yet.
|
|
39
|
+
rule do |context:|
|
|
40
|
+
next if context[:auction].present? && context[:auction].not_started?
|
|
41
|
+
|
|
42
|
+
key(:base).failure(I18n.t("auction_already_started", scope: I18N_SCOPE))
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -6,34 +6,46 @@ module AuctionFunCore
|
|
|
6
6
|
module Processor
|
|
7
7
|
module Finish
|
|
8
8
|
##
|
|
9
|
-
#
|
|
9
|
+
# This class is designed for validate the finishing closed auctions. It ensures that
|
|
10
|
+
# the auction to be closed exists, is of the correct kind ('closed'), and is in the correct
|
|
11
|
+
# status ('running') to be finalized.
|
|
12
|
+
#
|
|
13
|
+
# @example Validating a closed auction
|
|
14
|
+
# contract = AuctionFunCore::Contracts::AuctionContext::Processor::Finish::ClosedContract.new
|
|
15
|
+
# attributes = { auction_id: 123 }
|
|
16
|
+
# result = contract.call(attributes)
|
|
17
|
+
# if result.success?
|
|
18
|
+
# puts "Auction can be finished."
|
|
19
|
+
# else
|
|
20
|
+
# puts "Failed to finish auction: #{result.errors.to_h}"
|
|
21
|
+
# end
|
|
10
22
|
#
|
|
11
23
|
class ClosedContract < Contracts::ApplicationContract
|
|
24
|
+
# Internationalization (i18n) scope for error messages.
|
|
12
25
|
I18N_SCOPE = "contracts.errors.custom.auction_context.processor.finish"
|
|
13
26
|
|
|
27
|
+
# Repository initialized to retrieve auction data for validation.
|
|
14
28
|
option :auction_repository, default: proc { Repos::AuctionContext::AuctionRepository.new }
|
|
15
29
|
|
|
30
|
+
# Parameters specifying the required input types and fields.
|
|
16
31
|
params do
|
|
17
32
|
required(:auction_id).filled(:integer)
|
|
18
33
|
end
|
|
19
34
|
|
|
20
|
-
#
|
|
21
|
-
# Validates if the auction exists in the database.
|
|
35
|
+
# Validates the existence of the auction.
|
|
22
36
|
rule(:auction_id) do |context:|
|
|
23
37
|
context[:auction] ||= auction_repository.by_id(value)
|
|
24
38
|
key.failure(I18n.t("contracts.errors.custom.not_found")) unless context[:auction]
|
|
25
39
|
end
|
|
26
40
|
|
|
27
|
-
#
|
|
28
|
-
#
|
|
41
|
+
# Validates the kind of the auction to ensure it is 'closed'.
|
|
29
42
|
rule do |context:|
|
|
30
43
|
next if context[:auction].present? && context[:auction].kind == "closed"
|
|
31
44
|
|
|
32
45
|
key(:base).failure(I18n.t("invalid_kind", scope: I18N_SCOPE))
|
|
33
46
|
end
|
|
34
47
|
|
|
35
|
-
#
|
|
36
|
-
#
|
|
48
|
+
# Validates the status of the auction to ensure it is 'running'.
|
|
37
49
|
rule do |context:|
|
|
38
50
|
next if context[:auction].present? && context[:auction].status == "running"
|
|
39
51
|
|
|
@@ -6,35 +6,47 @@ module AuctionFunCore
|
|
|
6
6
|
module Processor
|
|
7
7
|
module Finish
|
|
8
8
|
##
|
|
9
|
-
#
|
|
9
|
+
# This class is designed for validate the finishing penny auctions. It ensures that
|
|
10
|
+
# the auction to be penny exists, is of the correct kind ('penny'), and is in the correct
|
|
11
|
+
# status ('running') to be finalized.
|
|
12
|
+
#
|
|
13
|
+
# @example Validating a penny auction
|
|
14
|
+
# contract = AuctionFunCore::Contracts::AuctionContext::Processor::Finish::PennyContract.new
|
|
15
|
+
# attributes = { auction_id: 123 }
|
|
16
|
+
# result = contract.call(attributes)
|
|
17
|
+
# if result.success?
|
|
18
|
+
# puts "Auction can be finished."
|
|
19
|
+
# else
|
|
20
|
+
# puts "Failed to finish auction: #{result.errors.to_h}"
|
|
21
|
+
# end
|
|
10
22
|
#
|
|
11
23
|
class PennyContract < Contracts::ApplicationContract
|
|
24
|
+
# Internationalization (i18n) scope for error messages.
|
|
12
25
|
I18N_SCOPE = "contracts.errors.custom.auction_context.processor.finish"
|
|
13
26
|
|
|
27
|
+
# Repository initialized to retrieve auction data for validation.
|
|
14
28
|
option :auction_repository, default: proc { Repos::AuctionContext::AuctionRepository.new }
|
|
15
29
|
|
|
30
|
+
# Parameters specifying the required input types and fields.
|
|
16
31
|
params do
|
|
17
32
|
required(:auction_id).filled(:integer)
|
|
18
33
|
end
|
|
19
34
|
|
|
20
|
-
#
|
|
21
|
-
# Validates if the auction exists in the database.
|
|
35
|
+
# Validates the existence of the auction.
|
|
22
36
|
rule(:auction_id) do |context:|
|
|
23
37
|
context[:auction] ||= auction_repository.by_id(value)
|
|
24
38
|
|
|
25
39
|
key.failure(I18n.t("contracts.errors.custom.not_found")) unless context[:auction]
|
|
26
40
|
end
|
|
27
41
|
|
|
28
|
-
#
|
|
29
|
-
#
|
|
42
|
+
# Validates the kind of the auction to ensure it is 'penny'.
|
|
30
43
|
rule do |context:|
|
|
31
44
|
next if context[:auction].present? && context[:auction].kind == "penny"
|
|
32
45
|
|
|
33
46
|
key(:base).failure(I18n.t("invalid_kind", scope: I18N_SCOPE))
|
|
34
47
|
end
|
|
35
48
|
|
|
36
|
-
#
|
|
37
|
-
#
|
|
49
|
+
# Validates the status of the auction to ensure it is 'running'.
|
|
38
50
|
rule do |context:|
|
|
39
51
|
next if context[:auction].present? && context[:auction].status == "running"
|
|
40
52
|
|
|
@@ -6,35 +6,47 @@ module AuctionFunCore
|
|
|
6
6
|
module Processor
|
|
7
7
|
module Finish
|
|
8
8
|
##
|
|
9
|
-
#
|
|
9
|
+
# This class is designed for validate the finishing standard auctions. It ensures that
|
|
10
|
+
# the auction to be standard exists, is of the correct kind ('standard'), and is in the correct
|
|
11
|
+
# status ('running') to be finalized.
|
|
12
|
+
#
|
|
13
|
+
# @example Validating a standard auction
|
|
14
|
+
# contract = AuctionFunCore::Contracts::AuctionContext::Processor::Finish::StandardContract.new
|
|
15
|
+
# attributes = { auction_id: 123 }
|
|
16
|
+
# result = contract.call(attributes)
|
|
17
|
+
# if result.success?
|
|
18
|
+
# puts "Auction can be finished."
|
|
19
|
+
# else
|
|
20
|
+
# puts "Failed to finish auction: #{result.errors.to_h}"
|
|
21
|
+
# end
|
|
10
22
|
#
|
|
11
23
|
class StandardContract < Contracts::ApplicationContract
|
|
24
|
+
# Internationalization (i18n) scope for error messages.
|
|
12
25
|
I18N_SCOPE = "contracts.errors.custom.auction_context.processor.finish"
|
|
13
26
|
|
|
27
|
+
# Repository initialized to retrieve auction data for validation.
|
|
14
28
|
option :auction_repository, default: proc { Repos::AuctionContext::AuctionRepository.new }
|
|
15
29
|
|
|
30
|
+
# Parameters specifying the required input types and fields.
|
|
16
31
|
params do
|
|
17
32
|
required(:auction_id).filled(:integer)
|
|
18
33
|
end
|
|
19
34
|
|
|
20
|
-
#
|
|
21
|
-
# Validates if the auction exists in the database.
|
|
35
|
+
# Validates the existence of the auction.
|
|
22
36
|
rule(:auction_id) do |context:|
|
|
23
37
|
context[:auction] ||= auction_repository.by_id(value)
|
|
24
38
|
|
|
25
39
|
key.failure(I18n.t("contracts.errors.custom.not_found")) unless context[:auction]
|
|
26
40
|
end
|
|
27
41
|
|
|
28
|
-
#
|
|
29
|
-
#
|
|
42
|
+
# Validates the kind of the auction to ensure it is 'standard'.
|
|
30
43
|
rule do |context:|
|
|
31
44
|
next if context[:auction].present? && context[:auction].kind == "standard"
|
|
32
45
|
|
|
33
46
|
key(:base).failure(I18n.t("invalid_kind", scope: I18N_SCOPE))
|
|
34
47
|
end
|
|
35
48
|
|
|
36
|
-
#
|
|
37
|
-
#
|
|
49
|
+
# Validates the status of the auction to ensure it is 'running'.
|
|
38
50
|
rule do |context:|
|
|
39
51
|
next if context[:auction].present? && context[:auction].status == "running"
|
|
40
52
|
|
|
@@ -5,18 +5,30 @@ module AuctionFunCore
|
|
|
5
5
|
module AuctionContext
|
|
6
6
|
module Processor
|
|
7
7
|
##
|
|
8
|
-
#
|
|
8
|
+
# This class is designed to validate pausing an auction. It ensures
|
|
9
|
+
# that the auction exists in the database and checks that only auctions with
|
|
10
|
+
# a "running" status can be paused.
|
|
11
|
+
#
|
|
12
|
+
# @example Pausing an auction
|
|
13
|
+
# contract = AuctionFunCore::Contracts::AuctionContext::Processor::PauseContract.new
|
|
14
|
+
# attributes = { auction_id: 123 }
|
|
15
|
+
# result = contract.call(attributes)
|
|
16
|
+
# if result.success?
|
|
17
|
+
# puts "Auction paused successfully."
|
|
18
|
+
# else
|
|
19
|
+
# puts "Failed to pause auction: #{result.errors.to_h}"
|
|
20
|
+
# end
|
|
9
21
|
#
|
|
10
22
|
class PauseContract < Contracts::ApplicationContract
|
|
23
|
+
# Repository initialized to retrieve auction data for validation.
|
|
11
24
|
option :auction_repository, default: proc { Repos::AuctionContext::AuctionRepository.new }
|
|
12
25
|
|
|
26
|
+
# Parameters specifying the required input types and fields.
|
|
13
27
|
params do
|
|
14
28
|
required(:auction_id).filled(:integer)
|
|
15
29
|
end
|
|
16
30
|
|
|
17
|
-
#
|
|
18
|
-
# Validates if the auction exists in the database and check if only auctions
|
|
19
|
-
# with a "running" status can be paused.
|
|
31
|
+
# Validates the existence of the auction and its status.
|
|
20
32
|
rule(:auction_id) do |context:|
|
|
21
33
|
context[:auction] ||= auction_repository.by_id(value)
|
|
22
34
|
key.failure(I18n.t("contracts.errors.custom.not_found")) unless context[:auction]
|
|
@@ -5,28 +5,40 @@ module AuctionFunCore
|
|
|
5
5
|
module AuctionContext
|
|
6
6
|
module Processor
|
|
7
7
|
##
|
|
8
|
-
#
|
|
8
|
+
# This class is designed to validate the initiation of auctions. It ensures
|
|
9
|
+
# the auction exists and is of a valid kind, and also manages specific rules for auctions
|
|
10
|
+
# that require a stopwatch, such as penny auctions.
|
|
11
|
+
#
|
|
12
|
+
# @example Starting an auction
|
|
13
|
+
# contract = AuctionFunCore::Contracts::AuctionContext::Processor::StartContract.new
|
|
14
|
+
# attributes = { auction_id: 123, kind: "penny", stopwatch: 30 }
|
|
15
|
+
# result = contract.call(attributes)
|
|
16
|
+
# if result.success?
|
|
17
|
+
# puts "Auction started successfully."
|
|
18
|
+
# else
|
|
19
|
+
# puts "Failed to start auction: #{result.errors.to_h}"
|
|
20
|
+
# end
|
|
9
21
|
#
|
|
10
22
|
class StartContract < Contracts::ApplicationContract
|
|
11
23
|
include AuctionFunCore::Business::Configuration
|
|
12
24
|
|
|
25
|
+
# Repository initialized to retrieve auction data for validation.
|
|
13
26
|
option :auction_repo, default: proc { Repos::AuctionContext::AuctionRepository.new }
|
|
14
27
|
|
|
28
|
+
# Parameters specifying the required input types and fields.
|
|
15
29
|
params do
|
|
16
30
|
required(:auction_id).filled(:integer)
|
|
17
31
|
required(:kind).value(included_in?: AUCTION_KINDS)
|
|
18
32
|
optional(:stopwatch).filled(:integer)
|
|
19
33
|
end
|
|
20
34
|
|
|
21
|
-
#
|
|
22
|
-
# Validates if the auction exists in the database.
|
|
35
|
+
# Validates the existence of the auction.
|
|
23
36
|
rule(:auction_id) do |context:|
|
|
24
37
|
context[:auction] ||= auction_repo.by_id(value)
|
|
25
38
|
key.failure(I18n.t("contracts.errors.custom.not_found")) unless context[:auction]
|
|
26
39
|
end
|
|
27
40
|
|
|
28
|
-
#
|
|
29
|
-
#
|
|
41
|
+
# Validates the requirements for the stopwatch in penny auctions.
|
|
30
42
|
rule(:stopwatch) do
|
|
31
43
|
# Must be filled if auction kind is type penny.
|
|
32
44
|
key.failure(I18n.t("contracts.errors.filled?")) if !key? && values[:kind] == "penny"
|
|
@@ -5,18 +5,30 @@ module AuctionFunCore
|
|
|
5
5
|
module AuctionContext
|
|
6
6
|
module Processor
|
|
7
7
|
##
|
|
8
|
-
#
|
|
8
|
+
# This class is designed to validate the resumption of auctions.
|
|
9
|
+
# It ensures that the auction exists in the database and checks that the auction
|
|
10
|
+
# is currently in a "paused" status, allowing it to be unpaused.
|
|
11
|
+
#
|
|
12
|
+
# @example Unpausing an auction
|
|
13
|
+
# contract = AuctionFunCore::Contracts::AuctionContext::Processor::UnpauseContract.new
|
|
14
|
+
# attributes = { auction_id: 123 }
|
|
15
|
+
# result = contract.call(attributes)
|
|
16
|
+
# if result.success?
|
|
17
|
+
# puts "Auction resumed successfully."
|
|
18
|
+
# else
|
|
19
|
+
# puts "Failed to resume auction: #{result.errors.to_h}"
|
|
20
|
+
# end
|
|
9
21
|
#
|
|
10
22
|
class UnpauseContract < Contracts::ApplicationContract
|
|
23
|
+
# Repository initialized to retrieve auction data for validation.
|
|
11
24
|
option :auction_repository, default: proc { Repos::AuctionContext::AuctionRepository.new }
|
|
12
25
|
|
|
26
|
+
# Parameters specifying the required input types and fields.
|
|
13
27
|
params do
|
|
14
28
|
required(:auction_id).filled(:integer)
|
|
15
29
|
end
|
|
16
30
|
|
|
17
|
-
#
|
|
18
|
-
# Validates if the auction exists in the database and and checks if the
|
|
19
|
-
# auction has a paused status.
|
|
31
|
+
# Validates the existence of the auction and checks its status.
|
|
20
32
|
rule(:auction_id) do |context:|
|
|
21
33
|
context[:auction] ||= auction_repository.by_id(value)
|
|
22
34
|
key.failure(I18n.t("contracts.errors.custom.not_found")) unless context[:auction]
|
|
@@ -3,13 +3,27 @@
|
|
|
3
3
|
module AuctionFunCore
|
|
4
4
|
module Contracts
|
|
5
5
|
module BidContext
|
|
6
|
-
#
|
|
6
|
+
# This class validates the creation of new bids for closed-type auctions.
|
|
7
|
+
# It ensures the bid is placed by a valid user on a valid auction that is open for bids, and that
|
|
8
|
+
# the bid value meets or exceeds the starting bid required by the auction.
|
|
9
|
+
# Furthermore, only one bid per participant is allowed.
|
|
10
|
+
#
|
|
11
|
+
# @example Creating a bid for a closed auction
|
|
12
|
+
# contract = AuctionFunCore::Contracts::BidContext::CreateBidClosedContract.new
|
|
13
|
+
# attributes = { auction_id: 123, user_id: 2, value_cents: 10000 }
|
|
14
|
+
# result = contract.call(attributes)
|
|
15
|
+
# if result.success?
|
|
16
|
+
# puts "Bid created successfully."
|
|
17
|
+
# else
|
|
18
|
+
# puts "Failed to create bid: #{result.errors.to_h}"
|
|
19
|
+
# end
|
|
7
20
|
class CreateBidClosedContract < Contracts::ApplicationContract
|
|
21
|
+
# Repositories initialized to retrieve data for validation.
|
|
8
22
|
option :user_repository, default: proc { Repos::UserContext::UserRepository.new }
|
|
9
23
|
option :auction_repository, default: proc { Repos::AuctionContext::AuctionRepository.new }
|
|
10
24
|
option :bid_repository, default: proc { Repos::BidContext::BidRepository.new }
|
|
11
25
|
|
|
12
|
-
#
|
|
26
|
+
# Parameters specifying the required input types and fields.
|
|
13
27
|
params do
|
|
14
28
|
required(:auction_id).filled(:integer)
|
|
15
29
|
required(:user_id).filled(:integer)
|
|
@@ -21,9 +35,7 @@ module AuctionFunCore
|
|
|
21
35
|
end
|
|
22
36
|
end
|
|
23
37
|
|
|
24
|
-
#
|
|
25
|
-
# validate whether the given auction is valid at the database level.
|
|
26
|
-
# validate if the auction is open to receive bids
|
|
38
|
+
# Validates the auction's validity and status for receiving bids.
|
|
27
39
|
rule(:auction_id) do |context:|
|
|
28
40
|
context[:auction] ||= auction_repository.by_id(value)
|
|
29
41
|
|
|
@@ -42,9 +54,7 @@ module AuctionFunCore
|
|
|
42
54
|
end
|
|
43
55
|
end
|
|
44
56
|
|
|
45
|
-
#
|
|
46
|
-
# Validate whether the given user is valid at the database level.
|
|
47
|
-
# Validates if user has already placed a bid
|
|
57
|
+
# Validates the user's existence and checks if they have already placed a bid.
|
|
48
58
|
rule(:user_id) do |context:|
|
|
49
59
|
context[:user] ||= user_repository.by_id(value)
|
|
50
60
|
|
|
@@ -57,8 +67,7 @@ module AuctionFunCore
|
|
|
57
67
|
end
|
|
58
68
|
end
|
|
59
69
|
|
|
60
|
-
#
|
|
61
|
-
# The bid amount must be greater than or equal to the starting bid.
|
|
70
|
+
# Validates that the bid amount is greater than or equal to the auction's starting bid.
|
|
62
71
|
rule(:value_cents) do |context:|
|
|
63
72
|
unless rule_error?(:user_id)
|
|
64
73
|
closed_auction_bid_value_is_gteq_initial_bid?(key, value, context[:auction].initial_bid_cents)
|
|
@@ -67,7 +76,7 @@ module AuctionFunCore
|
|
|
67
76
|
|
|
68
77
|
private
|
|
69
78
|
|
|
70
|
-
#
|
|
79
|
+
# Helper method to check if the bid amount meets the minimum required bid.
|
|
71
80
|
def closed_auction_bid_value_is_gteq_initial_bid?(key, value_cents, minimal_bid_cents)
|
|
72
81
|
return unless value_cents < minimal_bid_cents
|
|
73
82
|
|
|
@@ -3,12 +3,25 @@
|
|
|
3
3
|
module AuctionFunCore
|
|
4
4
|
module Contracts
|
|
5
5
|
module BidContext
|
|
6
|
-
#
|
|
6
|
+
# This class validates the creation of new bids for penny-type auctions.
|
|
7
|
+
# It guarantees that the bid can only be made within the correct status of this type of auction,
|
|
8
|
+
# in addition, the participant must have sufficient balance in their wallet to place a new bid.
|
|
9
|
+
#
|
|
10
|
+
# @example Creating a bid for a penny auction
|
|
11
|
+
# contract = AuctionFunCore::Contracts::BidContext::CreateBidPennyContract.new
|
|
12
|
+
# attributes = { auction_id: 123, user_id: 2 }
|
|
13
|
+
# result = contract.call(attributes)
|
|
14
|
+
# if result.success?
|
|
15
|
+
# puts "Bid created successfully."
|
|
16
|
+
# else
|
|
17
|
+
# puts "Failed to create bid: #{result.errors.to_h}"
|
|
18
|
+
# end
|
|
7
19
|
class CreateBidPennyContract < Contracts::ApplicationContract
|
|
20
|
+
# Repositories initialized to retrieve data for validation.
|
|
8
21
|
option :user_repo, default: proc { Repos::UserContext::UserRepository.new }
|
|
9
22
|
option :auction_repo, default: proc { Repos::AuctionContext::AuctionRepository.new }
|
|
10
23
|
|
|
11
|
-
#
|
|
24
|
+
# Parameters specifying the required input types and fields.
|
|
12
25
|
params do
|
|
13
26
|
required(:auction_id).filled(:integer)
|
|
14
27
|
required(:user_id).filled(:integer)
|
|
@@ -19,9 +32,7 @@ module AuctionFunCore
|
|
|
19
32
|
end
|
|
20
33
|
end
|
|
21
34
|
|
|
22
|
-
#
|
|
23
|
-
# validate whether the given auction is valid at the database level.
|
|
24
|
-
# validate if the auction is open to receive bids
|
|
35
|
+
# Validates the auction's validity, kind, and status for receiving bids.
|
|
25
36
|
rule(:auction_id) do |context:|
|
|
26
37
|
context[:auction] ||= auction_repo.by_id(value)
|
|
27
38
|
|
|
@@ -40,9 +51,7 @@ module AuctionFunCore
|
|
|
40
51
|
end
|
|
41
52
|
end
|
|
42
53
|
|
|
43
|
-
#
|
|
44
|
-
# Validate whether the given user is valid at the database level.
|
|
45
|
-
# Validates if user has enough balance to bid.
|
|
54
|
+
# Validates the user's existence and ensures they have enough balance to bid.
|
|
46
55
|
rule(:user_id) do |context:|
|
|
47
56
|
context[:user] ||= user_repo.by_id(value)
|
|
48
57
|
|
|
@@ -59,7 +68,7 @@ module AuctionFunCore
|
|
|
59
68
|
|
|
60
69
|
private
|
|
61
70
|
|
|
62
|
-
#
|
|
71
|
+
# Helper method to check if the user has sufficient balance to place a bid in a penny auction.
|
|
63
72
|
def penny_auction_check_user_has_balance?(key, auction_bid_cents, balance_cents)
|
|
64
73
|
key.failure(I18n.t("contracts.errors.custom.bids.insufficient_balance")) if balance_cents < auction_bid_cents
|
|
65
74
|
end
|
|
@@ -3,12 +3,25 @@
|
|
|
3
3
|
module AuctionFunCore
|
|
4
4
|
module Contracts
|
|
5
5
|
module BidContext
|
|
6
|
-
#
|
|
6
|
+
# This class validates the creation of new bids for standard-type auctions.
|
|
7
|
+
# It ensures the bid is placed by a valid user on a valid auction that is open for bids,
|
|
8
|
+
# and that the bid value meets or exceeds the minimum bid required by the auction.
|
|
9
|
+
#
|
|
10
|
+
# @example Creating a bid for a standard auction
|
|
11
|
+
# contract = AuctionFunCore::Contracts::BidContext::CreateBidStandardContract.new
|
|
12
|
+
# attributes = { auction_id: 1, user_id: 2, value_cents: 5000 }
|
|
13
|
+
# result = contract.call(attributes)
|
|
14
|
+
# if result.success?
|
|
15
|
+
# puts "Bid created successfully."
|
|
16
|
+
# else
|
|
17
|
+
# puts "Failed to create bid: #{result.errors.to_h}"
|
|
18
|
+
# end
|
|
7
19
|
class CreateBidStandardContract < Contracts::ApplicationContract
|
|
20
|
+
# Repositories initialized to retrieve data for validation.
|
|
8
21
|
option :user_repo, default: proc { Repos::UserContext::UserRepository.new }
|
|
9
22
|
option :auction_repo, default: proc { Repos::AuctionContext::AuctionRepository.new }
|
|
10
23
|
|
|
11
|
-
#
|
|
24
|
+
# Parameters specifying the required input types and fields.
|
|
12
25
|
params do
|
|
13
26
|
required(:auction_id).filled(:integer)
|
|
14
27
|
required(:user_id).filled(:integer)
|
|
@@ -20,9 +33,7 @@ module AuctionFunCore
|
|
|
20
33
|
end
|
|
21
34
|
end
|
|
22
35
|
|
|
23
|
-
#
|
|
24
|
-
# validate whether the given auction is valid at the database level.
|
|
25
|
-
# validate if the auction is open to receive bids
|
|
36
|
+
# Validates the auction's validity, kind, and status for receiving bids.
|
|
26
37
|
rule(:auction_id) do |context:|
|
|
27
38
|
context[:auction] ||= auction_repo.by_id(value)
|
|
28
39
|
|
|
@@ -41,22 +52,20 @@ module AuctionFunCore
|
|
|
41
52
|
end
|
|
42
53
|
end
|
|
43
54
|
|
|
44
|
-
#
|
|
45
|
-
# Validate whether the given user is valid at the database level.
|
|
55
|
+
# Validates the user's existence in the database.
|
|
46
56
|
rule(:user_id) do |context:|
|
|
47
57
|
context[:user] ||= user_repo.by_id(value)
|
|
48
58
|
key.failure(I18n.t("contracts.errors.custom.not_found")) unless context[:user]
|
|
49
59
|
end
|
|
50
60
|
|
|
51
|
-
#
|
|
52
|
-
# must be greater than or equal to the auction's minimal bid.
|
|
61
|
+
# Validates that the bid amount is greater than or equal to the auction's minimum bid.
|
|
53
62
|
rule(:value_cents) do |context:|
|
|
54
63
|
standard_auction_valid_bid?(key, value, context[:auction].minimal_bid_cents)
|
|
55
64
|
end
|
|
56
65
|
|
|
57
66
|
private
|
|
58
67
|
|
|
59
|
-
#
|
|
68
|
+
# Helper method to check if the bid amount meets the minimum required bid.
|
|
60
69
|
def standard_auction_valid_bid?(key, value_cents, minimal_bid_cents)
|
|
61
70
|
return if value_cents >= minimal_bid_cents
|
|
62
71
|
|
|
@@ -3,12 +3,27 @@
|
|
|
3
3
|
module AuctionFunCore
|
|
4
4
|
module Contracts
|
|
5
5
|
module StaffContext
|
|
6
|
-
#
|
|
6
|
+
# This class is designed to authenticate staff members.
|
|
7
|
+
# It validates the login and password, checking their format and verifying them against the database records.
|
|
8
|
+
#
|
|
9
|
+
# @example Authenticating a staff member
|
|
10
|
+
# contract = AuctionFunCore::Contracts::StaffContext::AuthenticationContract.new
|
|
11
|
+
# attributes = { login: 'staff@example.com', password: 'securePassword123' }
|
|
12
|
+
# result = contract.call(attributes)
|
|
13
|
+
# if result.success?
|
|
14
|
+
# puts "Authentication successful."
|
|
15
|
+
# else
|
|
16
|
+
# puts "Authentication failed: #{result.errors.to_h}"
|
|
17
|
+
# end
|
|
18
|
+
#
|
|
7
19
|
class AuthenticationContract < ApplicationContract
|
|
20
|
+
# Scope for internationalization (i18n) entries specific to errors in this contract.
|
|
8
21
|
I18N_SCOPE = "contracts.errors.custom.default"
|
|
9
22
|
|
|
23
|
+
# Repositories initialized to retrieve data for validation.
|
|
10
24
|
option :staff_repository, default: proc { Repos::StaffContext::StaffRepository.new }
|
|
11
25
|
|
|
26
|
+
# Parameters specifying the required input types and fields.
|
|
12
27
|
params do
|
|
13
28
|
required(:login)
|
|
14
29
|
required(:password)
|
|
@@ -18,12 +33,11 @@ module AuctionFunCore
|
|
|
18
33
|
end
|
|
19
34
|
end
|
|
20
35
|
|
|
36
|
+
# Additional rules for validating the format of login and password.
|
|
21
37
|
rule(:login).validate(:login_format)
|
|
22
38
|
rule(:password).validate(:password_format)
|
|
23
39
|
|
|
24
|
-
#
|
|
25
|
-
# Searches for the staff in the database from the login, and, if found,
|
|
26
|
-
# compares the entered password.
|
|
40
|
+
# Validates the presence of the staff member in the database and checks if the password matches.
|
|
27
41
|
rule do |context:|
|
|
28
42
|
next if (rule_error?(:login) || schema_error?(:login)) || (rule_error?(:password) || schema_error?(:password))
|
|
29
43
|
|
|
@@ -3,13 +3,27 @@
|
|
|
3
3
|
module AuctionFunCore
|
|
4
4
|
module Contracts
|
|
5
5
|
module StaffContext
|
|
6
|
-
#
|
|
6
|
+
# This class is designed to create staff members.
|
|
7
|
+
# It validates the parameters, ensuring their format and uniqueness.
|
|
8
|
+
#
|
|
9
|
+
# @example Registering a new staff member
|
|
10
|
+
# contract = AuctionFunCore::Contracts::StaffContext::RegistrationContract.new
|
|
11
|
+
# attributes = { name: 'John Doe', email: 'john.doe@example.com', phone: '1234567890' }
|
|
12
|
+
# result = contract.call(attributes)
|
|
13
|
+
# if result.success?
|
|
14
|
+
# puts "Staff member registered successfully."
|
|
15
|
+
# else
|
|
16
|
+
# puts "Failed to register staff member: #{result.errors.to_h}"
|
|
17
|
+
# end
|
|
18
|
+
#
|
|
7
19
|
class RegistrationContract < ApplicationContract
|
|
20
|
+
# Scope for internationalization (i18n) entries specific to errors in this contract.
|
|
8
21
|
I18N_SCOPE = "contracts.errors.custom.default"
|
|
9
22
|
|
|
23
|
+
# Repositories initialized to retrieve data for validation.
|
|
10
24
|
option :staff_repository, default: proc { Repos::StaffContext::StaffRepository.new }
|
|
11
25
|
|
|
12
|
-
#
|
|
26
|
+
# Parameters specifying the required input types and fields.
|
|
13
27
|
params do
|
|
14
28
|
required(:name)
|
|
15
29
|
required(:email)
|
|
@@ -19,27 +33,25 @@ module AuctionFunCore
|
|
|
19
33
|
result.to_h.compact
|
|
20
34
|
end
|
|
21
35
|
|
|
22
|
-
#
|
|
36
|
+
# Normalizes and adds default values after coercion.
|
|
23
37
|
after(:value_coercer) do |result|
|
|
24
38
|
result.update(email: result[:email].strip.downcase) if result[:email]
|
|
25
39
|
result.update(phone: result[:phone].tr_s("^0-9", "")) if result[:phone]
|
|
26
40
|
end
|
|
27
41
|
end
|
|
28
42
|
|
|
43
|
+
# Validates the format of the staff member's name.
|
|
29
44
|
rule(:name).validate(:name_format)
|
|
30
45
|
|
|
31
|
-
#
|
|
32
|
-
# It must validate the format and uniqueness in the database.
|
|
46
|
+
# It ensures email format and checks for uniqueness in the database.
|
|
33
47
|
rule(:email).validate(:email_format)
|
|
34
48
|
rule(:email) do
|
|
35
|
-
# Email should be unique on database
|
|
36
49
|
if !rule_error?(:email) && staff_repository.exists?(email: value)
|
|
37
50
|
key.failure(I18n.t(:taken, scope: I18N_SCOPE))
|
|
38
51
|
end
|
|
39
52
|
end
|
|
40
53
|
|
|
41
|
-
#
|
|
42
|
-
# It must validate the format and uniqueness in the database.
|
|
54
|
+
# It ensures phone format and checks for uniqueness in the database.
|
|
43
55
|
rule(:phone).validate(:phone_format)
|
|
44
56
|
rule(:phone) do
|
|
45
57
|
if !rule_error?(:phone) && staff_repository.exists?(phone: value)
|