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.
Files changed (77) hide show
  1. checksums.yaml +4 -4
  2. data/.standard.yml +2 -0
  3. data/CHANGELOG.md +23 -0
  4. data/Procfile +1 -0
  5. data/README.md +34 -32
  6. data/Rakefile +1 -1
  7. data/i18n/en-US/contracts/contracts.en-US.yml +3 -0
  8. data/i18n/en-US/mail/application.en-US.yml +7 -0
  9. data/i18n/en-US/mail/auction_context/pre_auction/auction_start_reminder.en-US.yml +11 -0
  10. data/i18n/pt-BR/contracts/contracts.pt-BR.yml +3 -0
  11. data/i18n/pt-BR/mail/application.pt-BR.yml +7 -0
  12. data/i18n/pt-BR/mail/auction_context/pre_auction/auction_start_reminder.pt-BR.yml +11 -0
  13. data/lib/auction_fun_core/business/configuration.rb +31 -0
  14. data/lib/auction_fun_core/business/token_generator.rb +19 -1
  15. data/lib/auction_fun_core/contracts/application_contract.rb +9 -1
  16. data/lib/auction_fun_core/contracts/auction_context/create_contract.rb +35 -20
  17. data/lib/auction_fun_core/contracts/auction_context/post_auction/participant_contract.rb +23 -1
  18. data/lib/auction_fun_core/contracts/auction_context/post_auction/winner_contract.rb +22 -1
  19. data/lib/auction_fun_core/contracts/auction_context/pre_auction/auction_start_reminder_contract.rb +48 -0
  20. data/lib/auction_fun_core/contracts/auction_context/processor/finish/closed_contract.rb +19 -7
  21. data/lib/auction_fun_core/contracts/auction_context/processor/finish/penny_contract.rb +19 -7
  22. data/lib/auction_fun_core/contracts/auction_context/processor/finish/standard_contract.rb +19 -7
  23. data/lib/auction_fun_core/contracts/auction_context/processor/pause_contract.rb +16 -4
  24. data/lib/auction_fun_core/contracts/auction_context/processor/start_contract.rb +17 -5
  25. data/lib/auction_fun_core/contracts/auction_context/processor/unpause_contract.rb +16 -4
  26. data/lib/auction_fun_core/contracts/bid_context/create_bid_closed_contract.rb +20 -11
  27. data/lib/auction_fun_core/contracts/bid_context/create_bid_penny_contract.rb +18 -9
  28. data/lib/auction_fun_core/contracts/bid_context/create_bid_standard_contract.rb +19 -10
  29. data/lib/auction_fun_core/contracts/staff_context/authentication_contract.rb +18 -4
  30. data/lib/auction_fun_core/contracts/staff_context/registration_contract.rb +20 -8
  31. data/lib/auction_fun_core/contracts/user_context/authentication_contract.rb +18 -4
  32. data/lib/auction_fun_core/contracts/user_context/email_confirmation_contract.rb +17 -2
  33. data/lib/auction_fun_core/contracts/user_context/phone_confirmation_contract.rb +17 -2
  34. data/lib/auction_fun_core/contracts/user_context/registration_contract.rb +26 -8
  35. data/lib/auction_fun_core/entities/auction.rb +48 -4
  36. data/lib/auction_fun_core/entities/bid.rb +3 -2
  37. data/lib/auction_fun_core/entities/staff.rb +15 -2
  38. data/lib/auction_fun_core/entities/user.rb +31 -2
  39. data/lib/auction_fun_core/events/app.rb +8 -2
  40. data/lib/auction_fun_core/events/listener.rb +19 -16
  41. data/lib/auction_fun_core/operations/auction_context/create_operation.rb +25 -9
  42. data/lib/auction_fun_core/operations/auction_context/post_auction/participant_operation.rb +36 -3
  43. data/lib/auction_fun_core/operations/auction_context/post_auction/winner_operation.rb +36 -2
  44. data/lib/auction_fun_core/operations/auction_context/pre_auction/auction_start_reminder_operation.rb +96 -0
  45. data/lib/auction_fun_core/operations/auction_context/processor/finish/closed_operation.rb +82 -10
  46. data/lib/auction_fun_core/operations/auction_context/processor/finish/penny_operation.rb +81 -10
  47. data/lib/auction_fun_core/operations/auction_context/processor/finish/standard_operation.rb +81 -12
  48. data/lib/auction_fun_core/operations/auction_context/processor/pause_operation.rb +36 -1
  49. data/lib/auction_fun_core/operations/auction_context/processor/unpause_operation.rb +36 -1
  50. data/lib/auction_fun_core/relations/auctions.rb +178 -97
  51. data/lib/auction_fun_core/relations/bids.rb +18 -0
  52. data/lib/auction_fun_core/repos/auction_context/auction_repository.rb +40 -11
  53. data/lib/auction_fun_core/repos/bid_context/bid_repository.rb +27 -5
  54. data/lib/auction_fun_core/repos/staff_context/staff_repository.rb +63 -21
  55. data/lib/auction_fun_core/repos/user_context/user_repository.rb +69 -25
  56. data/lib/auction_fun_core/services/mail/auction_context/post_auction/participant_mailer.rb +7 -1
  57. data/lib/auction_fun_core/services/mail/auction_context/post_auction/winner_mailer.rb +7 -1
  58. data/lib/auction_fun_core/services/mail/auction_context/pre_auction/auction_start_reminder_mailer.rb +35 -0
  59. data/lib/auction_fun_core/services/mail/templates/auction_context/post_auction/participant.html.erb +1 -1
  60. data/lib/auction_fun_core/services/mail/templates/auction_context/post_auction/winner.html.erb +1 -1
  61. data/lib/auction_fun_core/services/mail/templates/auction_context/pre_auction/auction_start_reminder.html.erb +192 -0
  62. data/lib/auction_fun_core/services/mail/user_context/registration_mailer.rb +6 -0
  63. data/lib/auction_fun_core/version.rb +1 -1
  64. data/lib/auction_fun_core/workers/application_job.rb +10 -0
  65. data/lib/auction_fun_core/workers/operations/auction_context/post_auction/participant_operation_job.rb +7 -2
  66. data/lib/auction_fun_core/workers/operations/auction_context/post_auction/winner_operation_job.rb +6 -2
  67. data/lib/auction_fun_core/workers/operations/auction_context/pre_auction/auction_start_reminder_operation_job.rb +44 -0
  68. data/lib/auction_fun_core/workers/operations/auction_context/processor/finish/closed_operation_job.rb +6 -3
  69. data/lib/auction_fun_core/workers/operations/auction_context/processor/finish/penny_operation_job.rb +6 -3
  70. data/lib/auction_fun_core/workers/operations/auction_context/processor/finish/standard_operation_job.rb +6 -2
  71. data/lib/auction_fun_core/workers/operations/auction_context/processor/start_operation_job.rb +6 -3
  72. data/lib/auction_fun_core/workers/services/mail/auction_context/post_auction/participant_mailer_job.rb +12 -7
  73. data/lib/auction_fun_core/workers/services/mail/auction_context/post_auction/winner_mailer_job.rb +11 -5
  74. data/lib/auction_fun_core/workers/services/mail/auction_context/pre_auction/auction_start_reminder_mailer_job.rb +48 -0
  75. data/lib/auction_fun_core/workers/services/mail/user_context/registration_mailer_job.rb +8 -6
  76. data/system/providers/background_job.rb +6 -0
  77. metadata +10 -2
