auction_fun_core 0.8.7 → 0.8.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (155) hide show
  1. checksums.yaml +4 -4
  2. data/.standard.yml +2 -0
  3. data/CHANGELOG.md +29 -0
  4. data/Procfile +1 -0
  5. data/README.md +34 -32
  6. data/Rakefile +1 -1
  7. data/auction_fun_core.gemspec +1 -1
  8. data/i18n/en-US/contracts/contracts.en-US.yml +3 -0
  9. data/i18n/en-US/mail/application.en-US.yml +7 -0
  10. data/i18n/en-US/mail/auction_context/pre_auction/auction_start_reminder.en-US.yml +11 -0
  11. data/i18n/pt-BR/contracts/contracts.pt-BR.yml +3 -0
  12. data/i18n/pt-BR/mail/application.pt-BR.yml +7 -0
  13. data/i18n/pt-BR/mail/auction_context/pre_auction/auction_start_reminder.pt-BR.yml +11 -0
  14. data/lib/auction_fun_core/business/configuration.rb +31 -0
  15. data/lib/auction_fun_core/business/token_generator.rb +19 -1
  16. data/lib/auction_fun_core/contracts/application_contract.rb +9 -1
  17. data/lib/auction_fun_core/contracts/auction_context/create_contract.rb +35 -20
  18. data/lib/auction_fun_core/contracts/auction_context/post_auction/participant_contract.rb +23 -1
  19. data/lib/auction_fun_core/contracts/auction_context/post_auction/winner_contract.rb +22 -1
  20. data/lib/auction_fun_core/contracts/auction_context/pre_auction/auction_start_reminder_contract.rb +48 -0
  21. data/lib/auction_fun_core/contracts/auction_context/processor/finish/closed_contract.rb +19 -7
  22. data/lib/auction_fun_core/contracts/auction_context/processor/finish/penny_contract.rb +19 -7
  23. data/lib/auction_fun_core/contracts/auction_context/processor/finish/standard_contract.rb +19 -7
  24. data/lib/auction_fun_core/contracts/auction_context/processor/pause_contract.rb +16 -4
  25. data/lib/auction_fun_core/contracts/auction_context/processor/start_contract.rb +17 -5
  26. data/lib/auction_fun_core/contracts/auction_context/processor/unpause_contract.rb +16 -4
  27. data/lib/auction_fun_core/contracts/bid_context/create_bid_closed_contract.rb +20 -11
  28. data/lib/auction_fun_core/contracts/bid_context/create_bid_penny_contract.rb +18 -9
  29. data/lib/auction_fun_core/contracts/bid_context/create_bid_standard_contract.rb +19 -10
  30. data/lib/auction_fun_core/contracts/staff_context/authentication_contract.rb +18 -4
  31. data/lib/auction_fun_core/contracts/staff_context/registration_contract.rb +20 -8
  32. data/lib/auction_fun_core/contracts/user_context/authentication_contract.rb +18 -4
  33. data/lib/auction_fun_core/contracts/user_context/email_confirmation_contract.rb +17 -2
  34. data/lib/auction_fun_core/contracts/user_context/phone_confirmation_contract.rb +17 -2
  35. data/lib/auction_fun_core/contracts/user_context/registration_contract.rb +26 -8
  36. data/lib/auction_fun_core/entities/auction.rb +48 -4
  37. data/lib/auction_fun_core/entities/bid.rb +3 -2
  38. data/lib/auction_fun_core/entities/staff.rb +15 -2
  39. data/lib/auction_fun_core/entities/user.rb +31 -2
  40. data/lib/auction_fun_core/events/app.rb +8 -2
  41. data/lib/auction_fun_core/events/listener.rb +19 -16
  42. data/lib/auction_fun_core/operations/auction_context/create_operation.rb +25 -9
  43. data/lib/auction_fun_core/operations/auction_context/post_auction/participant_operation.rb +36 -3
  44. data/lib/auction_fun_core/operations/auction_context/post_auction/winner_operation.rb +36 -2
  45. data/lib/auction_fun_core/operations/auction_context/pre_auction/auction_start_reminder_operation.rb +96 -0
  46. data/lib/auction_fun_core/operations/auction_context/processor/finish/closed_operation.rb +82 -10
  47. data/lib/auction_fun_core/operations/auction_context/processor/finish/penny_operation.rb +81 -10
  48. data/lib/auction_fun_core/operations/auction_context/processor/finish/standard_operation.rb +81 -12
  49. data/lib/auction_fun_core/operations/auction_context/processor/pause_operation.rb +36 -1
  50. data/lib/auction_fun_core/operations/auction_context/processor/unpause_operation.rb +36 -1
  51. data/lib/auction_fun_core/relations/auctions.rb +178 -97
  52. data/lib/auction_fun_core/relations/bids.rb +18 -0
  53. data/lib/auction_fun_core/repos/auction_context/auction_repository.rb +40 -11
  54. data/lib/auction_fun_core/repos/bid_context/bid_repository.rb +27 -5
  55. data/lib/auction_fun_core/repos/staff_context/staff_repository.rb +63 -21
  56. data/lib/auction_fun_core/repos/user_context/user_repository.rb +69 -25
  57. data/lib/auction_fun_core/services/mail/auction_context/post_auction/participant_mailer.rb +7 -1
  58. data/lib/auction_fun_core/services/mail/auction_context/post_auction/winner_mailer.rb +7 -1
  59. data/lib/auction_fun_core/services/mail/auction_context/pre_auction/auction_start_reminder_mailer.rb +35 -0
  60. data/lib/auction_fun_core/services/mail/templates/auction_context/post_auction/participant.html.erb +1 -1
  61. data/lib/auction_fun_core/services/mail/templates/auction_context/post_auction/winner.html.erb +1 -1
  62. data/lib/auction_fun_core/services/mail/templates/auction_context/pre_auction/auction_start_reminder.html.erb +192 -0
  63. data/lib/auction_fun_core/services/mail/user_context/registration_mailer.rb +6 -0
  64. data/lib/auction_fun_core/version.rb +1 -1
  65. data/lib/auction_fun_core/workers/application_job.rb +10 -0
  66. data/lib/auction_fun_core/workers/operations/auction_context/post_auction/participant_operation_job.rb +7 -2
  67. data/lib/auction_fun_core/workers/operations/auction_context/post_auction/winner_operation_job.rb +6 -2
  68. data/lib/auction_fun_core/workers/operations/auction_context/pre_auction/auction_start_reminder_operation_job.rb +44 -0
  69. data/lib/auction_fun_core/workers/operations/auction_context/processor/finish/closed_operation_job.rb +6 -3
  70. data/lib/auction_fun_core/workers/operations/auction_context/processor/finish/penny_operation_job.rb +6 -3
  71. data/lib/auction_fun_core/workers/operations/auction_context/processor/finish/standard_operation_job.rb +6 -2
  72. data/lib/auction_fun_core/workers/operations/auction_context/processor/start_operation_job.rb +6 -3
  73. data/lib/auction_fun_core/workers/services/mail/auction_context/post_auction/participant_mailer_job.rb +12 -7
  74. data/lib/auction_fun_core/workers/services/mail/auction_context/post_auction/winner_mailer_job.rb +11 -5
  75. data/lib/auction_fun_core/workers/services/mail/auction_context/pre_auction/auction_start_reminder_mailer_job.rb +48 -0
  76. data/lib/auction_fun_core/workers/services/mail/user_context/registration_mailer_job.rb +8 -6
  77. data/spec/auction_fun_core/contracts/auction_context/create_contract_spec.rb +158 -0
  78. data/spec/auction_fun_core/contracts/auction_context/post_auction/participant_contract_spec.rb +77 -0
  79. data/spec/auction_fun_core/contracts/auction_context/post_auction/winner_contract_spec.rb +76 -0
  80. data/spec/auction_fun_core/contracts/auction_context/pre_auction/auction_start_reminder_contract_spec.rb +48 -0
  81. data/spec/auction_fun_core/contracts/auction_context/processor/finish/closed_contract_spec.rb +59 -0
  82. data/spec/auction_fun_core/contracts/auction_context/processor/finish/penny_contract_spec.rb +59 -0
  83. data/spec/auction_fun_core/contracts/auction_context/processor/finish/standard_contract_spec.rb +59 -0
  84. data/spec/auction_fun_core/contracts/auction_context/processor/pause_contract_spec.rb +39 -0
  85. data/spec/auction_fun_core/contracts/auction_context/processor/start_contract_spec.rb +59 -0
  86. data/spec/auction_fun_core/contracts/auction_context/processor/unpause_contract_spec.rb +39 -0
  87. data/spec/auction_fun_core/contracts/bid_context/create_bid_closed_contract_spec.rb +130 -0
  88. data/spec/auction_fun_core/contracts/bid_context/create_bid_penny_contract_spec.rb +118 -0
  89. data/spec/auction_fun_core/contracts/bid_context/create_bid_standard_contract_spec.rb +154 -0
  90. data/spec/auction_fun_core/contracts/staff_context/authentication_contract_spec.rb +89 -0
  91. data/spec/auction_fun_core/contracts/staff_context/registration_contract_spec.rb +24 -0
  92. data/spec/auction_fun_core/contracts/user_context/authentication_contract_spec.rb +89 -0
  93. data/spec/auction_fun_core/contracts/user_context/email_confirmation_contract_spec.rb +54 -0
  94. data/spec/auction_fun_core/contracts/user_context/phone_confirmation_contract_spec.rb +54 -0
  95. data/spec/auction_fun_core/contracts/user_context/registration_contract_spec.rb +27 -0
  96. data/spec/auction_fun_core/entities/auction_spec.rb +75 -0
  97. data/spec/auction_fun_core/entities/bid_spec.rb +7 -0
  98. data/spec/auction_fun_core/entities/staff_spec.rb +38 -0
  99. data/spec/auction_fun_core/entities/user_spec.rb +106 -0
  100. data/spec/auction_fun_core/operations/auction_context/create_operation_spec.rb +126 -0
  101. data/spec/auction_fun_core/operations/auction_context/post_auction/participant_operation_spec.rb +88 -0
  102. data/spec/auction_fun_core/operations/auction_context/post_auction/winner_operation_spec.rb +76 -0
  103. data/spec/auction_fun_core/operations/auction_context/pre_auction/auction_start_reminder_operation_spec.rb +98 -0
  104. data/spec/auction_fun_core/operations/auction_context/processor/finish/closed_operation_spec.rb +107 -0
  105. data/spec/auction_fun_core/operations/auction_context/processor/finish/penny_operation_spec.rb +107 -0
  106. data/spec/auction_fun_core/operations/auction_context/processor/finish/standard_operation_spec.rb +106 -0
  107. data/spec/auction_fun_core/operations/auction_context/processor/pause_operation_spec.rb +83 -0
  108. data/spec/auction_fun_core/operations/auction_context/processor/start_operation_spec.rb +147 -0
  109. data/spec/auction_fun_core/operations/auction_context/processor/unpause_operation_spec.rb +80 -0
  110. data/spec/auction_fun_core/operations/bid_context/create_bid_closed_operation_spec.rb +95 -0
  111. data/spec/auction_fun_core/operations/bid_context/create_bid_penny_operation_spec.rb +133 -0
  112. data/spec/auction_fun_core/operations/bid_context/create_bid_standard_operation_spec.rb +95 -0
  113. data/spec/auction_fun_core/operations/staff_context/authentication_operation_spec.rb +74 -0
  114. data/spec/auction_fun_core/operations/staff_context/registration_operation_spec.rb +93 -0
  115. data/spec/auction_fun_core/operations/user_context/authentication_operation_spec.rb +74 -0
  116. data/spec/auction_fun_core/operations/user_context/email_confirmation_operation_spec.rb +76 -0
  117. data/spec/auction_fun_core/operations/user_context/phone_confirmation_operation_spec.rb +76 -0
  118. data/spec/auction_fun_core/operations/user_context/registration_operation_spec.rb +100 -0
  119. data/spec/auction_fun_core/relations/auctions_spec.rb +471 -0
  120. data/spec/auction_fun_core/repos/auction_context/auction_repository_spec.rb +64 -0
  121. data/spec/auction_fun_core/repos/bid_context/bid_repository_spec.rb +64 -0
  122. data/spec/auction_fun_core/repos/staff_context/staff_repository_spec.rb +118 -0
  123. data/spec/auction_fun_core/repos/user_context/user_repository_spec.rb +117 -0
  124. data/spec/auction_fun_core/services/mail/auction_context/post_auction/participant_mailer_spec.rb +48 -0
  125. data/spec/auction_fun_core/services/mail/auction_context/post_auction/winner_mailer_spec.rb +48 -0
  126. data/spec/auction_fun_core/services/mail/auction_context/pre_auction/auction_start_reminder_mailer_spec.rb +40 -0
  127. data/spec/auction_fun_core/services/mail/user_context/registration_mailer_spec.rb +33 -0
  128. data/spec/auction_fun_core/workers/operations/auction_context/post_auction/participation_operation_job_spec.rb +54 -0
  129. data/spec/auction_fun_core/workers/operations/auction_context/post_auction/winner_operation_job_spec.rb +48 -0
  130. data/spec/auction_fun_core/workers/operations/auction_context/pre_auction/auction_start_reminder_operation_job_spec.rb +53 -0
  131. data/spec/auction_fun_core/workers/operations/auction_context/processor/finish/closed_operation_job_spec.rb +47 -0
  132. data/spec/auction_fun_core/workers/operations/auction_context/processor/finish/penny_operation_job_spec.rb +47 -0
  133. data/spec/auction_fun_core/workers/operations/auction_context/processor/finish/standard_operation_job_spec.rb +47 -0
  134. data/spec/auction_fun_core/workers/operations/auction_context/processor/start_operation_job_spec.rb +47 -0
  135. data/spec/auction_fun_core/workers/services/mail/auction_context/post_auction/participant_mailer_job_spec.rb +62 -0
  136. data/spec/auction_fun_core/workers/services/mail/auction_context/post_auction/pre_auction/auction_start_reminder_mailer_job_spec.rb +59 -0
  137. data/spec/auction_fun_core/workers/services/mail/auction_context/post_auction/winner_mailer_job_spec.rb +62 -0
  138. data/spec/auction_fun_core/workers/services/mail/user_context/registration_mailer_job_spec.rb +53 -0
  139. data/spec/auction_fun_core_spec.rb +7 -0
  140. data/spec/spec_helper.rb +61 -0
  141. data/spec/support/background_job.rb +7 -0
  142. data/spec/support/factories/auctions.rb +143 -0
  143. data/spec/support/factories/bids.rb +6 -0
  144. data/spec/support/factories/staffs.rb +18 -0
  145. data/spec/support/factories/users.rb +43 -0
  146. data/spec/support/faker.rb +6 -0
  147. data/spec/support/mail.rb +13 -0
  148. data/spec/support/shared_examples/validate_email_contract.rb +25 -0
  149. data/spec/support/shared_examples/validate_name_contract.rb +19 -0
  150. data/spec/support/shared_examples/validate_password_confirmation_contract.rb +16 -0
  151. data/spec/support/shared_examples/validate_password_contract.rb +18 -0
  152. data/spec/support/shared_examples/validate_phone_contract.rb +25 -0
  153. data/spec/support/shared_examples/validate_stopwatch_contract.rb +32 -0
  154. data/system/providers/background_job.rb +6 -0
  155. metadata +87 -2
