auction_fun_core 0.8.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.editorconfig +12 -0
- data/.env.development.template +7 -0
- data/.env.test.template +7 -0
- data/.rspec +3 -0
- data/.standard.yml +3 -0
- data/.tool-versions +5 -0
- data/CHANGELOG.md +145 -0
- data/CODE_OF_CONDUCT.md +84 -0
- data/LICENSE.txt +21 -0
- data/Procfile +4 -0
- data/README.md +141 -0
- data/Rakefile +13 -0
- data/auction_fun_core.gemspec +57 -0
- data/config/app.rb +5 -0
- data/config/application.rb +37 -0
- data/config/boot.rb +15 -0
- data/db/migrate/20240216200926_enable_postgres_extensions.rb +13 -0
- data/db/migrate/20240217115734_create_users.rb +28 -0
- data/db/migrate/20240220140151_create_custom_types.rb +11 -0
- data/db/migrate/20240220140254_create_staffs.rb +20 -0
- data/db/migrate/20240229142933_create_custom_types.rb +13 -0
- data/db/migrate/20240229143000_create_auctions.rb +29 -0
- data/db/migrate/20240304144422_create_bids.rb +19 -0
- data/db/seeds.rb +116 -0
- data/i18n/en-US/contracts/contracts.en-US.yml +72 -0
- data/i18n/en-US/mail/user_context/registration.en-US.yml +11 -0
- data/i18n/pt-BR/contracts/contracts.pt-BR.yml +72 -0
- data/i18n/pt-BR/mail/user_context/registration.pt-BR.yml +12 -0
- data/lib/auction_fun_core/business/configuration.rb +18 -0
- data/lib/auction_fun_core/business/token_generator.rb +17 -0
- data/lib/auction_fun_core/commands/auction_context/create_auction.rb +19 -0
- data/lib/auction_fun_core/commands/auction_context/delete_auction.rb +15 -0
- data/lib/auction_fun_core/commands/auction_context/update_auction.rb +18 -0
- data/lib/auction_fun_core/commands/bid_context/create_bid.rb +19 -0
- data/lib/auction_fun_core/commands/bid_context/delete_bid.rb +15 -0
- data/lib/auction_fun_core/commands/bid_context/update_bid.rb +18 -0
- data/lib/auction_fun_core/commands/staff_context/create_staff.rb +19 -0
- data/lib/auction_fun_core/commands/user_context/create_user.rb +19 -0
- data/lib/auction_fun_core/contracts/application_contract.rb +55 -0
- data/lib/auction_fun_core/contracts/auction_context/create_contract.rb +101 -0
- data/lib/auction_fun_core/contracts/auction_context/processor/finish_contract.rb +27 -0
- data/lib/auction_fun_core/contracts/auction_context/processor/pause_contract.rb +34 -0
- data/lib/auction_fun_core/contracts/auction_context/processor/start_contract.rb +46 -0
- data/lib/auction_fun_core/contracts/auction_context/processor/unpause_contract.rb +34 -0
- data/lib/auction_fun_core/contracts/bid_context/create_bid_closed_contract.rb +79 -0
- data/lib/auction_fun_core/contracts/bid_context/create_bid_penny_contract.rb +69 -0
- data/lib/auction_fun_core/contracts/bid_context/create_bid_standard_contract.rb +68 -0
- data/lib/auction_fun_core/contracts/staff_context/authentication_contract.rb +47 -0
- data/lib/auction_fun_core/contracts/staff_context/registration_contract.rb +52 -0
- data/lib/auction_fun_core/contracts/user_context/authentication_contract.rb +47 -0
- data/lib/auction_fun_core/contracts/user_context/email_confirmation_contract.rb +40 -0
- data/lib/auction_fun_core/contracts/user_context/phone_confirmation_contract.rb +40 -0
- data/lib/auction_fun_core/contracts/user_context/registration_contract.rb +63 -0
- data/lib/auction_fun_core/entities/auction.rb +17 -0
- data/lib/auction_fun_core/entities/bid.rb +10 -0
- data/lib/auction_fun_core/entities/staff.rb +21 -0
- data/lib/auction_fun_core/entities/user.rb +37 -0
- data/lib/auction_fun_core/events/app.rb +27 -0
- data/lib/auction_fun_core/events/listener.rb +89 -0
- data/lib/auction_fun_core/operations/auction_context/create_operation.rb +77 -0
- data/lib/auction_fun_core/operations/auction_context/processor/finish_operation.rb +61 -0
- data/lib/auction_fun_core/operations/auction_context/processor/pause_operation.rb +57 -0
- data/lib/auction_fun_core/operations/auction_context/processor/start_operation.rb +84 -0
- data/lib/auction_fun_core/operations/auction_context/processor/unpause_operation.rb +57 -0
- data/lib/auction_fun_core/operations/base.rb +11 -0
- data/lib/auction_fun_core/operations/bid_context/create_bid_closed_operation.rb +64 -0
- data/lib/auction_fun_core/operations/bid_context/create_bid_penny_operation.rb +64 -0
- data/lib/auction_fun_core/operations/bid_context/create_bid_standard_operation.rb +74 -0
- data/lib/auction_fun_core/operations/staff_context/authentication_operation.rb +52 -0
- data/lib/auction_fun_core/operations/staff_context/registration_operation.rb +76 -0
- data/lib/auction_fun_core/operations/user_context/authentication_operation.rb +52 -0
- data/lib/auction_fun_core/operations/user_context/email_confirmation_operation.rb +67 -0
- data/lib/auction_fun_core/operations/user_context/phone_confirmation_operation.rb +67 -0
- data/lib/auction_fun_core/operations/user_context/registration_operation.rb +105 -0
- data/lib/auction_fun_core/relations/auctions.rb +119 -0
- data/lib/auction_fun_core/relations/bids.rb +28 -0
- data/lib/auction_fun_core/relations/staffs.rb +27 -0
- data/lib/auction_fun_core/relations/users.rb +26 -0
- data/lib/auction_fun_core/repos/auction_context/auction_repository.rb +42 -0
- data/lib/auction_fun_core/repos/bid_context/bid_repository.rb +27 -0
- data/lib/auction_fun_core/repos/staff_context/staff_repository.rb +64 -0
- data/lib/auction_fun_core/repos/user_context/user_repository.rb +78 -0
- data/lib/auction_fun_core/services/mail/templates/layout.html.erb +72 -0
- data/lib/auction_fun_core/services/mail/templates/user_context/registration.html.erb +170 -0
- data/lib/auction_fun_core/services/mail/user_context/registration_mailer.rb +25 -0
- data/lib/auction_fun_core/version.rb +8 -0
- data/lib/auction_fun_core/workers/application_job.rb +22 -0
- data/lib/auction_fun_core/workers/operations/auction_context/processor/finish_operation_job.rb +32 -0
- data/lib/auction_fun_core/workers/operations/auction_context/processor/start_operation_job.rb +32 -0
- data/lib/auction_fun_core/workers/services/mail/user_context/registration_mailer_job.rb +40 -0
- data/lib/auction_fun_core.rb +21 -0
- data/lib/tasks/database.rake +87 -0
- data/system/providers/background_job.rb +15 -0
- data/system/providers/core.rb +35 -0
- data/system/providers/db.rb +26 -0
- data/system/providers/events.rb +13 -0
- data/system/providers/logger.rb +11 -0
- data/system/providers/mail.rb +25 -0
- data/system/providers/persistence.rb +18 -0
- data/system/providers/settings.rb +26 -0
- metadata +400 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
ROM::SQL.migration do
|
|
4
|
+
change do
|
|
5
|
+
create_table(:auctions) do
|
|
6
|
+
primary_key :id
|
|
7
|
+
foreign_key :staff_id, :staffs, null: false
|
|
8
|
+
column :title, String, null: false
|
|
9
|
+
column :description, :text
|
|
10
|
+
column :kind, :auction_kinds, null: false
|
|
11
|
+
column :status, :auction_statuses, null: false
|
|
12
|
+
column :started_at, DateTime, null: false
|
|
13
|
+
column :finished_at, DateTime
|
|
14
|
+
column :stopwatch, Integer, null: false, default: 0
|
|
15
|
+
column :initial_bid_cents, Integer, null: false, default: 0
|
|
16
|
+
column :initial_bid_currency, String, null: false, default: "USD"
|
|
17
|
+
column :minimal_bid_cents, Integer, null: false, default: 0
|
|
18
|
+
column :minimal_bid_currency, String, null: false, default: "USD"
|
|
19
|
+
column :metadata, :jsonb, null: false, default: "{}"
|
|
20
|
+
column :statistics, :jsonb, null: false, default: "{}"
|
|
21
|
+
|
|
22
|
+
column :created_at, DateTime, null: false
|
|
23
|
+
column :updated_at, DateTime, null: false
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
add_index :auctions, %i[staff_id], name: "idx_admin"
|
|
27
|
+
add_index :auctions, %i[kind status], name: "idx_kind_status"
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
ROM::SQL.migration do
|
|
4
|
+
change do
|
|
5
|
+
create_table :bids do
|
|
6
|
+
primary_key :id
|
|
7
|
+
foreign_key :user_id, :users, null: false
|
|
8
|
+
foreign_key :auction_id, :auctions, null: false
|
|
9
|
+
|
|
10
|
+
column :value_cents, Integer, null: false, default: 0
|
|
11
|
+
column :value_currency, String, null: false, default: "USD"
|
|
12
|
+
|
|
13
|
+
column :created_at, DateTime, null: false
|
|
14
|
+
column :updated_at, DateTime, null: false
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
add_index :bids, %i[auction_id user_id], name: "idx_user_auction"
|
|
18
|
+
end
|
|
19
|
+
end
|
data/db/seeds.rb
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "pry"
|
|
4
|
+
require "faker"
|
|
5
|
+
|
|
6
|
+
I18n.enforce_available_locales = false
|
|
7
|
+
Faker::Config.locale = "pt-BR"
|
|
8
|
+
|
|
9
|
+
# Constants
|
|
10
|
+
STOPWATCH_OPTIONS = [15, 30, 45, 60].freeze
|
|
11
|
+
|
|
12
|
+
# Start application
|
|
13
|
+
AuctionFunCore::Application.start(:core)
|
|
14
|
+
|
|
15
|
+
# Instantiate repos
|
|
16
|
+
auction_repository = AuctionFunCore::Repos::AuctionContext::AuctionRepository.new
|
|
17
|
+
staff_repository = AuctionFunCore::Repos::StaffContext::StaffRepository.new
|
|
18
|
+
|
|
19
|
+
# Create root staff. Create as a regular user using the normal flow and after that
|
|
20
|
+
# just change the type directly in the db.
|
|
21
|
+
|
|
22
|
+
root_staff_attributes = {
|
|
23
|
+
kind: "root", name: "Root Bot", email: "rootbot@auctionfun.net",
|
|
24
|
+
phone: Faker::PhoneNumber.unique.cell_phone_in_e164,
|
|
25
|
+
password: "password", password_confirmation: "password"
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
AuctionFunCore::Operations::StaffContext::RegistrationOperation.call(root_staff_attributes) do |result|
|
|
29
|
+
result.failure { |failure| raise "Error to create root staff: #{failure}" }
|
|
30
|
+
result.success { |root| @root = root }
|
|
31
|
+
end
|
|
32
|
+
staff_repository.update(@root.id, kind: "root")
|
|
33
|
+
|
|
34
|
+
# Add common staff
|
|
35
|
+
|
|
36
|
+
common_staff_attributes = {
|
|
37
|
+
name: "Staff Bot", email: "staffbot@auctionfun.net",
|
|
38
|
+
phone: Faker::PhoneNumber.unique.cell_phone_in_e164,
|
|
39
|
+
password: "password", password_confirmation: "password"
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
AuctionFunCore::Operations::StaffContext::RegistrationOperation.call(common_staff_attributes) do |result|
|
|
43
|
+
result.failure { |failure| raise "Error to create common staff: #{failure}" }
|
|
44
|
+
result.success { |staff| @staff = staff }
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Create some standard auctions
|
|
48
|
+
(1..15).each do |i|
|
|
49
|
+
attributes = {
|
|
50
|
+
staff_id: @staff.id, title: Faker::Commerce.product_name, description: Faker::Lorem.paragraph_by_chars,
|
|
51
|
+
kind: "standard", started_at: i.hour.from_now, finished_at: i.day.from_now,
|
|
52
|
+
initial_bid_cents: (i * 100), minimal_bid_cents: (i * 100)
|
|
53
|
+
}
|
|
54
|
+
AuctionFunCore::Operations::AuctionContext::CreateOperation.call(attributes) do |result|
|
|
55
|
+
result.failure { |failure| raise "Error to create standard auction: #{failure}" }
|
|
56
|
+
result.success { |auction| puts "Create standard auction with: #{auction.to_h}" }
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Create some penny auctions
|
|
61
|
+
(1..10).each do |i|
|
|
62
|
+
stopwatch = STOPWATCH_OPTIONS.sample
|
|
63
|
+
started_at = i.hour.from_now
|
|
64
|
+
finished_at = started_at + stopwatch.seconds
|
|
65
|
+
|
|
66
|
+
attributes = {
|
|
67
|
+
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
|
|
69
|
+
}
|
|
70
|
+
AuctionFunCore::Operations::AuctionContext::CreateOperation.call(attributes) do |result|
|
|
71
|
+
result.failure { |failure| raise "Error to create penny auction: #{failure}" }
|
|
72
|
+
result.success { |auction| puts "Create penny auction with: #{auction.to_h}" }
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Create some closed auctions
|
|
77
|
+
(1..3).each do |i|
|
|
78
|
+
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,
|
|
81
|
+
initial_bid_cents: (i * 1000)
|
|
82
|
+
}
|
|
83
|
+
AuctionFunCore::Operations::AuctionContext::CreateOperation.call(attributes) do |result|
|
|
84
|
+
result.failure { |failure| raise "Error to create closed auction: #{failure}" }
|
|
85
|
+
result.success { |auction| puts "Create closed auction with: #{auction.to_h}" }
|
|
86
|
+
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
|
+
|
|
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}" }
|
|
115
|
+
end
|
|
116
|
+
end
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
en-US:
|
|
2
|
+
contracts:
|
|
3
|
+
errors:
|
|
4
|
+
or: "or"
|
|
5
|
+
array?: "must be an array"
|
|
6
|
+
empty?: "must be empty"
|
|
7
|
+
excludes?: "must not include %{value}"
|
|
8
|
+
excluded_from?:
|
|
9
|
+
arg:
|
|
10
|
+
default: "must not be one of: %{list}"
|
|
11
|
+
range: "must not be one of: %{list_left} - %{list_right}"
|
|
12
|
+
exclusion?: "must not be one of: %{list}"
|
|
13
|
+
eql?: "must be equal to %{left}"
|
|
14
|
+
not_eql?: "must not be equal to %{left}"
|
|
15
|
+
filled?: "must be filled"
|
|
16
|
+
format?: "is in invalid format"
|
|
17
|
+
number?: "must be a number"
|
|
18
|
+
odd?: "must be odd"
|
|
19
|
+
even?: "must be even"
|
|
20
|
+
gt?: "must be greater than %{num}"
|
|
21
|
+
gteq?: "must be greater than or equal to %{num}"
|
|
22
|
+
hash?: "must be a hash"
|
|
23
|
+
included_in?:
|
|
24
|
+
arg:
|
|
25
|
+
default: "must be one of: %{list}"
|
|
26
|
+
range: "must be one of: %{list_left} - %{list_right}"
|
|
27
|
+
inclusion?: "must be one of: %{list}"
|
|
28
|
+
includes?: "must include %{value}"
|
|
29
|
+
bool?: "must be boolean"
|
|
30
|
+
true?: "must be true"
|
|
31
|
+
false?: "must be false"
|
|
32
|
+
int?: "must be an integer"
|
|
33
|
+
float?: "must be a float"
|
|
34
|
+
decimal?: "must be a decimal"
|
|
35
|
+
date?: "must be a date"
|
|
36
|
+
date_time?: "must be a date time"
|
|
37
|
+
time?: "must be a time"
|
|
38
|
+
key?: "is required"
|
|
39
|
+
attr?: "is required"
|
|
40
|
+
lt?: "must be less than %{num}"
|
|
41
|
+
lteq?: "must be less than or equal to %{num}"
|
|
42
|
+
max_size?: "size cannot be greater than %{num}"
|
|
43
|
+
min_size?: "size cannot be less than %{num}"
|
|
44
|
+
none?: "cannot be defined"
|
|
45
|
+
str?: "must be a string"
|
|
46
|
+
type?: "must be %{type}"
|
|
47
|
+
size?:
|
|
48
|
+
arg:
|
|
49
|
+
default: "size must be %{size}"
|
|
50
|
+
range: "size must be within %{size_left} - %{size_right}"
|
|
51
|
+
value:
|
|
52
|
+
string:
|
|
53
|
+
arg:
|
|
54
|
+
default: "length must be %{size}"
|
|
55
|
+
range: "length must be within %{size_left} - %{size_right}"
|
|
56
|
+
custom:
|
|
57
|
+
default:
|
|
58
|
+
taken: "has already been taken"
|
|
59
|
+
not_found: "not found"
|
|
60
|
+
password_confirmation: "doesn't match password"
|
|
61
|
+
login_not_found: "Invalid credentials"
|
|
62
|
+
inactive_account: "Your account is suspended or inactive"
|
|
63
|
+
future: "must be in the future"
|
|
64
|
+
macro:
|
|
65
|
+
email_format: "need to be a valid email"
|
|
66
|
+
login_format: "invalid login"
|
|
67
|
+
name_format: "must be between %{min} and %{max} characters"
|
|
68
|
+
password_format: "must be between %{min} and %{max} characters"
|
|
69
|
+
phone_format: "need to be a valid mobile number"
|
|
70
|
+
auction_context:
|
|
71
|
+
create:
|
|
72
|
+
finished_at: "must be after started time"
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
en-US:
|
|
2
|
+
mail:
|
|
3
|
+
general:
|
|
4
|
+
hello: "Hi %{name}"
|
|
5
|
+
app_name: "AuctionFun"
|
|
6
|
+
team: "Team AuctionFun"
|
|
7
|
+
user_context:
|
|
8
|
+
registration:
|
|
9
|
+
subject: "Welcome to AuctionFun"
|
|
10
|
+
body:
|
|
11
|
+
description: "Welcome to our platform! We are delighted to have you on board. If you have any questions or need assistance, feel free to reach out."
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
pt-BR:
|
|
2
|
+
contracts:
|
|
3
|
+
errors:
|
|
4
|
+
or: "ou"
|
|
5
|
+
array?: "deve ser um array"
|
|
6
|
+
empty?: "deve ficar vazio"
|
|
7
|
+
excludes?: "não deve incluir %{value}"
|
|
8
|
+
excluded_from?:
|
|
9
|
+
arg:
|
|
10
|
+
default: "não deve ser um de: %{list}"
|
|
11
|
+
range: "não deve ser um de: %{list_left} - %{list_right}"
|
|
12
|
+
exclusion?: "não deve ser um de: %{list}"
|
|
13
|
+
eql?: "deve ser igual a %{left}"
|
|
14
|
+
not_eql?: "não deve ser igual a %{left}"
|
|
15
|
+
filled?: "deve ser preenchido"
|
|
16
|
+
format?: "está em formato inválido"
|
|
17
|
+
number?: "deve ser um número"
|
|
18
|
+
odd?: "deve ser ímpar"
|
|
19
|
+
even?: "deve ser par"
|
|
20
|
+
gt?: "deve ser maior que %{num}"
|
|
21
|
+
gteq?: "deve ser maior ou igual a %{num}"
|
|
22
|
+
hash?: "deve ser do tipo hash"
|
|
23
|
+
included_in?:
|
|
24
|
+
arg:
|
|
25
|
+
default: "deve ser um de: %{list}"
|
|
26
|
+
range: "deve ser um de: %{list_left} - %{list_right}"
|
|
27
|
+
inclusion?: "deve ser um de: %{list}"
|
|
28
|
+
includes?: "deve incluir %{value}"
|
|
29
|
+
bool?: "deve ser booleano"
|
|
30
|
+
true?: "deve ser verdadeiro"
|
|
31
|
+
false?: "deve ser falso"
|
|
32
|
+
int?: "deve ser um número inteiro"
|
|
33
|
+
float?: "deve ser um número real"
|
|
34
|
+
decimal?: "deve ser um número decimal"
|
|
35
|
+
date?: "deve ser no formato de data"
|
|
36
|
+
date_time?: "deve ser no formato de data e hora"
|
|
37
|
+
time?: "deve ser no formato de tempo"
|
|
38
|
+
key?: "é requerido"
|
|
39
|
+
attr?: "é requerido"
|
|
40
|
+
lt?: "deve ser menor que %{num}"
|
|
41
|
+
lteq?: "deve ser menor ou igual a %{num}"
|
|
42
|
+
max_size?: "tamanho não pode ser maior que %{num}"
|
|
43
|
+
min_size?: "tamanho não pode ser menor que %{num}"
|
|
44
|
+
none?: "não pode ser definido"
|
|
45
|
+
str?: "deve ser do tipo texto"
|
|
46
|
+
type?: "deve ser do tipo %{type}"
|
|
47
|
+
size?:
|
|
48
|
+
arg:
|
|
49
|
+
default: "tamanho deve ser %{size}"
|
|
50
|
+
range: "tamanho deve ser entre %{size_left} e %{size_right}"
|
|
51
|
+
value:
|
|
52
|
+
string:
|
|
53
|
+
arg:
|
|
54
|
+
default: "deve ser %{size} caracteres"
|
|
55
|
+
range: "deve ser entre %{size_left} e %{size_right} caracteres"
|
|
56
|
+
custom:
|
|
57
|
+
default:
|
|
58
|
+
taken: "não está disponível"
|
|
59
|
+
not_found: "não encontrado"
|
|
60
|
+
password_confirmation: "não corresponde à senha"
|
|
61
|
+
login_not_found: "Credenciais inválidas"
|
|
62
|
+
inactive_account: "Sua conta está suspensa ou inativa"
|
|
63
|
+
future: "deve ser no futuro"
|
|
64
|
+
macro:
|
|
65
|
+
email_format: "não é um email válido"
|
|
66
|
+
login_format: "login inválido"
|
|
67
|
+
name_format: "deve ter entre %{min} e %{max} caracteres"
|
|
68
|
+
password_format: "deve ter entre %{min} e %{max} caracteres"
|
|
69
|
+
phone_format: "não é um número de celular válido"
|
|
70
|
+
auction_context:
|
|
71
|
+
create:
|
|
72
|
+
finished_at: "deve ser depois da hora de início"
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
pt-BR:
|
|
2
|
+
mail:
|
|
3
|
+
general:
|
|
4
|
+
hello: "Olá %{name}"
|
|
5
|
+
app_name: "AuctionFun"
|
|
6
|
+
team: "Time AuctionFun"
|
|
7
|
+
user_context:
|
|
8
|
+
registration:
|
|
9
|
+
subject: "Bem vindo a AuctionFun"
|
|
10
|
+
body:
|
|
11
|
+
description: "Bem-vindo/a à nossa plataforma! Estamos encantados por tê-lo/a conosco. Se tiver alguma dúvida ou precisar de ajuda, não hesite em entrar em contato."
|
|
12
|
+
email_confirmation_token: "Esse é o seu token de confirmação: <b>%{token}</b>"
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module AuctionFunCore
|
|
4
|
+
module Business
|
|
5
|
+
module Configuration
|
|
6
|
+
AUCTION_KINDS = Relations::Auctions::KINDS.values
|
|
7
|
+
AUCTION_STATUSES = Relations::Auctions::STATUSES.values
|
|
8
|
+
AUCTION_MIN_TITLE_LENGTH = 6
|
|
9
|
+
AUCTION_MAX_TITLE_LENGTH = 255
|
|
10
|
+
AUCTION_STOPWATCH_MIN_VALUE = 15
|
|
11
|
+
AUCTION_STOPWATCH_MAX_VALUE = 60
|
|
12
|
+
MIN_NAME_LENGTH = 6
|
|
13
|
+
MAX_NAME_LENGTH = 128
|
|
14
|
+
MIN_PASSWORD_LENGTH = 6
|
|
15
|
+
MAX_PASSWORD_LENGTH = 128
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module AuctionFunCore
|
|
4
|
+
module Business
|
|
5
|
+
# Responsible for generating interaction tokens with system users for general operations.
|
|
6
|
+
module TokenGenerator
|
|
7
|
+
def self.generate_email_token(length = 20)
|
|
8
|
+
rlength = (length * 3) / 4
|
|
9
|
+
SecureRandom.urlsafe_base64(rlength).tr("lIO0", "sxyz")
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def self.generate_phone_token(length = 6)
|
|
13
|
+
rand(0o00000..999_999).to_s.rjust(length, "0")
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module AuctionFunCore
|
|
4
|
+
module Commands
|
|
5
|
+
module AuctionContext
|
|
6
|
+
##
|
|
7
|
+
# Abstract base class for insert new tuples on auctions table.
|
|
8
|
+
# @abstract
|
|
9
|
+
class CreateAuction < ROM::Commands::Create[:sql]
|
|
10
|
+
relation :auctions
|
|
11
|
+
register_as :create
|
|
12
|
+
result :one
|
|
13
|
+
|
|
14
|
+
use :timestamps
|
|
15
|
+
timestamp :created_at, :updated_at
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module AuctionFunCore
|
|
4
|
+
module Commands
|
|
5
|
+
module AuctionContext
|
|
6
|
+
##
|
|
7
|
+
# Abstract base class for removes tuples in auctions table.
|
|
8
|
+
# @abstract
|
|
9
|
+
class DeleteAuction < ROM::Commands::Delete[:sql]
|
|
10
|
+
relation :auctions
|
|
11
|
+
register_as :delete
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module AuctionFunCore
|
|
4
|
+
module Commands
|
|
5
|
+
module AuctionContext
|
|
6
|
+
##
|
|
7
|
+
# Abstract base class for updates all tuples in its auctions table with new attributes
|
|
8
|
+
# @abstract
|
|
9
|
+
class UpdateAuction < ROM::Commands::Update[:sql]
|
|
10
|
+
relation :auctions
|
|
11
|
+
register_as :update
|
|
12
|
+
|
|
13
|
+
use :timestamps
|
|
14
|
+
timestamp :updated_at
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module AuctionFunCore
|
|
4
|
+
module Commands
|
|
5
|
+
module BidContext
|
|
6
|
+
##
|
|
7
|
+
# Abstract base class for insert new tuples on bids table.
|
|
8
|
+
# @abstract
|
|
9
|
+
class CreateBid < ROM::Commands::Create[:sql]
|
|
10
|
+
relation :bids
|
|
11
|
+
register_as :create
|
|
12
|
+
result :one
|
|
13
|
+
|
|
14
|
+
use :timestamps
|
|
15
|
+
timestamp :created_at, :updated_at
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module AuctionFunCore
|
|
4
|
+
module Commands
|
|
5
|
+
module BidContext
|
|
6
|
+
##
|
|
7
|
+
# Abstract base class for removes tuples in bids table.
|
|
8
|
+
# @abstract
|
|
9
|
+
class DeleteBid < ROM::Commands::Delete[:sql]
|
|
10
|
+
relation :bids
|
|
11
|
+
register_as :delete
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module AuctionFunCore
|
|
4
|
+
module Commands
|
|
5
|
+
module BidContext
|
|
6
|
+
##
|
|
7
|
+
# Abstract base class for updates all tuples in its bids table with new attributes
|
|
8
|
+
# @abstract
|
|
9
|
+
class UpdateBid < ROM::Commands::Update[:sql]
|
|
10
|
+
relation :bids
|
|
11
|
+
register_as :update
|
|
12
|
+
|
|
13
|
+
use :timestamps
|
|
14
|
+
timestamp :updated_at
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module AuctionFunCore
|
|
4
|
+
module Commands
|
|
5
|
+
module StaffContext
|
|
6
|
+
##
|
|
7
|
+
# Abstract base class for insert new tuples on staffs table.
|
|
8
|
+
# @abstract
|
|
9
|
+
class CreateStaff < ROM::Commands::Create[:sql]
|
|
10
|
+
relation :staffs
|
|
11
|
+
register_as :create
|
|
12
|
+
result :one
|
|
13
|
+
|
|
14
|
+
use :timestamps
|
|
15
|
+
timestamp :created_at, :updated_at
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module AuctionFunCore
|
|
4
|
+
module Commands
|
|
5
|
+
module UserContext
|
|
6
|
+
##
|
|
7
|
+
# Abstract base class for insert new tuples on users table.
|
|
8
|
+
# @abstract
|
|
9
|
+
class CreateUser < ROM::Commands::Create[:sql]
|
|
10
|
+
relation :users
|
|
11
|
+
register_as :create
|
|
12
|
+
result :one
|
|
13
|
+
|
|
14
|
+
use :timestamps
|
|
15
|
+
timestamp :created_at, :updated_at
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "phonelib"
|
|
4
|
+
|
|
5
|
+
module AuctionFunCore
|
|
6
|
+
module Contracts
|
|
7
|
+
# Abstract base class for contracts.
|
|
8
|
+
# @abstract
|
|
9
|
+
class ApplicationContract < Dry::Validation::Contract
|
|
10
|
+
include AuctionFunCore::Business::Configuration
|
|
11
|
+
|
|
12
|
+
I18N_MACRO_SCOPE = "contracts.errors.custom.macro"
|
|
13
|
+
EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d-]+(\.[a-z\d-]+)*\.[a-z]+\z/i
|
|
14
|
+
|
|
15
|
+
config.messages.backend = :i18n
|
|
16
|
+
config.messages.default_locale = I18n.default_locale
|
|
17
|
+
config.messages.top_namespace = "contracts"
|
|
18
|
+
config.messages.load_paths << Application.root.join("i18n/#{I18n.default_locale}/contracts/contracts.#{I18n.default_locale}.yml").to_s
|
|
19
|
+
|
|
20
|
+
register_macro(:email_format) do
|
|
21
|
+
next if EMAIL_REGEX.match?(value)
|
|
22
|
+
|
|
23
|
+
key.failure(I18n.t(:email_format, scope: I18N_MACRO_SCOPE))
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
register_macro(:login_format) do
|
|
27
|
+
next if EMAIL_REGEX.match?(value) || Phonelib.parse(value).valid?
|
|
28
|
+
|
|
29
|
+
key.failure(I18n.t(:login_format, scope: I18N_MACRO_SCOPE))
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
register_macro(:name_format) do
|
|
33
|
+
next if value.length.between?(MIN_NAME_LENGTH, MAX_NAME_LENGTH)
|
|
34
|
+
|
|
35
|
+
key.failure(
|
|
36
|
+
I18n.t(:name_format, scope: I18N_MACRO_SCOPE, min: MIN_NAME_LENGTH, max: MAX_NAME_LENGTH)
|
|
37
|
+
)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
register_macro(:phone_format) do
|
|
41
|
+
next if ::Phonelib.parse(value).valid?
|
|
42
|
+
|
|
43
|
+
key.failure(I18n.t(:phone_format, scope: I18N_MACRO_SCOPE))
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
register_macro(:password_format) do
|
|
47
|
+
next if value.length.between?(MIN_PASSWORD_LENGTH, MAX_PASSWORD_LENGTH)
|
|
48
|
+
|
|
49
|
+
key.failure(
|
|
50
|
+
I18n.t(:password_format, scope: I18N_MACRO_SCOPE, min: MIN_PASSWORD_LENGTH, max: MAX_PASSWORD_LENGTH)
|
|
51
|
+
)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|