@@ -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
- # Contract class for finishing closed auctions.
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
- # Validation for auction.
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
- # Validation for kind.
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
- # Validation for status.
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
- # Contract class for finishing penny auctions.
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
- # Validation for auction.
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
- # Validation for kind.
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
- # Validation for status.
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
- # Contract class for finishing standard auctions.
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
- # Validation for auction.
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
- # Validation for kind.
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
- # Validation for status.
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
- # Contract class for pause auction.
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
- # Validation for auction.
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
- # Contract class for start auctions.
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
- # Validation for auction.
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
- # Validation for stopwatch.
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
- # Contract class for unpause auction.
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
- # Validation for auction.
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
- # Contract class to create new bids.
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
- # @param [Hash] opts Sets an allowed list of parameters, as well as some initial validations.
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
- # Validation for auction.
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
- # Validation for user.
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
- # Validation for value bid.
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
- # Checks if bid amount must be greater than or equal to the starting bid.
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
- # Contract class to create new bids.
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
- # @param [Hash] opts Sets an allowed list of parameters, as well as some initial validations.
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
- # Validation for auction.
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
- # Validation for user.
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
- # Checks if user has enough balance to bid.
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
- # Contract class to create new bids.
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
- # @param [Hash] opts Sets an allowed list of parameters, as well as some initial validations.
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
- # Validation for auction.
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
- # Validation for user.
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
- # Validation for value bid.
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
- # Checks if the bid amount is greather than or equal to minimum bid.
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
- # Contract class to authenticate staff.
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
- # Validation for login.
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
- # Contract class to create new staff.
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
- # @param [Hash] opts Sets an allowed list of parameters, as well as some initial validations.
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
- # Normalize and add default values
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
- # Validation for email.
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
- # Validation for phone.
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)