@@ -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)
@@ -3,12 +3,27 @@
3
3
  module AuctionFunCore
4
4
  module Contracts
5
5
  module UserContext
6
- # Contract class to authenticate users.
6
+ # This class is designed to authenticate users.
7
+ # It verifies the provided login credentials against stored user data in the system.
8
+ #
9
+ # @example Authenticating a user
10
+ # contract = AuctionFunCore::Contracts::UserContext::AuthenticationContract.new
11
+ # attributes = { login: 'example_user', password: 'securePassword123' }
12
+ # result = contract.call(attributes)
13
+ # if result.success?
14
+ # puts "User authenticated successfully."
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 :user_repository, default: proc { Repos::UserContext::UserRepository.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 user in the database from the login, and, if found,
26
- # compares the entered password.
40
+ # Validates the presence of the user 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,12 +3,27 @@
3
3
  module AuctionFunCore
4
4
  module Contracts
5
5
  module UserContext
6
- # Contract class responsible for validating the confirmation token for email.
6
+ # This class provides validation for confirming email addresses.
7
+ # It verifies the provided email confirmation token against stored user data in the system.
8
+ #
9
+ # @example Confirming an email address
10
+ # contract = AuctionFunCore::Contracts::UserContext::EmailConfirmationContract.new
11
+ # attributes = { email_confirmation_token: 'example_token' }
12
+ # result = contract.call(attributes)
13
+ # if result.success?
14
+ # puts "Email address enabled for confirmation."
15
+ # else
16
+ # puts "Failed to confirm email address: #{result.errors.to_h}"
17
+ # end
18
+ #
7
19
  class EmailConfirmationContract < 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 :user_repository, default: proc { Repos::UserContext::UserRepository.new }
11
25
 
26
+ # Parameters specifying the required input types and fields.
12
27
  params do
13
28
  required(:email_confirmation_token)
14
29
 
@@ -17,7 +32,6 @@ module AuctionFunCore
17
32
  end
18
33
  end
19
34
 
20
- # Validation for email_confirmation_token.
21
35
  # Searches for the user in the database from the email_confirmation_token
22
36
  rule do |context:|
23
37
  next if schema_error?(:email_confirmation_token)
@@ -29,6 +43,7 @@ module AuctionFunCore
29
43
  key(:email_confirmation_token).failure(I18n.t("not_found", scope: I18N_SCOPE))
30
44
  end
31
45
 
46
+ # Additional validation to check if the user account associated with the token is active.
32
47
  rule do |context:|
33
48
  next if context[:user].blank? || context[:user].active?
34
49
 
@@ -3,12 +3,27 @@
3
3
  module AuctionFunCore
4
4
  module Contracts
5
5
  module UserContext
6
- # Contract class responsible for validating the confirmation token for phone number.
6
+ # This class provides validation for confirming phone numbers.
7
+ # It verifies the provided phone confirmation token against stored user data in the system.
8
+ #
9
+ # @example Confirming a phone number
10
+ # contract = AuctionFunCore::Contracts::UserContext::PhoneConfirmationContract.new
11
+ # attributes = { phone_confirmation_token: 'example_token' }
12
+ # result = contract.call(attributes)
13
+ # if result.success?
14
+ # puts "Phone number enabled for confirmation."
15
+ # else
16
+ # puts "Failed to confirm phone number: #{result.errors.to_h}"
17
+ # end
18
+ #
7
19
  class PhoneConfirmationContract < 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 :user_repository, default: proc { Repos::UserContext::UserRepository.new }
11
25
 
26
+ # Parameters specifying the required input types and fields.
12
27
  params do
13
28
  required(:phone_confirmation_token)
14
29
 
@@ -17,7 +32,6 @@ module AuctionFunCore
17
32
  end
18
33
  end
19
34
 
20
- # Validation for token_confirmation_token.
21
35
  # Searches for the user in the database from the phone_confirmation_token
22
36
  rule do |context:|
23
37
  next if schema_error?(:phone_confirmation_token)
@@ -29,6 +43,7 @@ module AuctionFunCore
29
43
  key(:phone_confirmation_token).failure(I18n.t("not_found", scope: I18N_SCOPE))
30
44
  end
31
45
 
46
+ # Additional validation to check if the user account associated with the token is active.
32
47
  rule do |context:|
33
48
  next if context[:user].blank? || context[:user].active?
34
49
 
@@ -3,13 +3,33 @@
3
3
  module AuctionFunCore
4
4
  module Contracts
5
5
  module UserContext
6
- # Contract class to create new users.
6
+ # This class is designed to create new users.
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 = {
12
+ # name: 'John Doe',
13
+ # email: 'john.doe@example.com',
14
+ # phone: '1234567890'
15
+ # password: 'password',
16
+ # password_confirmation: 'password'
17
+ # }
18
+ # result = contract.call(attributes)
19
+ # if result.success?
20
+ # puts "New user registered successfully."
21
+ # else
22
+ # puts "Failed to register new user: #{result.errors.to_h}"
23
+ # end
24
+ #
7
25
  class RegistrationContract < ApplicationContract
26
+ # Scope for internationalization (i18n) entries specific to errors in this contract.
8
27
  I18N_SCOPE = "contracts.errors.custom.default"
9
28
 
29
+ # Repositories initialized to retrieve data for validation.
10
30
  option :user_repository, default: proc { Repos::UserContext::UserRepository.new }
11
31
 
12
- # @param [Hash] opts Sets an allowed list of parameters, as well as some initial validations.
32
+ # Parameters specifying the required input types and fields.
13
33
  params do
14
34
  required(:name)
15
35
  required(:email)
@@ -21,17 +41,17 @@ module AuctionFunCore
21
41
  result.to_h.compact
22
42
  end
23
43
 
24
- # Normalize and add default values
44
+ # Normalizes and adds default values after coercion.
25
45
  after(:value_coercer) do |result|
26
46
  result.update(email: result[:email].strip.downcase) if result[:email]
27
47
  result.update(phone: result[:phone].tr_s("^0-9", "")) if result[:phone]
28
48
  end
29
49
  end
30
50
 
51
+ # Validates the format of the user's name.
31
52
  rule(:name).validate(:name_format)
32
53
 
33
- # Validation for email.
34
- # It must validate the format and uniqueness in the database.
54
+ # It ensures email format and checks for uniqueness in the database.
35
55
  rule(:email).validate(:email_format)
36
56
  rule(:email) do
37
57
  # Email should be unique on database
@@ -40,8 +60,7 @@ module AuctionFunCore
40
60
  end
41
61
  end
42
62
 
43
- # Validation for phone.
44
- # It must validate the format and uniqueness in the database.
63
+ # It ensures phone format and checks for uniqueness in the database.
45
64
  rule(:phone).validate(:phone_format)
46
65
  rule(:phone) do
47
66
  if !rule_error?(:phone) && user_repository.exists?(phone: value)
@@ -49,7 +68,6 @@ module AuctionFunCore
49
68
  end
50
69
  end
51
70
 
52
- # Validation for password.
53
71
  # Check if the confirmation matches the password.
54
72
  rule(:password).validate(:password_format)
55
73
  rule(:password, :password_confirmation) do
@@ -2,22 +2,66 @@
2
2
 
3
3
  module AuctionFunCore
4
4
  module Entities
5
- # Auction Relations class. This return simple objects with attribute readers
6
- # to represent data in your auction.
5
+ ##
6
+ # Defines the Auction class as Entity. It appears to be a simple data structure
7
+ # class representing auction-related information.
7
8
  class Auction < ROM::Struct
8
- INQUIRER_ATTRIBUTES = Relations::Auctions::STATUSES.values.freeze
9
-
9
+ # Retrieves the initial bid amount for an auction as a Money object.
10
+ #
11
+ # This method creates and returns a new Money object that represents the initial bid
12
+ # amount required to start bidding in the auction. It utilizes `initial_bid_cents` and
13
+ # `initial_bid_currency` attributes to construct the Money object, ensuring that the amount
14
+ # is correctly represented in the specified currency.
15
+ #
16
+ # @return [Money] Returns a Money object representing the initial bid amount with the specified currency.
10
17
  def initial_bid
11
18
  Money.new(initial_bid_cents, initial_bid_currency)
12
19
  end
13
20
 
21
+ # Retrieves the minimal bid amount for an auction as a Money object.
22
+ #
23
+ # This method creates and returns a new Money object that represents the minimal bid
24
+ # amount required to participate in the auction. It uses `minimal_bid_cents` and
25
+ # `minimal_bid_currency` attributes to construct the Money object.
26
+ #
27
+ # @return [Money] Returns a Money object representing the minimal bid amount with the appropriate currency.
14
28
  def minimal_bid
15
29
  Money.new(minimal_bid_cents, minimal_bid_currency)
16
30
  end
17
31
 
32
+ # Checks if an auction has a winner.
33
+ #
34
+ # This method determines if an auction has a winner based on the presence of a `winner_id`.
35
+ # It returns true if the `winner_id` is present, indicating that the auction has concluded
36
+ # with a winning bidder.
37
+ #
38
+ # @return [Boolean] Returns `true` if there is a winner for the auction, otherwise returns `false`.
18
39
  def winner?
19
40
  winner_id.present?
20
41
  end
42
+
43
+ # Checks if an auction has already started.
44
+ #
45
+ # This method determines if an auction has begun based on its status and by comparing
46
+ # the auction's start time (`started_at`) with the current time. An auction is considered
47
+ # started if it is no longer scheduled (i.e., its status is not "scheduled") and
48
+ # the start time (`started_at`) is equal to or before the current time.
49
+ # @return [Boolean] Returns `true` if the auction has already started, otherwise returns `false`.
50
+ def started?
51
+ status != "scheduled" && Time.current > started_at
52
+ end
53
+
54
+ # Checks if an auction has not started yet.
55
+ #
56
+ # This method verifies if an auction is still in the "scheduled" status and whether
57
+ # its start time (`started_at`) is still in the future compared to the current time.
58
+ # The auction is considered not started if it is scheduled and the start time
59
+ # has not yet been reached.
60
+ #
61
+ # @return [Boolean] Returns `true` if the auction has not started yet, otherwise returns `false`.
62
+ def not_started?
63
+ status == "scheduled" && Time.current <= started_at
64
+ end
21
65
  end
22
66
  end
23
67
  end
@@ -2,8 +2,9 @@
2
2
 
3
3
  module AuctionFunCore
4
4
  module Entities
5
- # Bid Relations class. This return simple objects with attribute readers
6
- # to represent data in your bid.
5
+ ##
6
+ # Defines the Bid class as Entity. It appears to be a simple data structure
7
+ # class representing bid-related information.
7
8
  class Bid < ROM::Struct
8
9
  end
9
10
  end
@@ -2,17 +2,30 @@
2
2
 
3
3
  module AuctionFunCore
4
4
  module Entities
5
- # Staff Relations class. This return simple objects with attribute readers
6
- # to represent data in your staff.
5
+ ##
6
+ # Defines the Staff class as Entity. It appears to be a simple data structure
7
+ # class representing staff-related information.
7
8
  class Staff < ROM::Struct
9
+ ##
10
+ # Checks if the staff is active.
11
+ #
12
+ # @return [Boolean] True if the staff is active, otherwise false.
8
13
  def active?
9
14
  active
10
15
  end
11
16
 
17
+ ##
18
+ # Checks if the staff is inactive.
19
+ #
20
+ # @return [Boolean] True if the staff is inactive, otherwise false.
12
21
  def inactive?
13
22
  !active
14
23
  end
15
24
 
25
+ ##
26
+ # Returns staff information excluding password digest.
27
+ #
28
+ # @return [Hash] Staff information.
16
29
  def info
17
30
  attributes.except(:password_digest)
18
31
  end
@@ -2,33 +2,62 @@
2
2
 
3
3
  module AuctionFunCore
4
4
  module Entities
5
- # User Relations class. This return simple objects with attribute readers
6
- # to represent data in your user.
5
+ ##
6
+ # Defines the User class as Entity. It appears to be a simple data structure
7
+ # class representing user-related information.
7
8
  class User < ROM::Struct
9
+ ##
10
+ # Checks if the user is active.
11
+ #
12
+ # @return [Boolean] True if the user is active, otherwise false.
8
13
  def active?
9
14
  active
10
15
  end
11
16
 
17
+ ##
18
+ # Checks if the user is inactive.
19
+ #
20
+ # @return [Boolean] True if the user is inactive, otherwise false.
12
21
  def inactive?
13
22
  !active
14
23
  end
15
24
 
25
+ ##
26
+ # Checks if the user has been confirmed.
27
+ #
28
+ # @return [Boolean] True if the user is confirmed, otherwise false.
16
29
  def confirmed?
17
30
  confirmed_at.present?
18
31
  end
19
32
 
33
+ ##
34
+ # Checks if the user's email has been confirmed.
35
+ #
36
+ # @return [Boolean] True if the email is confirmed, otherwise false.
20
37
  def email_confirmed?
21
38
  email_confirmation_at.present?
22
39
  end
23
40
 
41
+ ##
42
+ # Checks if the user's phone has been confirmed.
43
+ #
44
+ # @return [Boolean] True if the phone is confirmed, otherwise false.
24
45
  def phone_confirmed?
25
46
  phone_confirmation_at.present?
26
47
  end
27
48
 
49
+ ##
50
+ # Returns user information excluding password digest.
51
+ #
52
+ # @return [Hash] User information.
28
53
  def info
29
54
  attributes.except(:password_digest)
30
55
  end
31
56
 
57
+ ##
58
+ # Returns the user's balance as a Money object.
59
+ #
60
+ # @return [Money] User's balance.
32
61
  def balance
33
62
  Money.new(balance_cents, balance_currency)
34
63
  end
@@ -2,23 +2,29 @@
2
2
 
3
3
  module AuctionFunCore
4
4
  module Events
5
- # Event class to register business events on system.
5
+ ##
6
+ # Represents the main application class for registering business events in the system.
7
+ #
8
+ # This class includes Dry::Events::Publisher[:app] to enable event publishing functionality.
6
9
  # @see https://dry-rb.org/gems/dry-events/main/
7
10
  class App
8
- # @!parser include Dry::Events::Publisher[:app]
9
11
  include Dry::Events::Publisher[:app]
10
12
 
13
+ # Registers events related to auctions.
11
14
  register_event("auctions.created")
12
15
  register_event("auctions.started")
13
16
  register_event("auctions.finished")
14
17
  register_event("auctions.paused")
15
18
  register_event("auctions.unpaused")
16
19
 
20
+ # Registers events related to bids.
17
21
  register_event("bids.created")
18
22
 
23
+ # Registers events related to staffs.
19
24
  register_event("staffs.authentication")
20
25
  register_event("staffs.registration")
21
26
 
27
+ # Registers events related to users.
22
28
  register_event("users.authentication")
23
29
  register_event("users.registration")
24
30
  register_event("users.confirmation")
@@ -2,7 +2,10 @@
2
2
 
3
3
  module AuctionFunCore
4
4
  module Events
5
- # Event class that can listen business events.
5
+ ##
6
+ # Represents a class that listens to business events and performs actions accordingly.
7
+ #
8
+ # This class defines methods to handle various events related to auctions, bids, staff, and users.
6
9
  # @see https://dry-rb.org/gems/dry-events/main/#event-listeners
7
10
  class Listener
8
11
  # Listener for to *auctions.created* event.
@@ -36,15 +39,15 @@ module AuctionFunCore
36
39
  end
37
40
 
38
41
  # Listener for to *bids.created* event.
39
- # @param event [Integer] Auction ID
42
+ # @param event [ROM::Struct::Bid] Auction ID
40
43
  def on_bids_created(bid)
41
44
  logger("Create bid with: #{bid.to_h}")
42
45
  end
43
46
 
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
47
+ # Listener for the *staffs.authentication* event.
48
+ # @param attributes [Hash] Authentication attributes.
49
+ # @option attributes staff_id [Integer] Staff ID.
50
+ # @option attributes time [DateTime] Authentication time.
48
51
  def on_staffs_authentication(attributes)
49
52
  logger("Staff #{attributes[:staff_id]} authenticated on: #{attributes[:time].iso8601}")
50
53
  end
@@ -61,26 +64,26 @@ module AuctionFunCore
61
64
  logger("New registered user: #{user.to_h}")
62
65
  end
63
66
 
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
67
+ # Listener for the *users.authentication* event.
68
+ # @param attributes [Hash] Authentication attributes.
69
+ # @option attributes user_id [Integer] User ID.
70
+ # @option attributes time [DateTime] Authentication time.
68
71
  def on_users_authentication(attributes)
69
72
  logger("User #{attributes[:user_id]} authenticated on: #{attributes[:time].iso8601}")
70
73
  end
71
74
 
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
75
+ # Listener for the *users.confirmation* event.
76
+ # @param attributes [Hash] Confirmation attributes.
77
+ # @option user_id [Integer] User ID.
78
+ # @option time [DateTime] Authentication time.
76
79
  def on_users_confirmation(attributes)
77
80
  logger("User #{attributes[:user_id]} confirmed at: #{attributes[:time].iso8601}")
78
81
  end
79
82
 
80
83
  private
81
84
 
82
- # Append message to system log.
83
- # @param message [String] the message
85
+ # Appends a message to the system log.
86
+ # @param message [String] The message.
84
87
  def logger(message)
85
88
  Application[:logger].info(message)
86
89
  end
@@ -10,6 +10,7 @@ module AuctionFunCore
10
10
  include Import["repos.auction_context.auction_repository"]
11
11
  include Import["contracts.auction_context.create_contract"]
12
12
  include Import["workers.operations.auction_context.processor.start_operation_job"]
13
+ include Import["workers.operations.auction_context.pre_auction.auction_start_reminder_operation_job"]
13
14
 
14
15
  # @todo Add custom doc
15
16
  def self.call(attributes, &block)
@@ -27,6 +28,7 @@ module AuctionFunCore
27
28
  auction_repository.transaction do |_t|
28
29
  @auction = yield persist(values)
29
30
  yield scheduled_start_auction(@auction)
31
+ yield schedule_auction_notification(@auction)
30
32
  yield publish_auctions_created(@auction)
31
33
  end
32
34
 
@@ -63,15 +65,6 @@ module AuctionFunCore
63
65
  Success(auction_repository.create(result))
64
66
  end
65
67
 
66
- # Triggers the publication of event *auctions.created*.
67
- # @param auction [Hash] Auction persisted attributes
68
- # @return [Dry::Monads::Result::Success]
69
- def publish_auctions_created(auction)
70
- Application[:event].publish("auctions.created", auction.to_h)
71
-
72
- Success()
73
- end
74
-
75
68
  # Calls the background job class that will schedule the start of the auction.
76
69
  # Added a small delay to perform operations (such as sending broadcasts and/or other operations).
77
70
  # @param auction [ROM::Struct::Auction]
@@ -81,6 +74,29 @@ module AuctionFunCore
81
74
 
82
75
  Success(start_operation_job.class.perform_at(perform_at, auction.id))
83
76
  end
77
+
78
+ # Schedules a notification to be sent to users one hour before the auction starts.
79
+ # The scheduling is only done if the start of the auction is more than one hour ahead of the current time,
80
+ # ensuring that there is sufficient time for the notification to be sent.
81
+ #
82
+ # @param auction [ROM::Struct::Auction]
83
+ # @return [String] sidekiq jid
84
+ def schedule_auction_notification(auction)
85
+ perform_time = auction.started_at - 1.hour
86
+
87
+ return Success() if perform_time <= Time.current
88
+
89
+ Success(auction_start_reminder_operation_job.class.perform_at(perform_time, auction.id))
90
+ end
91
+
92
+ # Triggers the publication of event *auctions.created*.
93
+ # @param auction [ROM::Struct::Auction]
94
+ # @return [Dry::Monads::Result::Success]
95
+ def publish_auctions_created(auction)
96
+ Application[:event].publish("auctions.created", auction.to_h)
97
+
98
+ Success()
99
+ end
84
100
  end
85
101
  end
86
102
  end