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
@@ -7,7 +7,7 @@ module AuctionFunCore
7
7
  module Finish
8
8
  ##
9
9
  # Operation class for finalizing a standard auction.
10
- # By default, this change auction status from 'running' to 'finished'.
10
+ # By default, this changes the auction status from 'running' to 'finished'.
11
11
  #
12
12
  class StandardOperation < AuctionFunCore::Operations::Base
13
13
  include Import["repos.auction_context.auction_repository"]
@@ -15,7 +15,21 @@ module AuctionFunCore
15
15
  include Import["workers.operations.auction_context.post_auction.winner_operation_job"]
16
16
  include Import["workers.operations.auction_context.post_auction.participant_operation_job"]
17
17
 
18
- # @todo Add custom doc
18
+ ##
19
+ # Executes the standard operation with the provided attributes.
20
+ #
21
+ # @param attributes [Hash] The attributes for the standard operation.
22
+ # @option attributes auction_id [Integer] The ID of the auction.
23
+ # @yield [Dry::Matcher::Evaluator] The block to handle the result of the operation.
24
+ # @return [Dry::Matcher::Evaluator] The result of the operation.
25
+ #
26
+ # @example
27
+ # attributes = { auction_id: 123 }
28
+ #
29
+ # AuctionFunCore::Operations::AuctionContext::Processor::Finish::StandardOperation.call(attributes) do |result|
30
+ # result.success { |auction| puts "Finished standard auction sucessfully! #{auction.to_h}" }
31
+ # result.failure { |failure| puts "Failed to finished standard auction: #{failure.errors.to_h}"}
32
+ # end
19
33
  def self.call(attributes, &block)
20
34
  operation = new.call(attributes)
21
35
 
@@ -24,12 +38,27 @@ module AuctionFunCore
24
38
  Dry::Matcher::ResultMatcher.call(operation, &block)
25
39
  end
26
40
 
27
- # TODO: update doc
28
- # It only performs the basic processing of completing an auction.
29
- # It just changes the status at the database level and triggers the finished event.
30
- # @param attrs [Hash] auction attributes
31
- # @option auction_id [Integer] Auction ID
32
- # @return [Dry::Monads::Result::Success, Dry::Monads::Result::Failure]
41
+ ##
42
+ # Performs the closing of a standard auction.
43
+ #
44
+ # @param attributes [Hash] The attributes for the standard operation.
45
+ # @option attributes auction_id [Integer] The ID of the auction.
46
+ # @return [Dry::Monads::Result::Success, Dry::Monads::Result::Failure] The result of the operation.
47
+ #
48
+ # @example
49
+ # attributes = { auction_id: 123 }
50
+ #
51
+ # operation = AuctionFunCore::Operations::AuctionContext::Processor::Finish::StandardOperation.call(attributes)
52
+ #
53
+ # if operation.success?
54
+ # auction = operation.success
55
+ # puts "Finished standard auction sucessfully! #{auction.to_h}"
56
+ # end
57
+ #
58
+ # if operation.failure?
59
+ # failure = operation.failure
60
+ # puts "Failed to finished standard auction: #{failure.errors.to_h}"
61
+ # end
33
62
  def call(attributes)
34
63
  auction = yield validate_contract(attributes)
35
64
  summary = yield load_standard_auction_winners_and_participants(auction.id)
@@ -52,10 +81,12 @@ module AuctionFunCore
52
81
 
53
82
  private
54
83
 
55
- # Calls the finish standard contract class to perform the validation
56
- # of the informed attributes.
57
- # @param attributes [Hash] auction attributes
58
- # @return [Dry::Monads::Result::Success, Dry::Monads::Result::Failure]
84
+ ##
85
+ # Validates the contract with the provided attributes.
86
+ #
87
+ # @param attributes [Hash] The attributes to validate.
88
+ # @return [Dry::Monads::Result] The result of the validation.
89
+ #
59
90
  def validate_contract(attributes)
