auction_fun_core 0.8.5 → 0.8.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +25 -0
  3. data/auction_fun_core.gemspec +1 -0
  4. data/db/migrate/20240229143000_create_auctions.rb +1 -0
  5. data/db/seeds.rb +87 -36
  6. data/i18n/en-US/contracts/contracts.en-US.yml +9 -0
  7. data/i18n/en-US/mail/application.en-US.yml +59 -0
  8. data/i18n/en-US/mail/auction_context/post_auction/participant.en-US.yml +13 -0
  9. data/i18n/en-US/mail/auction_context/post_auction/winner.en-US.yml +13 -0
  10. data/i18n/pt-BR/contracts/contracts.pt-BR.yml +9 -0
  11. data/i18n/pt-BR/mail/application.pt-BR.yml +59 -0
  12. data/i18n/pt-BR/mail/auction_context/post_auction/participant.pt-BR.yml +13 -0
  13. data/i18n/pt-BR/mail/auction_context/post_auction/winner.pt-BR.yml +13 -0
  14. data/i18n/pt-BR/mail/user_context/registration.pt-BR.yml +0 -4
  15. data/lib/auction_fun_core/contracts/auction_context/post_auction/participant_contract.rb +42 -0
  16. data/lib/auction_fun_core/contracts/auction_context/post_auction/winner_contract.rb +41 -0
  17. data/lib/auction_fun_core/contracts/auction_context/processor/finish/closed_contract.rb +47 -0
  18. data/lib/auction_fun_core/contracts/auction_context/processor/finish/penny_contract.rb +48 -0
  19. data/lib/auction_fun_core/contracts/auction_context/processor/finish/standard_contract.rb +48 -0
  20. data/lib/auction_fun_core/entities/auction.rb +6 -0
  21. data/lib/auction_fun_core/operations/auction_context/create_operation.rb +12 -2
  22. data/lib/auction_fun_core/operations/auction_context/post_auction/participant_operation.rb +52 -0
  23. data/lib/auction_fun_core/operations/auction_context/post_auction/winner_operation.rb +51 -0
  24. data/lib/auction_fun_core/operations/auction_context/processor/finish/closed_operation.rb +100 -0
  25. data/lib/auction_fun_core/operations/auction_context/processor/finish/penny_operation.rb +100 -0
  26. data/lib/auction_fun_core/operations/auction_context/processor/finish/standard_operation.rb +102 -0
  27. data/lib/auction_fun_core/operations/auction_context/processor/start_operation.rb +23 -11
  28. data/lib/auction_fun_core/operations/bid_context/create_bid_penny_operation.rb +57 -7
  29. data/lib/auction_fun_core/operations/staff_context/registration_operation.rb +10 -0
  30. data/lib/auction_fun_core/relations/auctions.rb +167 -26
  31. data/lib/auction_fun_core/relations/staffs.rb +1 -1
  32. data/lib/auction_fun_core/services/mail/auction_context/post_auction/participant_mailer.rb +31 -0
  33. data/lib/auction_fun_core/services/mail/auction_context/post_auction/winner_mailer.rb +31 -0
  34. data/lib/auction_fun_core/services/mail/templates/auction_context/post_auction/participant.html.erb +173 -0
  35. data/lib/auction_fun_core/services/mail/templates/auction_context/post_auction/winner.html.erb +174 -0
  36. data/lib/auction_fun_core/services/mail/templates/user_context/registration.html.erb +2 -2
  37. data/lib/auction_fun_core/version.rb +1 -1
  38. data/lib/auction_fun_core/workers/application_job.rb +2 -0
  39. data/lib/auction_fun_core/workers/operations/auction_context/post_auction/participant_operation_job.rb +33 -0
  40. data/lib/auction_fun_core/workers/operations/auction_context/post_auction/winner_operation_job.rb +33 -0
  41. data/lib/auction_fun_core/workers/operations/auction_context/processor/finish/closed_operation_job.rb +34 -0
  42. data/lib/auction_fun_core/workers/operations/auction_context/processor/finish/penny_operation_job.rb +37 -0
  43. data/lib/auction_fun_core/workers/operations/auction_context/processor/finish/standard_operation_job.rb +34 -0
  44. data/lib/auction_fun_core/workers/services/mail/auction_context/post_auction/participant_mailer_job.rb +51 -0
  45. data/lib/auction_fun_core/workers/services/mail/auction_context/post_auction/winner_mailer_job.rb +51 -0
  46. data/system/providers/background_job.rb +19 -0
  47. metadata +43 -5
  48. data/lib/auction_fun_core/contracts/auction_context/processor/finish_contract.rb +0 -27
  49. data/lib/auction_fun_core/operations/auction_context/processor/finish_operation.rb +0 -61
  50. data/lib/auction_fun_core/workers/operations/auction_context/processor/finish_operation_job.rb +0 -32
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b42434481eccb486a4e38674f4219b1969e8951bd0a06430066a2ca9e9c9931d
4
- data.tar.gz: a243a07a6b63c1e9a10f17a616290b1eea8c825af4a5e1a47e7f4f3515e192c6
3
+ metadata.gz: 3dc7fade29c1849f1e1c8d9a67cd060e0ceeac555290cf9cc3588a27eab72ee0
4
+ data.tar.gz: 7995c3ca65daa279c8e989771f7989e06695fcbdef4d7472c4f5aee0c02048f1
5
5
  SHA512:
