clean-architecture 0.0.1
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/.gitignore +1 -0
- data/.overcommit.yml +41 -0
- data/.reek +16 -0
- data/.rspec +2 -0
- data/.rubocop.yml +57 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +3 -0
- data/Gemfile +24 -0
- data/Gemfile.lock +160 -0
- data/Guardfile +111 -0
- data/README.md +17 -0
- data/Rakefile +8 -0
- data/clean-architecture.gemspec +29 -0
- data/generate_require_files.rb +49 -0
- data/lib/clean-architecture.rb +3 -0
- data/lib/clean_architecture/all.rb +11 -0
- data/lib/clean_architecture/entities/all.rb +7 -0
- data/lib/clean_architecture/entities/targeted_parameters.rb +20 -0
- data/lib/clean_architecture/entities/untargeted_parameters.rb +18 -0
- data/lib/clean_architecture/entities/use_case_history_entry.rb +52 -0
- data/lib/clean_architecture/interfaces/all.rb +17 -0
- data/lib/clean_architecture/interfaces/authorization_check.rb +15 -0
- data/lib/clean_architecture/interfaces/authorization_parameters.rb +18 -0
- data/lib/clean_architecture/interfaces/base_parameters.rb +23 -0
- data/lib/clean_architecture/interfaces/command.rb +23 -0
- data/lib/clean_architecture/interfaces/jsonable.rb +15 -0
- data/lib/clean_architecture/interfaces/persistence.rb +15 -0
- data/lib/clean_architecture/interfaces/strategy.rb +17 -0
- data/lib/clean_architecture/interfaces/success_payload.rb +19 -0
- data/lib/clean_architecture/interfaces/targeted_parameters.rb +18 -0
- data/lib/clean_architecture/interfaces/use_case.rb +23 -0
- data/lib/clean_architecture/interfaces/use_case_actor.rb +19 -0
- data/lib/clean_architecture/interfaces/use_case_history_entry.rb +39 -0
- data/lib/clean_architecture/interfaces/use_case_target.rb +23 -0
- data/lib/clean_architecture/queries/all.rb +5 -0
- data/lib/clean_architecture/queries/http_success_code.rb +28 -0
- data/lib/clean_architecture/serializers/all.rb +6 -0
- data/lib/clean_architecture/serializers/html_response_from_result.rb +23 -0
- data/lib/clean_architecture/serializers/json_response_from_result.rb +67 -0
- data/lib/clean_architecture/strategies/actor_gets_authorized_then_does_work.rb +30 -0
- data/lib/clean_architecture/strategies/all.rb +6 -0
- data/lib/clean_architecture/strategies/with_audit_trail.rb +40 -0
- data/lib/clean_architecture/version.rb +5 -0
- metadata +170 -0
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'duckface'
|
4
|
+
|
5
|
+
module CleanArchitecture
|
6
|
+
module Interfaces
|
7
|
+
module UseCaseHistoryEntry
|
8
|
+
extend Duckface::ActsAsInterface
|
9
|
+
|
10
|
+
def extra_parameters_hash
|
11
|
+
raise NotImplementedError
|
12
|
+
end
|
13
|
+
|
14
|
+
def failure_messages
|
15
|
+
raise NotImplementedError
|
16
|
+
end
|
17
|
+
|
18
|
+
def prior_target_state
|
19
|
+
raise NotImplementedError
|
20
|
+
end
|
21
|
+
|
22
|
+
def succeeded?
|
23
|
+
raise NotImplementedError
|
24
|
+
end
|
25
|
+
|
26
|
+
def target_identifier
|
27
|
+
raise NotImplementedError
|
28
|
+
end
|
29
|
+
|
30
|
+
def use_case_class_name
|
31
|
+
raise NotImplementedError
|
32
|
+
end
|
33
|
+
|
34
|
+
def user_identifier
|
35
|
+
raise NotImplementedError
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'duckface'
|
4
|
+
|
5
|
+
module CleanArchitecture
|
6
|
+
module Interfaces
|
7
|
+
module UseCaseTarget
|
8
|
+
extend Duckface::ActsAsInterface
|
9
|
+
|
10
|
+
def attribute_hash
|
11
|
+
raise NotImplementedError
|
12
|
+
end
|
13
|
+
|
14
|
+
def identifier
|
15
|
+
raise NotImplementedError
|
16
|
+
end
|
17
|
+
|
18
|
+
def type_name
|
19
|
+
raise NotImplementedError
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module CleanArchitecture
|
4
|
+
module Queries
|
5
|
+
class HttpSuccessCode
|
6
|
+
def initialize(http_method)
|
7
|
+
@http_method = http_method
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_sym
|
11
|
+
code = HTTP_METHOD_TO_SUCCESS_CODE[@http_method]
|
12
|
+
if code.nil?
|
13
|
+
raise NotImplementedError, "cannot determine success code for HTTP method #{@http_method}"
|
14
|
+
end
|
15
|
+
code
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
HTTP_METHOD_TO_SUCCESS_CODE = {
|
21
|
+
'GET' => :ok,
|
22
|
+
'POST' => :created,
|
23
|
+
'PUT' => :accepted,
|
24
|
+
'DELETE' => :ok
|
25
|
+
}.freeze
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'dry/matcher/result_matcher'
|
4
|
+
|
5
|
+
module CleanArchitecture
|
6
|
+
module Serializers
|
7
|
+
class HtmlResponseFromResult
|
8
|
+
def initialize(result, http_method)
|
9
|
+
@result = result
|
10
|
+
@http_method = http_method
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_h
|
14
|
+
Dry::Matcher::ResultMatcher.call(@result) do |matcher|
|
15
|
+
matcher.success do |data|
|
16
|
+
{ status: Queries::HttpSuccessCode.new(@http_method).to_sym, data: data }
|
17
|
+
end
|
18
|
+
matcher.failure { |error_message| { status: :error, error: error_message } }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'dry-monads'
|
4
|
+
require 'dry/matcher/result_matcher'
|
5
|
+
|
6
|
+
module CleanArchitecture
|
7
|
+
module Serializers
|
8
|
+
class JsonResponseFromResult
|
9
|
+
def initialize(result, http_method, success_payload)
|
10
|
+
@result = result
|
11
|
+
@http_method = http_method
|
12
|
+
@success_payload = success_payload
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_h
|
16
|
+
{
|
17
|
+
status: http_status_code,
|
18
|
+
json: json
|
19
|
+
}
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def http_status_code
|
25
|
+
Dry::Matcher::ResultMatcher.call(@result) do |matcher|
|
26
|
+
matcher.success { Queries::HttpSuccessCode.new(@http_method).to_sym }
|
27
|
+
matcher.failure do
|
28
|
+
if result_is_authorization_failure?
|
29
|
+
:unauthorized
|
30
|
+
else
|
31
|
+
:expectation_failed
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def json
|
38
|
+
Dry::Matcher::ResultMatcher.call(@result) do |matcher|
|
39
|
+
matcher.success { success_payload }
|
40
|
+
matcher.failure { |failure_message| error_payload(failure_message) }
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def success_payload
|
45
|
+
{
|
46
|
+
jsonapi: json_api_version_hash,
|
47
|
+
data: @success_payload.data_hash
|
48
|
+
}
|
49
|
+
end
|
50
|
+
|
51
|
+
def error_payload(failure_message)
|
52
|
+
{
|
53
|
+
jsonapi: json_api_version_hash,
|
54
|
+
errors: [failure_message]
|
55
|
+
}
|
56
|
+
end
|
57
|
+
|
58
|
+
def json_api_version_hash
|
59
|
+
{ version: @success_payload.version }
|
60
|
+
end
|
61
|
+
|
62
|
+
def result_is_authorization_failure?
|
63
|
+
!@result.failure.index('Unauthorized: ').nil?
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'dry-monads'
|
4
|
+
|
5
|
+
module CleanArchitecture
|
6
|
+
module Strategies
|
7
|
+
class ActorGetsAuthorizedThenDoesWork
|
8
|
+
extend Forwardable
|
9
|
+
|
10
|
+
implements_interface Interfaces::Strategy
|
11
|
+
|
12
|
+
def initialize(authorization_check, sub_strategy)
|
13
|
+
@authorization_check = authorization_check
|
14
|
+
@sub_strategy = sub_strategy
|
15
|
+
end
|
16
|
+
|
17
|
+
def_delegator :@sub_strategy, :parameters
|
18
|
+
|
19
|
+
def result
|
20
|
+
@result ||= begin
|
21
|
+
if @authorization_check.authorized?
|
22
|
+
@sub_strategy.result
|
23
|
+
else
|
24
|
+
Dry::Monads::Failure('Unauthorized: Invalid API key')
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'duckface'
|
4
|
+
|
5
|
+
module CleanArchitecture
|
6
|
+
module Strategies
|
7
|
+
class WithAuditTrail
|
8
|
+
implements_interface Interfaces::Strategy
|
9
|
+
extend Forwardable
|
10
|
+
|
11
|
+
def initialize(use_case_class, sub_strategy, use_case_target)
|
12
|
+
@use_case_class = use_case_class
|
13
|
+
@sub_strategy = sub_strategy
|
14
|
+
@use_case_target = use_case_target
|
15
|
+
end
|
16
|
+
|
17
|
+
def result
|
18
|
+
@result ||= begin
|
19
|
+
strategy_result = @sub_strategy.result
|
20
|
+
entry = new_use_case_history_entry(strategy_result)
|
21
|
+
parameters.persistence.create_use_case_history_entry(entry)
|
22
|
+
strategy_result
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def_delegator :@sub_strategy, :parameters
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def new_use_case_history_entry(sub_strategy_result)
|
31
|
+
Entities::UseCaseHistoryEntry.new(
|
32
|
+
@use_case_class,
|
33
|
+
@sub_strategy.parameters,
|
34
|
+
sub_strategy_result,
|
35
|
+
@use_case_target
|
36
|
+
)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
metadata
ADDED
@@ -0,0 +1,170 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: clean-architecture
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Bellroy Tech Team
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-06-23 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: dry-matcher
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: dry-monads
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: duckface-interfaces
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: bundler
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.13'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.13'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rake
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '10.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '10.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rspec
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '3.0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '3.0'
|
97
|
+
description: An attempt at building a reusable Clean Architecture framework for Ruby
|
98
|
+
email:
|
99
|
+
- tech@bellroy.com
|
100
|
+
executables: []
|
101
|
+
extensions: []
|
102
|
+
extra_rdoc_files: []
|
103
|
+
files:
|
104
|
+
- ".gitignore"
|
105
|
+
- ".overcommit.yml"
|
106
|
+
- ".reek"
|
107
|
+
- ".rspec"
|
108
|
+
- ".rubocop.yml"
|
109
|
+
- ".ruby-version"
|
110
|
+
- CHANGELOG.md
|
111
|
+
- Gemfile
|
112
|
+
- Gemfile.lock
|
113
|
+
- Guardfile
|
114
|
+
- README.md
|
115
|
+
- Rakefile
|
116
|
+
- clean-architecture.gemspec
|
117
|
+
- generate_require_files.rb
|
118
|
+
- lib/clean-architecture.rb
|
119
|
+
- lib/clean_architecture/all.rb
|
120
|
+
- lib/clean_architecture/entities/all.rb
|
121
|
+
- lib/clean_architecture/entities/targeted_parameters.rb
|
122
|
+
- lib/clean_architecture/entities/untargeted_parameters.rb
|
123
|
+
- lib/clean_architecture/entities/use_case_history_entry.rb
|
124
|
+
- lib/clean_architecture/interfaces/all.rb
|
125
|
+
- lib/clean_architecture/interfaces/authorization_check.rb
|
126
|
+
- lib/clean_architecture/interfaces/authorization_parameters.rb
|
127
|
+
- lib/clean_architecture/interfaces/base_parameters.rb
|
128
|
+
- lib/clean_architecture/interfaces/command.rb
|
129
|
+
- lib/clean_architecture/interfaces/jsonable.rb
|
130
|
+
- lib/clean_architecture/interfaces/persistence.rb
|
131
|
+
- lib/clean_architecture/interfaces/strategy.rb
|
132
|
+
- lib/clean_architecture/interfaces/success_payload.rb
|
133
|
+
- lib/clean_architecture/interfaces/targeted_parameters.rb
|
134
|
+
- lib/clean_architecture/interfaces/use_case.rb
|
135
|
+
- lib/clean_architecture/interfaces/use_case_actor.rb
|
136
|
+
- lib/clean_architecture/interfaces/use_case_history_entry.rb
|
137
|
+
- lib/clean_architecture/interfaces/use_case_target.rb
|
138
|
+
- lib/clean_architecture/queries/all.rb
|
139
|
+
- lib/clean_architecture/queries/http_success_code.rb
|
140
|
+
- lib/clean_architecture/serializers/all.rb
|
141
|
+
- lib/clean_architecture/serializers/html_response_from_result.rb
|
142
|
+
- lib/clean_architecture/serializers/json_response_from_result.rb
|
143
|
+
- lib/clean_architecture/strategies/actor_gets_authorized_then_does_work.rb
|
144
|
+
- lib/clean_architecture/strategies/all.rb
|
145
|
+
- lib/clean_architecture/strategies/with_audit_trail.rb
|
146
|
+
- lib/clean_architecture/version.rb
|
147
|
+
homepage: https://bellroy.com
|
148
|
+
licenses: []
|
149
|
+
metadata: {}
|
150
|
+
post_install_message:
|
151
|
+
rdoc_options: []
|
152
|
+
require_paths:
|
153
|
+
- lib
|
154
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
155
|
+
requirements:
|
156
|
+
- - ">="
|
157
|
+
- !ruby/object:Gem::Version
|
158
|
+
version: '0'
|
159
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
160
|
+
requirements:
|
161
|
+
- - ">="
|
162
|
+
- !ruby/object:Gem::Version
|
163
|
+
version: '0'
|
164
|
+
requirements: []
|
165
|
+
rubyforge_project:
|
166
|
+
rubygems_version: 2.6.13
|
167
|
+
signing_key:
|
168
|
+
specification_version: 4
|
169
|
+
summary: Bellroy Clean Architecture Framework
|
170
|
+
test_files: []
|