60
91
  contract = standard_contract.call(attributes)
61
92
 
@@ -64,12 +95,25 @@ module AuctionFunCore
64
95
  Success(contract.context[:auction])
65
96
  end
66
97
 
98
+ ##
99
+ # Loads the winners and participants of the standard auction.
100
+ #
101
+ # @param auction_id [Integer] The ID of the auction.
102
+ # @return [Dry::Monads::Result] The result of loading the winners and participants.
103
+ #
67
104
  def load_standard_auction_winners_and_participants(auction_id)
68
105
  summary = relation.load_standard_auction_winners_and_participants(auction_id).first
69
106
 
70
107
  Success(summary)
71
108
  end
72
109
 
110
+ ##
111
+ # Updates the attributes of the finished auction.
112
+ #
113
+ # @param auction [Auction] The auction object.
114
+ # @param summary [Summary] The summary of winners and participants.
115
+ # @return [Dry::Monads::Result] The result of updating the attributes.
116
+ #
73
117
  def update_finished_auction(auction, summary)
74
118
  attrs = {status: "finished"}
75
119
  attrs[:winner_id] = summary.winner_id if summary.winner_id.present?
@@ -77,20 +121,45 @@ module AuctionFunCore
77
121
  Success(attrs)
78
122
  end
79
123
 
124
+ ##
125
+ # Retrieves the relation.
126
+ #
127
+ # @return [ROM::Relation] The relation object.
128
+ #
80
129
  def relation
81
130
  AuctionFunCore::Application[:container].relations[:auctions]
82
131
  end
83
132
 
133
+ ##
134
+ # Executes the winner operation asynchronously.
135
+ #
136
+ # @param auction_id [Integer] The ID of the auction.
137
+ # @param winner_id [Integer] The ID of the winner.
138
+ # @return [Dry::Monads::Result] The result of executing the operation.
139
+ #
84
140
  def winner_operation(auction_id, winner_id)
85
141
  return Success() if winner_id.blank?
86
142
 
87
143
  Success(winner_operation_job.class.perform_async(auction_id, winner_id))
88
144
  end
89
145
 
146
+ ##
147
+ # Executes the participant operation asynchronously.
148
+ #
149
+ # @param auction_id [Integer] The ID of the auction.
150
+ # @param participant_id [Integer] The ID of the participant.
151
+ # @return [Dry::Monads::Result] The result of executing the operation.
152
+ #
90
153
  def participant_operation(auction_id, participant_id)
91
154
  Success(participant_operation_job.class.perform_async(auction_id, participant_id))
92
155
  end
93
156
 
157
+ ##
158
+ # Publishes the auction finish event.
159
+ #
160
+ # @param auction [ROM::Struct::Auction] The auction object.
161
+ # @return [void]
162
+ #
94
163
  def publish_auction_finish_event(auction)
95
164
  Application[:event].publish("auctions.finished", auction.to_h)
96
165
  end
@@ -12,7 +12,21 @@ module AuctionFunCore
12
12
  include Import["repos.auction_context.auction_repository"]
13
13
  include Import["contracts.auction_context.processor.pause_contract"]
14
14
 
15
- # @todo Add custom doc
15
+ ##
16
+ # Executes the pause operation with the provided attributes.
17
+ #
18
+ # @param attributes [Hash] The attributes for the pause operation.
19
+ # @option attributes auction_id [Integer] The ID of the auction.
20
+ # @yield [Dry::Matcher::Evaluator] The block to handle the result of the operation.
21
+ # @return [Dry::Matcher::Evaluator] The result of the operation.
22
+ #
23
+ # @example
24
+ # attributes = { auction_id: 123 }
25
+ #
26
+ # AuctionFunCore::Operations::AuctionContext::Processor::PauseOperation.call(attributes) do |result|
27
+ # result.success { |auction| puts "Paused auction sucessfully! #{auction.to_h}" }
28
+ # result.failure { |failure| puts "Failed to pause auction: #{failure.errors.to_h}"}
29
+ # end
16
30
  def self.call(attributes, &block)