6
- metadata.gz: 6a3d12e06b32f527e2744f996b14716e32e6f496a5367452eeeae62425a34c7a90878c2f256e901a9a165b00325838f0bba29526580d02dc65d0240c4444d2f8
7
- data.tar.gz: 4dcaa1d26811cdab77368cc5eb5567b83a5cf647e9f123ecaed217e41e908e7f1ea6e56a5fcfccc6410f04e9ba91b054fe282c41a7c7b1b5806556006f76e703
6
+ metadata.gz: ddfa76b5f57846ed62986520b98c367f46490c6d74aebd55b45ff033f84ddfb31f95dc370afec5159b49e93bdf678b4d63437b58bcc47e63c6461b5963aa6d31
7
+ data.tar.gz: eddbd9f79955aed50f5ac48605a16454bb93329e3e87fb21eb8437c0af43291b0ec84f3b29099635fa7cb89cab0e4cd0cdc8cfec433b3e003d1b69a94ace1f4a
data/CHANGELOG.md CHANGED
@@ -1,5 +1,30 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.8.7] - 2024-04-23
4
+
5
+ ### Added
6
+
7
+ - Removing default values from relations;
8
+ - Rebuild factories to not contain default values;
9
+ - Add automated tests for auction relations;
10
+
11
+ ## [0.8.6] - 2024-04-23
12
+
13
+ ### Added
14
+
15
+ - Auction finalization configured for each type of auction;
16
+ - Add operations for winner and participant of an auction;
17
+ - Configure background job to work with unique jobs;
18
+ - Add 'sidekiq-unique-jobs' to be responsible for finishing penny auctions;
19
+
20
+ ### Changed:
21
+
22
+ - General improvements on seed data;
23
+
24
+ ### Fixed:
25
+
26
+ - NameError: uninitialized constant AuctionFunCore::Workers::ApplicationJob::Sidekiq (NameError)
27
+
3
28
  ## [0.8.5] - 2024-04-03
4
29
 
5
30
  ### Added
@@ -49,6 +49,7 @@ Gem::Specification.new do |spec|
49
49
  spec.add_dependency "rom", "5.3.0"
50
50
  spec.add_dependency "rom-sql", "3.6.2"
51
51
  spec.add_dependency "sidekiq", "7.2.2"
52
+ spec.add_dependency "sidekiq-unique-jobs", "8.0.10"
52
53
  spec.add_dependency "yard", "0.9.36"
53
54
  spec.add_dependency "zeitwerk", "2.6.13"
