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,119 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module AuctionFunCore
|
|
4
|
+
module Relations
|
|
5
|
+
# SQL relation for auctions.
|
|
6
|
+
# @see https://rom-rb.org/5.0/learn/sql/relations/
|
|
7
|
+
class Auctions < ROM::Relation[:sql]
|
|
8
|
+
use :pagination, per_page: 10
|
|
9
|
+
|
|
10
|
+
KINDS = Types::Coercible::String.default("standard").enum("standard", "penny", "closed")
|
|
11
|
+
STATUSES = Types::Coercible::String.default("scheduled")
|
|
12
|
+
.enum("scheduled", "running", "paused", "canceled", "finished")
|
|
13
|
+
|
|
14
|
+
schema(:auctions, infer: true) do
|
|
15
|
+
attribute :id, Types::Integer
|
|
16
|
+
attribute :staff_id, Types::ForeignKey(:staffs)
|
|
17
|
+
attribute :title, Types::String
|
|
18
|
+
attribute :description, Types::String
|
|
19
|
+
attribute :kind, KINDS
|
|
20
|
+
attribute :status, STATUSES
|
|
21
|
+
attribute :started_at, Types::DateTime
|
|
22
|
+
attribute :finished_at, Types::DateTime
|
|
23
|
+
attribute :stopwatch, Types::Integer
|
|
24
|
+
attribute :initial_bid_cents, Types::Integer
|
|
25
|
+
attribute :initial_bid_currency, Types::String
|
|
26
|
+
attribute :minimal_bid_cents, Types::Integer
|
|
27
|
+
attribute :minimal_bid_currency, Types::String
|
|
28
|
+
|
|
29
|
+
attribute :metadata, Types::PG::JSONB
|
|
30
|
+
attribute :statistics, Types::PG::JSONB
|
|
31
|
+
primary_key :id
|
|
32
|
+
|
|
33
|
+
associations do
|
|
34
|
+
belongs_to :staff, as: :staff, relation: :staffs
|
|
35
|
+
has_many :bids, as: :bids, relation: :bids
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
struct_namespace Entities
|
|
40
|
+
auto_struct(true)
|
|
41
|
+
|
|
42
|
+
def all(page = 1, per_page = 10, options = {bidders_count: 3})
|
|
43
|
+
offset = ((page - 1) * per_page)
|
|
44
|
+
|
|
45
|
+
read(all_auctions_with_bid_info(per_page, offset, options))
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def info(auction_id, options = {bidders_count: 3})
|
|
49
|
+
raise "Invalid argument" unless auction_id.is_a?(Integer)
|
|
50
|
+
|
|
51
|
+
read(auction_with_bid_info(auction_id, options))
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
private
|
|
55
|
+
|
|
56
|
+
def auction_with_bid_info(auction_id, options = {bidders_count: 3})
|
|
57
|
+
"SELECT a.id, a.title, a.description, a.kind, a.status, a.started_at, a.finished_at, a.stopwatch, a.initial_bid_cents,
|
|
58
|
+
(SELECT COUNT(*) FROM (SELECT * FROM bids WHERE bids.auction_id = #{auction_id}) dt) AS total_bids,
|
|
59
|
+
CASE
|
|
60
|
+
WHEN a.kind = 'standard' THEN
|
|
61
|
+
json_build_object(
|
|
62
|
+
'current', a.minimal_bid_cents,
|
|
63
|
+
'minimal', a.minimal_bid_cents,
|
|
64
|
+
'bidders', COALESCE(
|
|
65
|
+
json_agg(json_build_object('id', bi.id, 'user_id', users.id, 'name', users.name, 'value', bi.value_cents, 'date', bi.created_at) ORDER BY value_cents DESC)
|
|
66
|
+
FILTER (where bi.id IS NOT NULL AND users.id IS NOT NULL), '[]'::json
|
|
67
|
+
)
|
|
68
|
+
)
|
|
69
|
+
WHEN a.kind = 'penny' THEN
|
|
70
|
+
json_build_object(
|
|
71
|
+
'value', a.initial_bid_cents,
|
|
72
|
+
'bidders', COALESCE(
|
|
73
|
+
json_agg(json_build_object('id', bi.id, 'user_id', users.id, 'name', users.name, 'value', bi.value_cents, 'date', bi.created_at) ORDER BY value_cents DESC)
|
|
74
|
+
FILTER (where bi.id IS NOT NULL AND users.id IS NOT NULL), '[]'::json
|
|
75
|
+
)
|
|
76
|
+
)
|
|
77
|
+
WHEN a.kind = 'closed' THEN
|
|
78
|
+
json_build_object('minimal', (a.initial_bid_cents + (a.initial_bid_cents * 0.10))::int)
|
|
79
|
+
END as bids
|
|
80
|
+
FROM auctions as a
|
|
81
|
+
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}
|
|
82
|
+
LEFT JOIN users ON bi.user_id = users.id AND bi.auction_id = a.id
|
|
83
|
+
WHERE a.id = #{auction_id}
|
|
84
|
+
GROUP BY a.id"
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def all_auctions_with_bid_info(per_page, offset, options = {bidders_count: 3})
|
|
88
|
+
"SELECT a.id, a.title, a.description, a.kind, a.status, a.started_at, a.finished_at, a.stopwatch, a.initial_bid_cents,
|
|
89
|
+
(SELECT COUNT(*) FROM (SELECT * FROM bids WHERE bids.auction_id = a.id) dt) AS total_bids,
|
|
90
|
+
CASE
|
|
91
|
+
WHEN a.kind = 'standard' THEN
|
|
92
|
+
json_build_object(
|
|
93
|
+
'current', a.minimal_bid_cents,
|
|
94
|
+
'minimal', a.minimal_bid_cents,
|
|
95
|
+
'bidders', COALESCE(
|
|
96
|
+
json_agg(json_build_object('id', bi.id, 'user_id', users.id, 'name', users.name, 'value', bi.value_cents, 'date', bi.created_at) ORDER BY value_cents DESC)
|
|
97
|
+
FILTER (where bi.id IS NOT NULL AND users.id IS NOT NULL), '[]'::json
|
|
98
|
+
)
|
|
99
|
+
)
|
|
100
|
+
WHEN a.kind = 'penny' THEN
|
|
101
|
+
json_build_object(
|
|
102
|
+
'value', a.initial_bid_cents,
|
|
103
|
+
'bidders', COALESCE(
|
|
104
|
+
json_agg(json_build_object('id', bi.id, 'user_id', users.id, 'name', users.name, 'value', bi.value_cents, 'date', bi.created_at) ORDER BY value_cents DESC)
|
|
105
|
+
FILTER (where bi.id IS NOT NULL AND users.id IS NOT NULL), '[]'::json
|
|
106
|
+
)
|
|
107
|
+
)
|
|
108
|
+
WHEN a.kind = 'closed' THEN
|
|
109
|
+
json_build_object('minimal', (a.initial_bid_cents + (a.initial_bid_cents * 0.10))::int)
|
|
110
|
+
END as bids
|
|
111
|
+
FROM auctions as a
|
|
112
|
+
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
|
|
113
|
+
LEFT JOIN users ON bi.user_id = users.id AND bi.auction_id = a.id
|
|
114
|
+
GROUP BY a.id
|
|
115
|
+
LIMIT #{per_page} OFFSET #{offset}"
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module AuctionFunCore
|
|
4
|
+
module Relations
|
|
5
|
+
# SQL relation for bids
|
|
6
|
+
# @see https://rom-rb.org/5.0/learn/sql/relations/
|
|
7
|
+
class Bids < ROM::Relation[:sql]
|
|
8
|
+
use :pagination, per_page: 3
|
|
9
|
+
|
|
10
|
+
schema(:bids, infer: true) do
|
|
11
|
+
attribute :id, Types::Integer
|
|
12
|
+
|
|
13
|
+
attribute :auction_id, Types::ForeignKey(:auctions)
|
|
14
|
+
attribute :user_id, Types::ForeignKey(:users)
|
|
15
|
+
|
|
16
|
+
associations do
|
|
17
|
+
belongs_to :auction
|
|
18
|
+
belongs_to :user
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
primary_key :id
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
struct_namespace Entities
|
|
25
|
+
auto_struct(true)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module AuctionFunCore
|
|
4
|
+
module Relations
|
|
5
|
+
# SQL relation for staffs.
|
|
6
|
+
# @see https://rom-rb.org/5.0/learn/sql/relations/
|
|
7
|
+
class Staffs < ROM::Relation[:sql]
|
|
8
|
+
use :pagination, per_page: 10
|
|
9
|
+
|
|
10
|
+
STAFF_KINDS = Types::Coercible::String.default("common").enum("root", "common")
|
|
11
|
+
|
|
12
|
+
schema(:staffs, infer: true) do
|
|
13
|
+
attribute :id, Types::Integer
|
|
14
|
+
attribute :name, Types::String
|
|
15
|
+
attribute :email, Types::String
|
|
16
|
+
attribute :phone, Types::String
|
|
17
|
+
attribute :kind, STAFF_KINDS
|
|
18
|
+
attribute :active, Types::Bool
|
|
19
|
+
|
|
20
|
+
primary_key :id
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
struct_namespace Entities
|
|
24
|
+
auto_struct(true)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module AuctionFunCore
|
|
4
|
+
module Relations
|
|
5
|
+
# SQL relation for users.
|
|
6
|
+
# @see https://rom-rb.org/5.0/learn/sql/relations/
|
|
7
|
+
class Users < ROM::Relation[:sql]
|
|
8
|
+
use :pagination, per_page: 10
|
|
9
|
+
|
|
10
|
+
schema(:users, infer: true) do
|
|
11
|
+
attribute :id, Types::Integer
|
|
12
|
+
attribute :name, Types::String
|
|
13
|
+
attribute :email, Types::String
|
|
14
|
+
attribute :phone, Types::String
|
|
15
|
+
attribute :active, Types::Bool
|
|
16
|
+
attribute :balance_cents, Types::Integer
|
|
17
|
+
attribute :balance_currency, Types::String
|
|
18
|
+
|
|
19
|
+
primary_key :id
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
struct_namespace Entities
|
|
23
|
+
auto_struct(true)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module AuctionFunCore
|
|
4
|
+
module Repos
|
|
5
|
+
module AuctionContext
|
|
6
|
+
# SQL repository for auctions.
|
|
7
|
+
class AuctionRepository < ROM::Repository[:auctions]
|
|
8
|
+
include Import["container"]
|
|
9
|
+
|
|
10
|
+
struct_namespace Entities
|
|
11
|
+
commands :create, update: :by_pk, delete: :by_pk
|
|
12
|
+
|
|
13
|
+
# Returns all auctions in the database.
|
|
14
|
+
# @return [Array<ROM::Struct::Auction>, []]
|
|
15
|
+
def all
|
|
16
|
+
auctions.to_a
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Returns the total number of auctions in database.
|
|
20
|
+
# @return [Integer]
|
|
21
|
+
def count
|
|
22
|
+
auctions.count
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Search auction in database by primary key.
|
|
26
|
+
# @param id [Integer] Auction ID
|
|
27
|
+
# @return [ROM::Struct::Auction, nil]
|
|
28
|
+
def by_id(id)
|
|
29
|
+
auctions.by_pk(id).one
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Search auction in database by primary key.
|
|
33
|
+
# @param id [Integer] Auction ID
|
|
34
|
+
# @raise [ROM::TupleCountMismatchError] if not found on database
|
|
35
|
+
# @return [ROM::Struct::Auction]
|
|
36
|
+
def by_id!(id)
|
|
37
|
+
auctions.by_pk(id).one!
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module AuctionFunCore
|
|
4
|
+
module Repos
|
|
5
|
+
module BidContext
|
|
6
|
+
# SQL repository for bids.
|
|
7
|
+
class BidRepository < ROM::Repository[:bids]
|
|
8
|
+
include Import["container"]
|
|
9
|
+
|
|
10
|
+
struct_namespace Entities
|
|
11
|
+
commands :create, update: :by_pk, delete: :by_pk
|
|
12
|
+
|
|
13
|
+
# Returns the total number of bids in database.
|
|
14
|
+
# @return [Integer]
|
|
15
|
+
def count
|
|
16
|
+
bids.count
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# @param conditions [Hash] DSL Dataset
|
|
20
|
+
# @return [Boolean]
|
|
21
|
+
def exists?(conditions)
|
|
22
|
+
bids.exist?(conditions)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module AuctionFunCore
|
|
4
|
+
module Repos
|
|
5
|
+
module StaffContext
|
|
6
|
+
# SQL repository for staffs.
|
|
7
|
+
class StaffRepository < ROM::Repository[:staffs]
|
|
8
|
+
include Import["container"]
|
|
9
|
+
|
|
10
|
+
struct_namespace Entities
|
|
11
|
+
commands :create, update: :by_pk, delete: :by_pk
|
|
12
|
+
|
|
13
|
+
# Returns all staffs in database.
|
|
14
|
+
# @return [Array<ROM::Struct::Staff>, []]
|
|
15
|
+
def all
|
|
16
|
+
staffs.to_a
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Returns the total number of staffs in database.
|
|
20
|
+
# @return [Integer]
|
|
21
|
+
def count
|
|
22
|
+
staffs.count
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Mount SQL conditions in query for search in database.
|
|
26
|
+
# @param conditions [Hash] DSL Dataset
|
|
27
|
+
# @return [AuctionFunCore::Relations::Staffs]
|
|
28
|
+
def query(conditions)
|
|
29
|
+
staffs.where(conditions)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Search staff in database by primary key.
|
|
33
|
+
# @param id [Integer] Staff ID
|
|
34
|
+
# @return [ROM::Struct::Staff, nil]
|
|
35
|
+
def by_id(id)
|
|
36
|
+
staffs.by_pk(id).one
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Search staffs in database by primary key.
|
|
40
|
+
# @param id [Integer] Staff ID
|
|
41
|
+
# @raise [ROM::TupleCountMismatchError] if not found on database
|
|
42
|
+
# @return [ROM::Struct::Auction]
|
|
43
|
+
def by_id!(id)
|
|
44
|
+
staffs.by_pk(id).one!
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Search staff in database by email of phone keys.
|
|
48
|
+
# @param login [String] Staff email or phone
|
|
49
|
+
# @return [ROM::Struct::Staff, nil]
|
|
50
|
+
def by_login(login)
|
|
51
|
+
staffs.where(Sequel[email: login] | Sequel[phone: login]).one
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Checks if it returns any staff given one or more conditions.
|
|
55
|
+
# @param conditions [Hash] DSL Dataset
|
|
56
|
+
# @return [true] when some staff is returned from the given condition.
|
|
57
|
+
# @return [false] when no staff is returned from the given condition.
|
|
58
|
+
def exists?(conditions)
|
|
59
|
+
staffs.exist?(conditions)
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module AuctionFunCore
|
|
4
|
+
module Repos
|
|
5
|
+
module UserContext
|
|
6
|
+
# SQL repository for users.
|
|
7
|
+
class UserRepository < ROM::Repository[:users]
|
|
8
|
+
include Import["container"]
|
|
9
|
+
|
|
10
|
+
struct_namespace Entities
|
|
11
|
+
commands :create, update: :by_pk, delete: :by_pk
|
|
12
|
+
|
|
13
|
+
# Returns all users in database.
|
|
14
|
+
# @return [Array<ROM::Struct::User>, []]
|
|
15
|
+
def all
|
|
16
|
+
users.to_a
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Returns the total number of users in database.
|
|
20
|
+
# @return [Integer]
|
|
21
|
+
def count
|
|
22
|
+
users.count
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Mount SQL conditions in query for search in database.
|
|
26
|
+
# @param conditions [Hash] DSL Dataset
|
|
27
|
+
# @return [AuctionFunCore::Relations::Users]
|
|
28
|
+
def query(conditions)
|
|
29
|
+
users.where(conditions)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Search user in database by primary key.
|
|
33
|
+
# @param id [Integer] User ID
|
|
34
|
+
# @return [ROM::Struct::User, nil]
|
|
35
|
+
def by_id(id)
|
|
36
|
+
users.by_pk(id).one
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Search user in database by primary key.
|
|
40
|
+
# @param id [Integer] User ID
|
|
41
|
+
# @raise [ROM::TupleCountMismatchError] if not found on database
|
|
42
|
+
# @return [ROM::Struct::Auction]
|
|
43
|
+
def by_id!(id)
|
|
44
|
+
users.by_pk(id).one!
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Search user in database by email of phone keys.
|
|
48
|
+
# @param login [String] User email or phone
|
|
49
|
+
# @return [ROM::Struct::User, nil]
|
|
50
|
+
def by_login(login)
|
|
51
|
+
users.where(Sequel[email: login] | Sequel[phone: login]).one
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Search user in database by email_confirmation_token key.
|
|
55
|
+
# @param email_confirmation_token [String] User email confirmation token
|
|
56
|
+
# @return [ROM::Struct::User, nil]
|
|
57
|
+
def by_email_confirmation_token(email_confirmation_token)
|
|
58
|
+
users.where(Sequel[email_confirmation_token: email_confirmation_token]).one
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Search user in database by phone_confirmation_token of phone keys.
|
|
62
|
+
# @param phone [String] User phone confirmation token
|
|
63
|
+
# @return [ROM::Struct::User, nil]
|
|
64
|
+
def by_phone_confirmation_token(phone_confirmation_token)
|
|
65
|
+
users.where(Sequel[phone_confirmation_token: phone_confirmation_token]).one
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Checks if it returns any user given one or more conditions.
|
|
69
|
+
# @param conditions [Hash] DSL Dataset
|
|
70
|
+
# @return [true] when some user is returned from the given condition.
|
|
71
|
+
# @return [false] when no user is returned from the given condition.
|
|
72
|
+
def exists?(conditions)
|
|
73
|
+
users.exist?(conditions)
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office">
|
|
3
|
+
<head>
|
|
4
|
+
<title>AuctionFun</title>
|
|
5
|
+
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
|
6
|
+
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
|
7
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
8
|
+
<style type="text/css">
|
|
9
|
+
#outlook a {
|
|
10
|
+
padding: 0;
|
|
11
|
+
}
|
|
12
|
+
body {
|
|
13
|
+
margin: 0;
|
|
14
|
+
padding: 0;
|
|
15
|
+
-webkit-text-size-adjust: 100%;
|
|
16
|
+
-ms-text-size-adjust: 100%;
|
|
17
|
+
}
|
|
18
|
+
table,
|
|
19
|
+
td {
|
|
20
|
+
border-collapse: collapse;
|
|
21
|
+
mso-table-lspace: 0pt;
|
|
22
|
+
mso-table-rspace: 0pt;
|
|
23
|
+
}
|
|
24
|
+
img {
|
|
25
|
+
border: 0;
|
|
26
|
+
height: auto;
|
|
27
|
+
line-height: 100%;
|
|
28
|
+
outline: none;
|
|
29
|
+
text-decoration: none;
|
|
30
|
+
-ms-interpolation-mode: bicubic;
|
|
31
|
+
}
|
|
32
|
+
p {
|
|
33
|
+
display: block;
|
|
34
|
+
margin: 13px 0;
|
|
35
|
+
}
|
|
36
|
+
</style>
|
|
37
|
+
<style type="text/css">
|
|
38
|
+
.mj-outlook-group-fix { width:100% !important; }
|
|
39
|
+
</style>
|
|
40
|
+
<style type="text/css">
|
|
41
|
+
@media only screen and (min-width:480px) {
|
|
42
|
+
.mj-column-per-100 {
|
|
43
|
+
width: 100% !important;
|
|
44
|
+
max-width: 100%;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
</style>
|
|
48
|
+
<style type="text/css">
|
|
49
|
+
@media only screen and (max-width:480px) {
|
|
50
|
+
table.mj-full-width-mobile {
|
|
51
|
+
width: 100% !important;
|
|
52
|
+
}
|
|
53
|
+
td.mj-full-width-mobile {
|
|
54
|
+
width: auto !important;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
</style>
|
|
58
|
+
<style type="text/css">
|
|
59
|
+
a,
|
|
60
|
+
span,
|
|
61
|
+
td,
|
|
62
|
+
th {
|
|
63
|
+
-webkit-font-smoothing: antialiased !important;
|
|
64
|
+
-moz-osx-font-smoothing: grayscale !important;
|
|
65
|
+
}
|
|
66
|
+
</style>
|
|
67
|
+
</head>
|
|
68
|
+
<body style="background-color:#ffffff;">
|
|
69
|
+
<%= yield %>
|
|
70
|
+
</div>
|
|
71
|
+
</body>
|
|
72
|
+
</html>
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
<table align="center" border="0" cellpadding="0" cellspacing="0" style="width:600px;" width="600">
|
|
2
|
+
<tr>
|
|
3
|
+
<td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;">
|
|
4
|
+
<div style="margin:0px auto;max-width:600px;">
|
|
5
|
+
<table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="width:100%;">
|
|
6
|
+
<tbody>
|
|
7
|
+
<tr>
|
|
8
|
+
<td style="direction:ltr;font-size:0px;padding:20px 0;padding-bottom:0px;text-align:center;">
|
|
9
|
+
<table role="presentation" border="0" cellpadding="0" cellspacing="0">
|
|
10
|
+
<tr>
|
|
11
|
+
<td style="vertical-align:top;width:600px;">
|
|
12
|
+
<div class="mj-column-per-100 mj-outlook-group-fix" style="font-size:0px;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;">
|
|
13
|
+
<table border="0" cellpadding="0" cellspacing="0" role="presentation" style="vertical-align:top;" width="100%">
|
|
14
|
+
<tbody>
|
|
15
|
+
<tr>
|
|
16
|
+
<td align="left" style="font-size:0px;padding:10px 25px;word-break:break-word;">
|
|
17
|
+
<table border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-collapse:collapse;border-spacing:0px;">
|
|
18
|
+
<tbody>
|
|
19
|
+
<tr>
|
|
20
|
+
<td style="width:50px;">
|
|
21
|
+
<img alt="image description" height="auto" src="https://codedmails.com/images/logo-circle.png" style="border:0;display:block;outline:none;text-decoration:none;height:auto;width:100%;font-size:14px;" width="50" />
|
|
22
|
+
</td>
|
|
23
|
+
</tr>
|
|
24
|
+
</tbody>
|
|
25
|
+
</table>
|
|
26
|
+
</td>
|
|
27
|
+
</tr>
|
|
28
|
+
<tr>
|
|
29
|
+
<td align="left" style="font-size:0px;padding:10px 25px;word-break:break-word;">
|
|
30
|
+
<div style="font-family:Helvetica, Arial, sans-serif;font-size:18px;font-weight:400;line-height:24px;text-align:left;color:#434245;">
|
|
31
|
+
<h1 style="margin: 0; font-size: 24px; line-height: normal; font-weight: bold;">
|
|
32
|
+
<%= I18n.t("mail.general.hello", name: @user.name) %>,
|
|
33
|
+
</h1>
|
|
34
|
+
</div>
|
|
35
|
+
</td>
|
|
36
|
+
</tr>
|
|
37
|
+
</tbody>
|
|
38
|
+
</table>
|
|
39
|
+
</div>
|
|
40
|
+
</td>
|
|
41
|
+
</tr>
|
|
42
|
+
</table>
|
|
43
|
+
</td>
|
|
44
|
+
</tr>
|
|
45
|
+
</tbody>
|
|
46
|
+
</table>
|
|
47
|
+
</div>
|
|
48
|
+
</td>
|
|
49
|
+
</tr>
|
|
50
|
+
</table>
|
|
51
|
+
<table align="center" border="0" cellpadding="0" cellspacing="0" style="width:600px;" width="600">
|
|
52
|
+
<tr>
|
|
53
|
+
<td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;">
|
|
54
|
+
<div style="margin:0px auto;max-width:600px;">
|
|
55
|
+
<table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" style="width:100%;">
|
|
56
|
+
<tbody>
|
|
57
|
+
<tr>
|
|
58
|
+
<td style="direction:ltr;font-size:0px;padding:20px 0;text-align:center;">
|
|
59
|
+
<table role="presentation" border="0" cellpadding="0" cellspacing="0">
|
|
60
|
+
<tr>
|
|
61
|
+
<td style="vertical-align:top;width:600px;">
|
|
62
|
+
<div class="mj-column-per-100 mj-outlook-group-fix" style="font-size:0px;text-align:left;direction:ltr;display:inline-block;vertical-align:top;width:100%;">
|
|
63
|
+
<table border="0" cellpadding="0" cellspacing="0" role="presentation" style="vertical-align:top;" width="100%">
|
|
64
|
+
<tbody>
|
|
65
|
+
<tr>
|
|
66
|
+
<td align="left" style="font-size:0px;padding:10px 25px;word-break:break-word;">
|
|
67
|
+
<div style="font-family:Helvetica, Arial, sans-serif;font-size:18px;font-weight:400;line-height:24px;text-align:left;color:#434245;">
|
|
68
|
+
<%= I18n.t("mail.user_context.registration.body.description") %>
|
|
69
|
+
</div>
|
|
70
|
+
</td>
|
|
71
|
+
</tr>
|
|
72
|
+
<tr>
|
|
73
|
+
<td align="left" style="font-size:0px;padding:10px 25px;word-break:break-word;">
|
|
74
|
+
<div style="font-family:Helvetica, Arial, sans-serif;font-size:18px;font-weight:400;line-height:24px;text-align:left;color:#434245;">
|
|
75
|
+
<%= raw I18n.t("mail.user_context.registration.body.email_confirmation_token", token: @user.email_confirmation_token) %>
|
|
76
|
+
</div>
|
|
77
|
+
</td>
|
|
78
|
+
</tr>
|
|
79
|
+
<tr>
|
|
80
|
+
<td align="left" style="font-size:0px;padding:10px 25px;word-break:break-word;">
|
|
81
|
+
<div style="font-family:Helvetica, Arial, sans-serif;font-size:18px;font-weight:bold;line-height:24px;text-align:left;color:#434245;">
|
|
82
|
+
<%= I18n.t("mail.general.team") %>
|
|
83
|
+
</div>
|
|
84
|
+
</td>
|
|
85
|
+
</tr>
|
|
86
|
+
<tr>
|
|
87
|
+
<td align="left" style="font-size:0px;padding:10px 25px;word-break:break-word;">
|
|
88
|
+
<table align="left" border="0" cellpadding="0" cellspacing="0" role="presentation">
|
|
89
|
+
<tr>
|
|
90
|
+
<td>
|
|
91
|
+
<table align="left" border="0" cellpadding="0" cellspacing="0" role="presentation" style="float:none;display:inline-table;">
|
|
92
|
+
<tbody>
|
|
93
|
+
<tr>
|
|
94
|
+
<td style="padding:4px;">
|
|
95
|
+
<table border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-radius:3px;width:18px;">
|
|
96
|
+
<tbody>
|
|
97
|
+
<tr>
|
|
98
|
+
<td style="font-size:0;height:18px;vertical-align:middle;width:18px;">
|
|
99
|
+
<a href="https://twitter.com/auctionfun" target="_blank" style="color: #2e58ff; text-decoration: none;">
|
|
100
|
+
<img alt="twitter-logo" height="18" src="https://codedmails.com/images/social/black/twitter-logo-transparent-black.png" style="border-radius:3px;display:block;" width="18" />
|
|
101
|
+
</a>
|
|
102
|
+
</td>
|
|
103
|
+
</tr>
|
|
104
|
+
</tbody>
|
|
105
|
+
</table>
|
|
106
|
+
</td>
|
|
107
|
+
</tr>
|
|
108
|
+
</tbody>
|
|
109
|
+
</table>
|
|
110
|
+
</td>
|
|
111
|
+
<td>
|
|
112
|
+
<table align="left" border="0" cellpadding="0" cellspacing="0" role="presentation" style="float:none;display:inline-table;">
|
|
113
|
+
<tbody>
|
|
114
|
+
<tr>
|
|
115
|
+
<td style="padding:4px;">
|
|
116
|
+
<table border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-radius:3px;width:18px;">
|
|
117
|
+
<tbody>
|
|
118
|
+
<tr>
|
|
119
|
+
<td style="font-size:0;height:18px;vertical-align:middle;width:18px;">
|
|
120
|
+
<a href="https://facebook.com/auctionfun" target="_blank" style="color: #2e58ff; text-decoration: none;">
|
|
121
|
+
<img alt="facebook-logo" height="18" src="https://codedmails.com/images/social/black/facebook-logo-transparent-black.png" style="border-radius:3px;display:block;" width="18" />
|
|
122
|
+
</a>
|
|
123
|
+
</td>
|
|
124
|
+
</tr>
|
|
125
|
+
</tbody>
|
|
126
|
+
</table>
|
|
127
|
+
</td>
|
|
128
|
+
</tr>
|
|
129
|
+
</tbody>
|
|
130
|
+
</table>
|
|
131
|
+
</td>
|
|
132
|
+
<td>
|
|
133
|
+
<table align="left" border="0" cellpadding="0" cellspacing="0" role="presentation" style="float:none;display:inline-table;">
|
|
134
|
+
<tbody>
|
|
135
|
+
<tr>
|
|
136
|
+
<td style="padding:4px;">
|
|
137
|
+
<table border="0" cellpadding="0" cellspacing="0" role="presentation" style="border-radius:3px;width:18px;">
|
|
138
|
+
<tbody>
|
|
139
|
+
<tr>
|
|
140
|
+
<td style="font-size:0;height:18px;vertical-align:middle;width:18px;">
|
|
141
|
+
<a href="https://instagram.com/auctionfun" target="_blank" style="color: #2e58ff; text-decoration: none;">
|
|
142
|
+
<img alt="instagram-logo" height="18" src="https://codedmails.com/images/social/black/instagram-logo-transparent-black.png" style="border-radius:3px;display:block;" width="18" />
|
|
143
|
+
</a>
|
|
144
|
+
</td>
|
|
145
|
+
</tr>
|
|
146
|
+
</tbody>
|
|
147
|
+
</table>
|
|
148
|
+
</td>
|
|
149
|
+
</tr>
|
|
150
|
+
</tbody>
|
|
151
|
+
</table>
|
|
152
|
+
</td>
|
|
153
|
+
</tr>
|
|
154
|
+
</table>
|
|
155
|
+
</td>
|
|
156
|
+
</tr>
|
|
157
|
+
</tbody>
|
|
158
|
+
</table>
|
|
159
|
+
</div>
|
|
160
|
+
</td>
|
|
161
|
+
</tr>
|
|
162
|
+
</table>
|
|
163
|
+
</td>
|
|
164
|
+
</tr>
|
|
165
|
+
</tbody>
|
|
166
|
+
</table>
|
|
167
|
+
</div>
|
|
168
|
+
</td>
|
|
169
|
+
</tr>
|
|
170
|
+
</table>
|