17
31
  operation = new.call(attributes)
18
32
 
@@ -21,6 +35,27 @@ module AuctionFunCore
21
35
  Dry::Matcher::ResultMatcher.call(operation, &block)
22
36
  end
23
37
 
38
+ ##
39
+ # Performing an auction pause
40
+ #
41
+ # @param attributes [Hash] The attributes for the pause operation.
42
+ # @option attributes auction_id [Integer] The ID of the auction.
43
+ # @return [Dry::Monads::Result::Success, Dry::Monads::Result::Failure] The result of the operation.
44
+ #
45
+ # @example
46
+ # attributes = { auction_id: 123 }
47
+ #
48
+ # operation = AuctionFunCore::Operations::AuctionContext::Processor::PauseOperation.call(attributes)
49
+ #
50
+ # if operation.success?
51
+ # auction = operation.success
52
+ # puts "Paused auction sucessfully! #{auction.to_h}"
53
+ # end
54
+ #
55
+ # if operation.failure?
56
+ # failure = operation.failure
57
+ # puts "Failed to pause auction: #{failure.errors.to_h}"
58
+ # end
24
59
  def call(attributes)
25
60
  attrs = yield validate(attributes)
26
61
 
@@ -12,7 +12,21 @@ module AuctionFunCore
12
12
  include Import["repos.auction_context.auction_repository"]
13
13
  include Import["contracts.auction_context.processor.unpause_contract"]
14
14
 
15
- # @todo Add custom doc
15
+ ##
16
+ # Executes the unpause operation with the provided attributes.
17
+ #
18
+ # @param attributes [Hash] The attributes for the unpause operation.
19
+ # @option attributes auction_id [Integer] The ID of the auction.
20
+ # @yield [Dry::Matcher::Evaluator] The block to handle the result of the operation.
21
+ # @return [Dry::Matcher::Evaluator] The result of the operation.
22
+ #
23
+ # @example
24
+ # attributes = { auction_id: 123 }
25
+ #
26
+ # AuctionFunCore::Operations::AuctionContext::Processor::UnpauseOperation.call(attributes) do |result|
27
+ # result.success { |auction| puts "Unpaused auction sucessfully! #{auction.to_h}" }
28
+ # result.failure { |failure| puts "Failed to unpause auction: #{failure.errors.to_h}"}
29
+ # end
16
30
  def self.call(attributes, &block)
17
31
  operation = new.call(attributes)
18
32
 
@@ -21,6 +35,27 @@ module AuctionFunCore
21
35
  Dry::Matcher::ResultMatcher.call(operation, &block)
22
36
  end
23
37
 
38
+ ##
39
+ # Performs the unpause of an auction.
40
+ #
41
+ # @param attributes [Hash] The attributes for the unpause operation.
42
+ # @option attributes auction_id [Integer] The ID of the auction.
43
+ # @return [Dry::Monads::Result::Success, Dry::Monads::Result::Failure] The result of the operation.
44
+ #
45
+ # @example
46
+ # attributes = { auction_id: 123 }
47
+ #
48
+ # operation = AuctionFunCore::Operations::AuctionContext::Processor::UnpauseOperation.call(attributes)
49
+ #
50
+ # if operation.success?
51
+ # auction = operation.success
52
+ # puts "Unpaused auction sucessfully! #{auction.to_h}"
53
+ # end
54
+ #
55
+ # if operation.failure?
56
+ # failure = operation.failure
57
+ # puts "Failed to unpause auction: #{failure.errors.to_h}"
58
+ # end
24
59
  def call(attributes)
25
60
  attrs = yield validate(attributes)
26
61
 
@@ -40,12 +40,30 @@ module AuctionFunCore
40
40
  struct_namespace Entities
41
41
  auto_struct(true)
42
42
 