54
55
 
@@ -5,6 +5,7 @@ ROM::SQL.migration do
5
5
  create_table(:auctions) do
6
6
  primary_key :id
7
7
  foreign_key :staff_id, :staffs, null: false
8
+ foreign_key :winner_id, :users
8
9
  column :title, String, null: false
9
10
  column :description, :text
10
11
  column :kind, :auction_kinds, null: false
data/db/seeds.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "pry"
4
3
  require "faker"
4
+ require "pry"
5
5
 
6
6
  I18n.enforce_available_locales = false
7
7
  Faker::Config.locale = "pt-BR"
@@ -13,7 +13,6 @@ STOPWATCH_OPTIONS = [15, 30, 45, 60].freeze
13
13
  AuctionFunCore::Application.start(:core)
14
14
 
15
15
  # Instantiate repos
16
- auction_repository = AuctionFunCore::Repos::AuctionContext::AuctionRepository.new
17
16
  staff_repository = AuctionFunCore::Repos::StaffContext::StaffRepository.new
18
17
 
19
18
  # Create root staff. Create as a regular user using the normal flow and after that
@@ -44,6 +43,19 @@ AuctionFunCore::Operations::StaffContext::RegistrationOperation.call(common_staf
44
43
  result.success { |staff| @staff = staff }
45
44
  end
46
45
 
46
+ # Add some users
47
+ 100.times do
48
+ attributes = {
49
+ name: Faker::Name.name, email: Faker::Internet.unique.email,
50
+ phone: Faker::PhoneNumber.unique.cell_phone_in_e164, password: "password",
51
+ password_confirmation: "password"
52
+ }
53
+ AuctionFunCore::Operations::UserContext::RegistrationOperation.call(attributes) do |result|
54
+ result.failure { |failure| raise "Error to create user: #{failure}" }
55
+ result.success { |user| puts "Create user with: #{user.to_h}" }
56
+ end
57
+ end
58
+
47
59
  # Create some standard auctions
48
60
  (1..15).each do |i|
49
61
  attributes = {
@@ -53,7 +65,31 @@ end
53
65
  }
54
66
  AuctionFunCore::Operations::AuctionContext::CreateOperation.call(attributes) do |result|
55
67
  result.failure { |failure| raise "Error to create standard auction: #{failure}" }
56
- result.success { |auction| puts "Create standard auction with: #{auction.to_h}" }
68
+ result.success do |auction|
69
+ @auction = auction
70
+ puts "Create standard auction with: #{auction.to_h}"
71
+ end
72
+ end
73
+
74
+ # Create auctions that have no bid. Multiples if 7
75
+ next if (i % 7).zero?
76
+
77
+ # Increase the value of each new bid by 10%
78
+ @current_bid = @auction.minimal_bid_cents
79
+ @minimal_percentage = 0.1
80
+ # Create some bids for standard auctions based on total users
81
+ (2..100).to_a.sample(rand(1..100)).each_with_index do |user_id, index|
82
+ @current_bid = index.zero? ? @current_bid : (@current_bid + (@current_bid * @minimal_percentage)).round(half: :up)
83
+ bid_params = {
84
+ auction_id: @auction.id,
85
+ user_id: user_id,
86
+ value_cents: @current_bid
87
+ }
88
+
89
+ AuctionFunCore::Operations::BidContext::CreateBidStandardOperation.call(bid_params) do |result|
90
+ result.failure { |failure| raise "Error to create bid: #{failure}" }
91
+ result.success { |bid| puts "Create standard bid with: #{bid.to_h}" }
92
+ end
57
93
  end
58
94
  end
59
95
 
@@ -65,52 +101,67 @@ end
65
101
 
66
102
  attributes = {
67
103
  staff_id: @staff.id, title: Faker::Commerce.product_name, description: Faker::Lorem.paragraph_by_chars,
68
- kind: "penny", started_at: started_at, finished_at: finished_at, stopwatch: stopwatch
104
+ kind: "penny", started_at: started_at, finished_at: finished_at, stopwatch: stopwatch,
105
+ initial_bid_cents: (i * 100), minimal_bid_cents: (i * 100)
69
106
  }
70
107
  AuctionFunCore::Operations::AuctionContext::CreateOperation.call(attributes) do |result|
71
108
  result.failure { |failure| raise "Error to create penny auction: #{failure}" }
72
- result.success { |auction| puts "Create penny auction with: #{auction.to_h}" }
109
+ result.success do |auction|
110
+ @auction = auction
111
+ puts "Create penny auction with: #{auction.to_h}"
112
+ end
113
+ end
114
+
115
+ # Create auctions that have no bid. Multiples if 7
116
+ next if (i % 7).zero?
117
+
118
+ # Create some bids for penny auctions based on total users
119
+ (2..100).to_a.sample(rand(1..100)).each do |user_id|
120
+ bid_params = {
121
+ auction_id: @auction.id,
122
+ user_id: user_id,
123
+ value_cents: @auction.minimal_bid_cents
124
+ }
125
+
126
+ AuctionFunCore::Operations::BidContext::CreateBidPennyOperation.call(bid_params) do |result|
127
+ result.failure { |failure| raise "Error to create bid: #{failure}" }
128
+ result.success { |bid| puts "Create penny bid with: #{bid.to_h}" }
129
+ end
73
130
  end
74
131
  end
75
132
 
76
133
  # Create some closed auctions
77
- (1..3).each do |i|
134
+ (1..5).each do |i|
78
135
  attributes = {
79
- staff_id: @staff.id, title: Faker::Commerce.product_name, kind: "closed",
80
- started_at: i.hour.from_now, finished_at: i.day.from_now.end_of_day,
136
+ staff_id: @staff.id, title: Faker::Commerce.product_name, description: Faker::Lorem.paragraph_by_chars,
137
+ kind: "closed", started_at: i.hour.from_now, finished_at: i.day.from_now.end_of_day,
81
138
  initial_bid_cents: (i * 1000)
82
139
  }
83
140
  AuctionFunCore::Operations::AuctionContext::CreateOperation.call(attributes) do |result|
84
141
  result.failure { |failure| raise "Error to create closed auction: #{failure}" }
85
- result.success { |auction| puts "Create closed auction with: #{auction.to_h}" }
142
+ result.success do |auction|
143
+ @auction = auction
144
+ puts "Create closed auction with: #{auction.to_h}"
145
+ end
86
146
  end
87
- end
88
-
89
- # Add some users
90
- 100.times do
91
- attributes = {
92
- name: Faker::Name.name, email: Faker::Internet.unique.email,
93
- phone: Faker::PhoneNumber.unique.cell_phone_in_e164, password: "password",
94
- password_confirmation: "password"
95
- }
96
- AuctionFunCore::Operations::UserContext::RegistrationOperation.call(attributes) do |result|
97
- result.failure { |failure| raise "Error to create user: #{failure}" }
98
- result.success { |user| puts "Create user with: #{user.to_h}" }
99
- end
100
- end
101
-
102
- # Create some bids
103
- auction_repository.all.each do |auction|
104
- next if auction.id.even?
105
-
106
- bid_params = {
107
- auction_id: auction.id,
108
- user_id: rand(2..100),
109
- value_cents: auction.minimal_bid_cents + (auction.minimal_bid_cents * 0.10)
110
- }
111
147
 
112
- "AuctionFunCore::Operations::BidContext::CreateBid#{auction.kind.capitalize}Operation".constantize.call(bid_params) do |result|
113
- result.failure { |failure| raise "Error to create bid: #{failure}" }
114
- result.success { |bid| puts "Create bid with: #{bid.to_h}" }
148
+ # Create auctions that have no bid. Pair numbers
149
+ next if i.even?
150
+
151
+ @minimal_bid = @auction.minimal_bid_cents
152
+ # Create some bids for closed auctions based on total users
153
+ (2..100).to_a.sample(rand(1..100)).each_with_index do |user_id, index|
154
+ # Choosing a random value for the bid, obeying the rule that it has to be just greater than the minimum bid.
155
+ random_bid = index.zero? ? @minimal_bid : rand((@minimal_bid + 1)..10_000).round
156
+ bid_params = {
157
+ auction_id: @auction.id,
158
+ user_id: user_id,
159
+ value_cents: random_bid
160
+ }
161
+
162
+ AuctionFunCore::Operations::BidContext::CreateBidClosedOperation.call(bid_params) do |result|
163
+ result.failure { |failure| raise "Error to create bid: #{failure}" }
164
+ result.success { |bid| puts "Create closed bid with: #{bid.to_h}" }
165
+ end
115
166
  end
116
167
  end
@@ -70,3 +70,12 @@ en-US:
70
70
  auction_context:
71
71
  create:
72
72
  finished_at: "must be after started time"
73
+ post_auction:
74
+ participant:
75
+ none: "there was no participation from this user in the auction reported"
76
+ winner:
77
+ wrong: "was not the winner of this auction"
78
+ processor:
79
+ finish:
80
+ invalid_kind: "auction with invalid type"
81
+ invalid_status: "auction with invalid status"
@@ -0,0 +1,59 @@
1
+ en-US:
2
+ date:
3
+ abbr_day_names:
4
+ - Sun
5
+ - Mon
6
+ - Tue
7
+ - Wed
8
+ - Thu
9
+ - Fri
10
+ - Sat
11
+ abbr_month_names:
12
+ -
13
+ - Jan
14
+ - Feb
15
+ - Mar
16
+ - Apr
17
+ - May
18
+ - Jun
19
+ - Jul
20
+ - Aug
21
+ - Sep
22
+ - Oct
23
+ - Nov
24
+ - Dec
25
+ day_names:
26
+ - Sunday
27
+ - Monday
28
+ - Tuesday
29
+ - Wednesday
30
+ - Thursday
31
+ - Friday
32
+ - Saturday
33
+ formats:
34
+ default: "%Y-%m-%d"
35
+ long: "%B %d, %Y"
36
+ short: "%b %d"
37
+ month_names:
38
+ -
39
+ - January
40
+ - February
41
+ - March
42
+ - April
43
+ - May
44
+ - June
45
+ - July
46
+ - August
47
+ - September
48
+ - October
49
+ - November
50
+ - December
51
+ order:
52
+ - :year
53
+ - :month
54
+ - :day
55
+ application:
56
+ general:
57
+ hello: "Hi %{name}"
58
+ app_name: "AuctionFun"
59
+ team: "Team AuctionFun"
@@ -0,0 +1,13 @@
1
+ en-US:
2
+ mail:
3
+ auction_context:
4
+ post_auction:
5
+ participant_mailer:
6
+ subject: "Thank you for participating in the auction %{title}"
7
+ body:
8
+ description: "Thank you for participating in the auction <b>%{title}</b>! Although you weren't the winner this time, we would like to recognize your efforts and share some statistics on your performance:"
9
+ stats:
10
+ auction_total_bids: "Total auction bids: %{auction_total_bids}"
11
+ winner_bid: "Winner bid: %{winner_bid}"
12
+ auction_date: "Auction Date"
13
+ regards: "We hope you found the experience enriching and invite you to participate in our future auctions. Follow our website and social media to stay up to date with upcoming opportunities."
@@ -0,0 +1,13 @@
1
+ en-US:
2
+ mail:
3
+ auction_context:
4
+ post_auction:
5
+ winner_mailer:
6
+ subject: "Congratulations! You are the winner of the auction %{title}!"
7
+ body:
8
+ description: "We are very happy to inform you that you were the winner of our auction <b>%{title}</b>! Your bid was the highest, and you are now the new owner of item. Below is some information and statistics about the auction:"
9
+ item:
10
+ title: "Auctioned item: <b>%{title}</b>"
11
+ winner_bid: "Your Winning Bid: %{winner_bid}"
12
+ auction_total_bids: "Total Number of Bids: %{auction_total_bids}"
13
+ auction_date: "Auction Date"
@@ -70,3 +70,12 @@ pt-BR:
70
70
  auction_context:
71
71
  create:
72
72
  finished_at: "deve ser depois da hora de início"
73
+ post_auction:
74
+ participant:
75
+ none: "não houve nenhuma participação deste usuário no leilão informado"
76
+ winner:
77
+ wrong: "não foi o vencedor deste leilão"
78
+ processor:
79
+ finish:
80
+ invalid_kind: "leilão com tipo inválido"
81
+ invalid_status: "leilão com status inválido"
@@ -0,0 +1,59 @@
1
+ pt-BR:
2
+ date:
3
+ abbr_day_names:
4
+ - Dom
5
+ - Seg
6
+ - Ter
7
+ - Qua
8
+ - Qui
9
+ - Sex
10
+ - Sáb
11
+ abbr_month_names:
12
+ -
13
+ - Jan
14
+ - Fev
15
+ - Mar
16
+ - Abr
17
+ - Mai
18
+ - Jun
19
+ - Jul
20
+ - Ago
21
+ - Set
22
+ - Out
23
+ - Nov
24
+ - Dez
25
+ day_names:
26
+ - Domingo
27
+ - Segunda-feira
28
+ - Terça-feira
29
+ - Quarta-feira
30
+ - Quinta-feira
31
+ - Sexta-feira
32
+ - Sábado
33
+ formats:
34
+ default: "%d/%m/%Y"
35
+ long: "%d de %B de %Y"
36
+ short: "%d de %B"
37
+ month_names:
38
+ -
39
+ - Janeiro
40
+ - Fevereiro
41
+ - Março
42
+ - Abril
43
+ - Maio
44
+ - Junho
45
+ - Julho
46
+ - Agosto
47
+ - Setembro
48
+ - Outubro
49
+ - Novembro
50
+ - Dezembro
51
+ order:
52
+ - :day
53
+ - :month
54
+ - :year
55
+ application:
56
+ general:
57
+ hello: "Olá %{name}"
58
+ app_name: "AuctionFun"
59
+ team: "Time AuctionFun"
@@ -0,0 +1,13 @@
1
+ pt-BR:
2
+ mail:
3
+ auction_context:
4
+ post_auction:
5
+ participant_mailer:
6
+ subject: "Sua participação no leilão %{title}"
7
+ body:
8
+ description: "Agradecemos por participar do leilão <b>%{title}</b>! Embora você não tenha sido o vencedor desta vez, gostaríamos de reconhecer o seu empenho e compartilhar algumas estatísticas do seu desempenho:"
9
+ stats:
10
+ auction_total_bids: "Total de lances do leilão: %{auction_total_bids}"
11
+ winner_bid: "Lance vencedor: %{winner_bid}"
12
+ auction_date: "Data do Leilão"
13
+ regards: "Esperamos que você tenha encontrado a experiência enriquecedora e convidamos você a participar de nossos futuros leilões. Acompanhe nosso site e redes sociais para ficar por dentro das próximas oportunidades."
@@ -0,0 +1,13 @@
1
+ pt-BR:
2
+ mail:
3
+ auction_context:
4
+ post_auction:
5
+ winner_mailer:
6
+ subject: "Parabéns! Você é o vencedor do leilão %{title}!"
7
+ body:
8
+ description: "Estamos muito felizes em informar que você foi o vencedor do leilão <b>%{title}</b>! Seu lance foi o maior, e agora você é o novo proprietário do item. Abaixo estão algumas informações e estatísticas sobre o leilão:"
9
+ item:
10
+ title: "Item Arrematado: <b>%{title}</b>"
11
+ winner_bid: "Seu Lance Vencedor: %{winner_bid}"
12
+ auction_total_bids: "Número Total de Lances: %{auction_total_bids}"
13
+ auction_date: "Data do Leilão"
@@ -1,9 +1,5 @@
1
1
  pt-BR:
2
2
  mail:
3
- general:
4
- hello: "Olá %{name}"
5
- app_name: "AuctionFun"
6
- team: "Time AuctionFun"
7
3
  user_context:
8
4
  registration:
9
5
  subject: "Bem vindo a AuctionFun"
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AuctionFunCore
4
+ module Contracts
5
+ module AuctionContext
6
+ module PostAuction
7
+ ##
8
+ # Contract class for validate participation auction.
9
+ #
10
+ class ParticipantContract < Contracts::ApplicationContract
11
+ I18N_SCOPE = "contracts.errors.custom.auction_context.post_auction.participation"
12
+
13
+ option :auction_repository, default: proc { Repos::AuctionContext::AuctionRepository.new }
14
+ option :user_repository, default: proc { Repos::UserContext::UserRepository.new }
15
+ option :bid_repository, default: proc { Repos::BidContext::BidRepository.new }
16
+
17
+ params do
18
+ required(:auction_id).filled(:integer)
19
+ required(:participant_id).filled(:integer)
20
+ end
21
+
22
+ rule(:auction_id) do |context:|
23
+ context[:auction] ||= auction_repository.by_id(value)
24
+ key.failure(I18n.t("contracts.errors.custom.not_found")) unless context[:auction]
25
+ end
26
+
27
+ rule(:participant_id) do |context:|
28
+ context[:participant] ||= user_repository.by_id(value)
29
+ key.failure(I18n.t("contracts.errors.custom.not_found")) unless context[:participant]
30
+ end
31
+
32
+ rule(:auction_id, :participant_id) do |context:|
33
+ next if (rule_error?(:auction_id) || schema_error?(:auction_id)) || (rule_error?(:winner_id) || schema_error?(:winner_id))
34
+ next if bid_repository.exists?(auction_id: values[:auction_id], user_id: values[:participant_id])
35
+
36
+ key(:participant_id).failure(I18n.t("none", scope: I18N_SCOPE))
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AuctionFunCore
4
+ module Contracts
5
+ module AuctionContext
6
+ module PostAuction
7
+ ##
8
+ # Contract class for validate winner auction.
9
+ #
10
+ class WinnerContract < Contracts::ApplicationContract
11
+ I18N_SCOPE = "contracts.errors.custom.auction_context.post_auction.winner"
12
+
13
+ option :auction_repository, default: proc { Repos::AuctionContext::AuctionRepository.new }
14
+ option :user_repository, default: proc { Repos::UserContext::UserRepository.new }
15
+
16
+ params do
17
+ required(:auction_id).filled(:integer)
18
+ required(:winner_id).filled(:integer)
19
+ end
20
+
21
+ rule(:auction_id) do |context:|
22
+ context[:auction] ||= auction_repository.by_id(value)
23
+ key.failure(I18n.t("contracts.errors.custom.not_found")) unless context[:auction]
24
+ end
25
+
26
+ rule(:winner_id) do |context:|
27
+ context[:winner] ||= user_repository.by_id(value)
28
+ key.failure(I18n.t("contracts.errors.custom.not_found")) unless context[:winner]
29
+ end
30
+
31
+ rule(:auction_id, :winner_id) do |context:|
32
+ next if (rule_error?(:auction_id) || schema_error?(:auction_id)) || (rule_error?(:winner_id) || schema_error?(:winner_id))
33
+ next if context[:auction].winner_id == values[:winner_id]
34
+
35
+ key(:winner_id).failure(I18n.t("wrong", scope: I18N_SCOPE))
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AuctionFunCore
4
+ module Contracts
5
+ module AuctionContext
6
+ module Processor
7
+ module Finish
8
+ ##
9
+ # Contract class for finishing closed auctions.
10
+ #
11
+ class ClosedContract < Contracts::ApplicationContract
12
+ I18N_SCOPE = "contracts.errors.custom.auction_context.processor.finish"
13
+
14
+ option :auction_repository, default: proc { Repos::AuctionContext::AuctionRepository.new }
15
+
16
+ params do
17
+ required(:auction_id).filled(:integer)
18
+ end
19
+
20
+ # Validation for auction.
21
+ # Validates if the auction exists in the database.
22
+ rule(:auction_id) do |context:|
23
+ context[:auction] ||= auction_repository.by_id(value)
24
+ key.failure(I18n.t("contracts.errors.custom.not_found")) unless context[:auction]
25
+ end
26
+
27
+ # Validation for kind.
28
+ #
29
+ rule do |context:|
30
+ next if context[:auction].present? && context[:auction].kind == "closed"
31
+
32
+ key(:base).failure(I18n.t("invalid_kind", scope: I18N_SCOPE))
33
+ end
34
+
35
+ # Validation for status.
36
+ #
37
+ rule do |context:|
38
+ next if context[:auction].present? && context[:auction].status == "running"
39
+
40
+ key(:base).failure(I18n.t("invalid_status", scope: I18N_SCOPE))
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AuctionFunCore
4
+ module Contracts
5
+ module AuctionContext
6
+ module Processor
7
+ module Finish
8
+ ##
9
+ # Contract class for finishing penny auctions.
10
+ #
11
+ class PennyContract < Contracts::ApplicationContract
12
+ I18N_SCOPE = "contracts.errors.custom.auction_context.processor.finish"
13
+
14
+ option :auction_repository, default: proc { Repos::AuctionContext::AuctionRepository.new }
15
+
16
+ params do
17
+ required(:auction_id).filled(:integer)
18
+ end
19
+
20
+ # Validation for auction.
21
+ # Validates if the auction exists in the database.
22
+ rule(:auction_id) do |context:|
23
+ context[:auction] ||= auction_repository.by_id(value)
24
+
25
+ key.failure(I18n.t("contracts.errors.custom.not_found")) unless context[:auction]
26
+ end
27
+
28
+ # Validation for kind.
29
+ #
30
+ rule do |context:|
31
+ next if context[:auction].present? && context[:auction].kind == "penny"
32
+
33
+ key(:base).failure(I18n.t("invalid_kind", scope: I18N_SCOPE))
34
+ end
35
+
36
+ # Validation for status.
37
+ #
38
+ rule do |context:|
39
+ next if context[:auction].present? && context[:auction].status == "running"
40
+
41
+ key(:base).failure(I18n.t("invalid_status", scope: I18N_SCOPE))
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AuctionFunCore
4
+ module Contracts
5
+ module AuctionContext
6
+ module Processor
7
+ module Finish
8
+ ##
9
+ # Contract class for finishing standard auctions.
10
+ #
11
+ class StandardContract < Contracts::ApplicationContract
12
+ I18N_SCOPE = "contracts.errors.custom.auction_context.processor.finish"
13
+
14
+ option :auction_repository, default: proc { Repos::AuctionContext::AuctionRepository.new }
15
+
16
+ params do
17
+ required(:auction_id).filled(:integer)
18
+ end
19
+
20
+ # Validation for auction.
21
+ # Validates if the auction exists in the database.
22
+ rule(:auction_id) do |context:|
23
+ context[:auction] ||= auction_repository.by_id(value)
24
+
25
+ key.failure(I18n.t("contracts.errors.custom.not_found")) unless context[:auction]
26
+ end
27
+
28
+ # Validation for kind.
29
+ #
30
+ rule do |context:|
31
+ next if context[:auction].present? && context[:auction].kind == "standard"
32
+
33
+ key(:base).failure(I18n.t("invalid_kind", scope: I18N_SCOPE))
34
+ end
35
+
36
+ # Validation for status.
37
+ #
38
+ rule do |context:|
39
+ next if context[:auction].present? && context[:auction].status == "running"
40
+
41
+ key(:base).failure(I18n.t("invalid_status", scope: I18N_SCOPE))
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end