43
+ # Retrieves a paginated list of auctions along with related information.
44
+ # By default, it retrieves the first page with 10 auctions per page and includes information for the top 3 bidders.
45
+ #
46
+ # @param page [Integer] The page number to retrieve (default is 1).
47
+ # @param per_page [Integer] The number of auctions per page (default is 10).
48
+ # @param options [Hash] Additional options for customization (default is {bidders_count: 3}).
49
+ # @option options [Integer] :bidders_count The number of top bidders to include in the result (default is 3).
50
+ # @return [Array<Hash>] An array of hashes representing the auctions and related information.
51
+ # @example Retrieve the first page of auctions with 10 per page and include information for the top 3 bidders
52
+ # all_auctions = all
53
+ #
54
+ # @example Retrieve the second page of auctions with 5 per page and include information for the top 5 bidders
55
+ # all_auctions = all(2, 5, { bidders_count: 5 })
56
+ #
57
+ # @example Retrieve the third page of auctions with 15 per page and include information for the top 2 bidders
58
+ # all_auctions = all(3, 15, { bidders_count: 2 })
59
+ #
60
+ # @raise [RuntimeError] if either `page` or `per_page` argument is not an integer.
43
61
  def all(page = 1, per_page = 10, options = {bidders_count: 3})
44
62
  raise "Invalid argument" unless page.is_a?(Integer) && per_page.is_a?(Integer)
45
63
 
46
64
  offset = ((page - 1) * per_page)
47
65
 
48
- read("
66
+ sql = <<-SQL
49
67
  SELECT a.id, a.title, a.description, a.kind, a.status, a.started_at, a.finished_at, a.stopwatch, a.initial_bid_cents,
50
68
  (SELECT COUNT(*) FROM (SELECT * FROM bids WHERE bids.auction_id = a.id) dt) AS total_bids,
51
69
  CASE
@@ -69,17 +87,37 @@ module AuctionFunCore
69
87
  WHEN a.kind = 'closed' THEN
70
88
  json_build_object('minimal', (a.initial_bid_cents + (a.initial_bid_cents * 0.10))::int)
71
89
  END as bids
72
- FROM auctions as a
73
- LEFT JOIN LATERAL (SELECT * FROM bids WHERE auction_id = a.id ORDER BY value_cents DESC LIMIT #{options[:bidders_count]}) as bi ON a.id = bi.auction_id
74
- LEFT JOIN users ON bi.user_id = users.id AND bi.auction_id = a.id
75
- GROUP BY a.id
76
- LIMIT #{per_page} OFFSET #{offset}")
90
+ FROM auctions as a
91
+ LEFT JOIN LATERAL (SELECT * FROM bids WHERE auction_id = a.id ORDER BY value_cents DESC LIMIT #{options[:bidders_count]}) as bi ON a.id = bi.auction_id
92
+ LEFT JOIN users ON bi.user_id = users.id AND bi.auction_id = a.id
93
+ GROUP BY a.id
94
+ LIMIT #{per_page} OFFSET #{offset}
95
+ SQL
96
+
97
+ read(sql)
77
98
  end
78
99
 
100
+ # Retrieves detailed information about a specific auction.
101
+ #
102
+ # @param auction_id [Integer] The ID of the auction to retrieve information for.
103
+ # @param options [Hash] Additional options for customization (default is {bidders_count: 3}).
104
+ # @option options [Integer] :bidders_count The number of top bidders to include in the result (default is 3).
105
+ # @return [Hash] A hash representing the auction and related information.
106
+ #
107
+ # @example Retrieve information for auction with ID 123
108
+ # auction_info = info(123)
109
+ #
110
+ # @example Retrieve information for auction with ID 456 and include information for the top 5 bidders
111
+ # auction_info = info(456, { bidders_count: 5 })
112
+ #
113
+ # @example Retrieve information for auction with ID 789 and include information for the top 2 bidders
114
+ # auction_info = info(789, { bidders_count: 2 })
115
+ #
116
+ # @raise [RuntimeError] if `auction_id` argument is not an integer.
79
117
  def info(auction_id, options = {bidders_count: 3})
80
118
  raise "Invalid argument" unless auction_id.is_a?(Integer)
81
119
 
82
- read("
120
+ sql = <<-SQL
83
121
  SELECT a.id, a.title, a.description, a.kind, a.status, a.started_at, a.finished_at, a.stopwatch, a.initial_bid_cents,
84
122
  (SELECT COUNT(*) FROM (SELECT * FROM bids WHERE bids.auction_id = #{auction_id}) dt) AS total_bids,
85
123
  CASE
@@ -103,11 +141,14 @@ module AuctionFunCore
103
141
  WHEN a.kind = 'closed' THEN
104
142
  json_build_object('minimal', (a.initial_bid_cents + (a.initial_bid_cents * 0.10))::int)
105
143
  END as bids
106
- FROM auctions as a
107
- LEFT JOIN LATERAL (SELECT * FROM bids WHERE auction_id = a.id ORDER BY value_cents DESC LIMIT #{options[:bidders_count]}) as bi ON a.id = bi.auction_id AND a.id = #{auction_id}
108
- LEFT JOIN users ON bi.user_id = users.id AND bi.auction_id = a.id
109
- WHERE a.id = #{auction_id}
110
- GROUP BY a.id")
144
+ FROM auctions as a
145
+ LEFT JOIN LATERAL (SELECT * FROM bids WHERE auction_id = a.id ORDER BY value_cents DESC LIMIT #{options[:bidders_count]}) as bi ON a.id = bi.auction_id AND a.id = #{auction_id}
146
+ LEFT JOIN users ON bi.user_id = users.id AND bi.auction_id = a.id
147
+ WHERE a.id = #{auction_id}
148
+ GROUP BY a.id
149
+ SQL
150
+
151
+ read(sql)
111
152
  end
112
153
 
113
154
  # Retrieves the standard auction winner and other participating bidders for a specified auction.
@@ -125,22 +166,26 @@ module AuctionFunCore
125
166
  def load_standard_auction_winners_and_participants(auction_id)
126
167
  raise "Invalid argument" unless auction_id.is_a?(Integer)
127
168
 
128
- read("SELECT a.id, a.kind, a.status, w.user_id AS winner_id, COALESCE(COUNT(b.id), 0) AS total_bids,
129
- COALESCE(
130
- ARRAY_REMOVE(ARRAY_AGG(DISTINCT b.user_id ORDER BY b.user_id), w.user_id), ARRAY[]::INT[]
131
- ) AS participant_ids
132
- FROM auctions a
133
- LEFT JOIN bids b ON a.id = b.auction_id
134
- LEFT JOIN (
135
- SELECT auction_id, user_id, MAX(value_cents) AS value_cents
136
- FROM bids
137
- WHERE auction_id = #{auction_id}
138
- GROUP BY auction_id, user_id
139
- ORDER BY value_cents DESC
140
- LIMIT 1
141
- ) AS w ON a.id = w.auction_id
142
- WHERE a.id = #{auction_id}
143
- GROUP BY a.id, w.user_id")
169
+ sql = <<-SQL
170
+ SELECT a.id, a.kind, a.status, w.user_id AS winner_id, COALESCE(COUNT(b.id), 0) AS total_bids,
171
+ COALESCE(
172
+ ARRAY_REMOVE(ARRAY_AGG(DISTINCT b.user_id ORDER BY b.user_id), w.user_id), ARRAY[]::INT[]
173
+ ) AS participant_ids
174
+ FROM auctions a
175
+ LEFT JOIN bids b ON a.id = b.auction_id
176
+ LEFT JOIN (
177
+ SELECT auction_id, user_id, MAX(value_cents) AS value_cents
178
+ FROM bids
179
+ WHERE auction_id = #{auction_id}
180
+ GROUP BY auction_id, user_id
181
+ ORDER BY value_cents DESC
182
+ LIMIT 1
183
+ ) AS w ON a.id = w.auction_id
184
+ WHERE a.id = #{auction_id}
185
+ GROUP BY a.id, w.user_id
186
+ SQL
187
+
188
+ read(sql)
144
189
  end
145
190
 
146
191
  # Retrieves the penny auction winner and other participating bidders for a specified auction.
@@ -158,21 +203,25 @@ module AuctionFunCore
158
203
  def load_penny_auction_winners_and_participants(auction_id)
159
204
  raise "Invalid argument" unless auction_id.is_a?(Integer)
160
205
 
161
- read("SELECT a.id, a.kind, a.status, w.user_id AS winner_id, COALESCE(COUNT(b.id), 0) AS total_bids,
162
- COALESCE(
163
- ARRAY_REMOVE(ARRAY_AGG(DISTINCT b.user_id ORDER BY b.user_id), w.user_id), ARRAY[]::INT[]
164
- ) AS participant_ids
165
- FROM auctions a
166
- LEFT JOIN bids b ON a.id = b.auction_id
167
- LEFT JOIN (
168
- SELECT auction_id, user_id
169
- FROM bids
170
- WHERE auction_id = #{auction_id}
171
- ORDER BY bids.created_at DESC
172
- LIMIT 1
173
- ) AS w ON a.id = w.auction_id
174
- WHERE a.id = #{auction_id}
175
- GROUP BY a.id, w.user_id")
206
+ sql = <<-SQL
207
+ SELECT a.id, a.kind, a.status, w.user_id AS winner_id, COALESCE(COUNT(b.id), 0) AS total_bids,
208
+ COALESCE(
209
+ ARRAY_REMOVE(ARRAY_AGG(DISTINCT b.user_id ORDER BY b.user_id), w.user_id), ARRAY[]::INT[]
210
+ ) AS participant_ids
211
+ FROM auctions a
212
+ LEFT JOIN bids b ON a.id = b.auction_id
213
+ LEFT JOIN (
214
+ SELECT auction_id, user_id
215
+ FROM bids
216
+ WHERE auction_id = #{auction_id}
217
+ ORDER BY bids.created_at DESC
218
+ LIMIT 1
219
+ ) AS w ON a.id = w.auction_id
220
+ WHERE a.id = #{auction_id}
221
+ GROUP BY a.id, w.user_id
222
+ SQL
223
+
224
+ read(sql)
176
225
  end
177
226
 
178
227
  # Retrieves the closed auction winner and other participating bidders for a specified auction.
@@ -190,70 +239,102 @@ module AuctionFunCore
190
239
  def load_closed_auction_winners_and_participants(auction_id)
191
240
  raise "Invalid argument" unless auction_id.is_a?(Integer)
192
241
 
193
- read("SELECT a.id, a.kind, a.status, w.user_id AS winner_id, COALESCE(COUNT(b.id), 0) AS total_bids,
194
- COALESCE(
195
- ARRAY_REMOVE(ARRAY_AGG(DISTINCT b.user_id ORDER BY b.user_id), w.user_id), ARRAY[]::INT[]
196
- ) AS participant_ids
197
- FROM auctions a
198
- LEFT JOIN bids b ON a.id = b.auction_id
199
- LEFT JOIN (
200
- SELECT auction_id, user_id, MAX(value_cents) AS value_cents
201
- FROM bids
202
- WHERE auction_id = #{auction_id}
203
- GROUP BY auction_id, user_id
204
- ORDER BY value_cents DESC
205
- LIMIT 1
206
- ) AS w ON a.id = w.auction_id
207
- WHERE a.id = #{auction_id}
208
- GROUP BY a.id, w.user_id")
242
+ sql = <<-SQL
243
+ SELECT a.id, a.kind, a.status, w.user_id AS winner_id, COALESCE(COUNT(b.id), 0) AS total_bids,
244
+ COALESCE(
245
+ ARRAY_REMOVE(ARRAY_AGG(DISTINCT b.user_id ORDER BY b.user_id), w.user_id), ARRAY[]::INT[]
246
+ ) AS participant_ids
247
+ FROM auctions a
248
+ LEFT JOIN bids b ON a.id = b.auction_id
249
+ LEFT JOIN (
250
+ SELECT auction_id, user_id, MAX(value_cents) AS value_cents
251
+ FROM bids
252
+ WHERE auction_id = #{auction_id}
253
+ GROUP BY auction_id, user_id
254
+ ORDER BY value_cents DESC
255
+ LIMIT 1
256
+ ) AS w ON a.id = w.auction_id
257
+ WHERE a.id = #{auction_id}
258
+ GROUP BY a.id, w.user_id
259
+ SQL
260
+
261
+ read(sql)
209
262
  end
210
263
 
264
+ # Loads statistics for the winner of a specific auction.
265
+ #
266
+ # @param auction_id [Integer] The ID of the auction to load statistics for.
267
+ # @param winner_id [Integer] The ID of the winner to load statistics for.
268
+ # @return [Hash] A hash representing the statistics for the winner of the auction.
269
+ #
270
+ # @example Load statistics for the winner of auction with ID 123 and winner with ID 456
271
+ # winner_stats = load_winner_statistics(123, 456)
272
+ #
273
+ # @raise [RuntimeError] if either `auction_id` or `winner_id` arguments are not integers.
211
274
  def load_winner_statistics(auction_id, winner_id)
212
275
  raise "Invalid argument" unless auction_id.is_a?(Integer) && winner_id.is_a?(Integer)
213
276
 
214
- read("SELECT a.id, COUNT(b.id) AS auction_total_bids, MAX(b.value_cents) AS winner_bid,
215
- date(a.finished_at) as auction_date,
216
- (SELECT COUNT(*) FROM bids b2
217
- WHERE b2.auction_id = #{auction_id}
218
- AND b2.user_id = #{winner_id}
219
- ) AS winner_total_bids
220
- FROM auctions a
221
- LEFT JOIN bids b ON a.id = b.auction_id AND a.id = #{auction_id}
222
- LEFT JOIN users u ON u.id = b.user_id AND u.id = #{winner_id}
223
- LEFT JOIN (
224
- SELECT auction_id, user_id, MAX(value_cents) AS value_cents
225
- FROM bids
226
- WHERE auction_id = #{auction_id}
227
- GROUP BY auction_id, user_id
228
- ORDER BY value_cents DESC
229
- LIMIT 1
230
- ) AS w ON a.id = w.auction_id
231
- WHERE a.id = #{auction_id}
232
- GROUP BY a.id")
277
+ sql = <<-SQL
278
+ SELECT a.id, COUNT(b.id) AS auction_total_bids, MAX(b.value_cents) AS winner_bid,
279
+ date(a.finished_at) as auction_date,
280
+ (SELECT COUNT(*) FROM bids b2
281
+ WHERE b2.auction_id = #{auction_id}
282
+ AND b2.user_id = #{winner_id}
283
+ ) AS winner_total_bids
284
+ FROM auctions a
285
+ LEFT JOIN bids b ON a.id = b.auction_id AND a.id = #{auction_id}
286
+ LEFT JOIN users u ON u.id = b.user_id AND u.id = #{winner_id}
287
+ LEFT JOIN (
288
+ SELECT auction_id, user_id, MAX(value_cents) AS value_cents
289
+ FROM bids
290
+ WHERE auction_id = #{auction_id}
291
+ GROUP BY auction_id, user_id
292
+ ORDER BY value_cents DESC
293
+ LIMIT 1
294
+ ) AS w ON a.id = w.auction_id
295
+ WHERE a.id = #{auction_id}
296
+ GROUP BY a.id
297
+ SQL
298
+
299
+ read(sql)
233
300
  end
234
301
 
302
+ # Loads statistics for a participant in a specific auction.
303
+ #
304
+ # @param auction_id [Integer] The ID of the auction to load statistics for.
305
+ # @param participant_id [Integer] The ID of the participant to load statistics for.
306
+ # @return [Hash] A hash representing the statistics for the participant in the auction.
307
+ #
308
+ # @example Load statistics for the participant with ID 456 in auction with ID 123
309
+ # participant_stats = load_participant_statistics(123, 456)
310
+ #
311
+ # @raise [RuntimeError] if either `auction_id` or `participant_id` arguments are not integers.
235
312
  def load_participant_statistics(auction_id, participant_id)
236
313
  raise "Invalid argument" unless auction_id.is_a?(Integer) && participant_id.is_a?(Integer)
237
314
 
238
- read("SELECT a.id, COUNT(b.id) AS auction_total_bids, MAX(b.value_cents) AS winner_bid,
239
- date(a.finished_at) as auction_date,
240
- (SELECT COUNT(*) FROM bids b2
241
- WHERE b2.auction_id = #{auction_id}
242
- AND b2.user_id = #{participant_id}
243
- ) AS winner_total_bids
244
- FROM auctions a
245
- LEFT JOIN bids b ON a.id = b.auction_id AND a.id = #{auction_id}
246
- LEFT JOIN users u ON u.id = b.user_id AND u.id = #{participant_id}
247
- LEFT JOIN (
248
- SELECT auction_id, user_id, MAX(value_cents) AS value_cents
249
- FROM bids
250
- WHERE auction_id = #{auction_id}
251
- GROUP BY auction_id, user_id
252
- ORDER BY value_cents DESC
253
- LIMIT 1
254
- ) AS w ON a.id = w.auction_id
255
- WHERE a.id = #{auction_id}
256
- GROUP BY a.id")
315
+ sql = <<-SQL
316
+ SELECT a.id, COUNT(b.id) AS auction_total_bids, MAX(b.value_cents) AS winner_bid,
317
+ date(a.finished_at) as auction_date,
318
+ (SELECT COUNT(*) FROM bids b2
319
+ WHERE b2.auction_id = #{auction_id}
320
+ AND b2.user_id = #{participant_id}
321
+ ) AS winner_total_bids
322
+ FROM auctions a
323
+ LEFT JOIN bids b ON a.id = b.auction_id AND a.id = #{auction_id}
324
+ LEFT JOIN users u ON u.id = b.user_id AND u.id = #{participant_id}
325
+ LEFT JOIN (
326
+ SELECT auction_id, user_id, MAX(value_cents) AS value_cents
327
+ FROM bids
328
+ WHERE auction_id = #{auction_id}
329
+ GROUP BY auction_id, user_id
330
+ ORDER BY value_cents DESC
331
+ LIMIT 1
332
+ ) AS w ON a.id = w.auction_id
333
+ WHERE a.id = #{auction_id}
334
+ GROUP BY a.id
335
+ SQL
336
+
337
+ read(sql)
257
338
  end
258
339
  end
259
340
  end
@@ -23,6 +23,24 @@ module AuctionFunCore
23
23
 
24
24
  struct_namespace Entities
25
25
  auto_struct(true)
26
+
27
+ # Retrieves a list of unique user IDs who have placed bids in a specified auction.
28
+ # A participant in an auction is defined as a user who has placed one or more bids.
29
+ #
30
+ # @param auction_id [Integer] the ID of the auction.
31
+ # @return [Array<Integer>] Returns an array of unique user IDs who have participated in the auction.
32
+ # @raise [RuntimeError] Raises an error if the auction_id is not an integer.
33
+ def participants(auction_id)
34
+ raise "Invalid argument" unless auction_id.is_a?(Integer)
35
+
36
+ sql = <<-SQL
37
+ SELECT COALESCE(ARRAY_AGG(DISTINCT user_id), ARRAY[]::INT[]) AS participant_ids
38
+ FROM bids
39
+ WHERE auction_id = #{auction_id}
40
+ SQL
41
+
42
+ read(sql)
43
+ end
26
44
  end
27
45
  end
28
46
  end