otto 1.6.0 → 2.0.0.pre2

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.
Files changed (136) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +3 -2
  3. data/.github/workflows/claude-code-review.yml +53 -0
  4. data/.github/workflows/claude.yml +49 -0
  5. data/.gitignore +3 -0
  6. data/.rubocop.yml +26 -344
  7. data/CHANGELOG.rst +131 -0
  8. data/CLAUDE.md +56 -0
  9. data/Gemfile +11 -4
  10. data/Gemfile.lock +38 -42
  11. data/README.md +2 -0
  12. data/bin/rspec +4 -4
  13. data/changelog.d/README.md +120 -0
  14. data/changelog.d/scriv.ini +5 -0
  15. data/docs/.gitignore +2 -0
  16. data/docs/migrating/v2.0.0-pre1.md +276 -0
  17. data/docs/migrating/v2.0.0-pre2.md +345 -0
  18. data/examples/.gitignore +1 -0
  19. data/examples/advanced_routes/README.md +33 -0
  20. data/examples/advanced_routes/app/controllers/handlers/async.rb +9 -0
  21. data/examples/advanced_routes/app/controllers/handlers/dynamic.rb +9 -0
  22. data/examples/advanced_routes/app/controllers/handlers/static.rb +9 -0
  23. data/examples/advanced_routes/app/controllers/modules/auth.rb +9 -0
  24. data/examples/advanced_routes/app/controllers/modules/transformer.rb +9 -0
  25. data/examples/advanced_routes/app/controllers/modules/validator.rb +9 -0
  26. data/examples/advanced_routes/app/controllers/routes_app.rb +232 -0
  27. data/examples/advanced_routes/app/controllers/v2/admin.rb +9 -0
  28. data/examples/advanced_routes/app/controllers/v2/config.rb +9 -0
  29. data/examples/advanced_routes/app/controllers/v2/settings.rb +9 -0
  30. data/examples/advanced_routes/app/logic/admin/logic/manager.rb +27 -0
  31. data/examples/advanced_routes/app/logic/admin/panel.rb +27 -0
  32. data/examples/advanced_routes/app/logic/analytics_processor.rb +25 -0
  33. data/examples/advanced_routes/app/logic/complex/business/handler.rb +27 -0
  34. data/examples/advanced_routes/app/logic/data_logic.rb +23 -0
  35. data/examples/advanced_routes/app/logic/data_processor.rb +25 -0
  36. data/examples/advanced_routes/app/logic/input_validator.rb +24 -0
  37. data/examples/advanced_routes/app/logic/nested/feature/logic.rb +27 -0
  38. data/examples/advanced_routes/app/logic/reports_generator.rb +27 -0
  39. data/examples/advanced_routes/app/logic/simple_logic.rb +25 -0
  40. data/examples/advanced_routes/app/logic/system/config/manager.rb +27 -0
  41. data/examples/advanced_routes/app/logic/test_logic.rb +23 -0
  42. data/examples/advanced_routes/app/logic/transform_logic.rb +23 -0
  43. data/examples/advanced_routes/app/logic/upload_logic.rb +23 -0
  44. data/examples/advanced_routes/app/logic/v2/logic/dashboard.rb +27 -0
  45. data/examples/advanced_routes/app/logic/v2/logic/processor.rb +27 -0
  46. data/examples/advanced_routes/app.rb +33 -0
  47. data/examples/advanced_routes/config.rb +23 -0
  48. data/examples/advanced_routes/config.ru +7 -0
  49. data/examples/advanced_routes/puma.rb +20 -0
  50. data/examples/advanced_routes/routes +167 -0
  51. data/examples/advanced_routes/run.rb +39 -0
  52. data/examples/advanced_routes/test.rb +58 -0
  53. data/examples/authentication_strategies/README.md +32 -0
  54. data/examples/authentication_strategies/app/auth.rb +68 -0
  55. data/examples/authentication_strategies/app/controllers/auth_controller.rb +29 -0
  56. data/examples/authentication_strategies/app/controllers/main_controller.rb +28 -0
  57. data/examples/authentication_strategies/config.ru +24 -0
  58. data/examples/authentication_strategies/routes +37 -0
  59. data/examples/basic/README.md +29 -0
  60. data/examples/basic/app.rb +7 -35
  61. data/examples/basic/routes +0 -9
  62. data/examples/mcp_demo/README.md +87 -0
  63. data/examples/mcp_demo/app.rb +29 -34
  64. data/examples/mcp_demo/config.ru +9 -60
  65. data/examples/security_features/README.md +46 -0
  66. data/examples/security_features/app.rb +23 -24
  67. data/examples/security_features/config.ru +8 -10
  68. data/lib/otto/core/configuration.rb +167 -0
  69. data/lib/otto/core/error_handler.rb +86 -0
  70. data/lib/otto/core/file_safety.rb +61 -0
  71. data/lib/otto/core/middleware_stack.rb +237 -0
  72. data/lib/otto/core/router.rb +184 -0
  73. data/lib/otto/core/uri_generator.rb +44 -0
  74. data/lib/otto/design_system.rb +7 -5
  75. data/lib/otto/env_keys.rb +114 -0
  76. data/lib/otto/helpers/base.rb +5 -21
  77. data/lib/otto/helpers/request.rb +10 -8
  78. data/lib/otto/helpers/response.rb +27 -4
  79. data/lib/otto/helpers/validation.rb +9 -7
  80. data/lib/otto/mcp/auth/token.rb +10 -9
  81. data/lib/otto/mcp/protocol.rb +24 -27
  82. data/lib/otto/mcp/rate_limiting.rb +8 -3
  83. data/lib/otto/mcp/registry.rb +7 -2
  84. data/lib/otto/mcp/route_parser.rb +10 -15
  85. data/lib/otto/mcp/{validation.rb → schema_validation.rb} +16 -11
  86. data/lib/otto/mcp/server.rb +45 -22
  87. data/lib/otto/response_handlers/auto.rb +39 -0
  88. data/lib/otto/response_handlers/base.rb +16 -0
  89. data/lib/otto/response_handlers/default.rb +16 -0
  90. data/lib/otto/response_handlers/factory.rb +39 -0
  91. data/lib/otto/response_handlers/json.rb +34 -0
  92. data/lib/otto/response_handlers/redirect.rb +25 -0
  93. data/lib/otto/response_handlers/view.rb +24 -0
  94. data/lib/otto/response_handlers.rb +9 -135
  95. data/lib/otto/route.rb +51 -55
  96. data/lib/otto/route_definition.rb +15 -18
  97. data/lib/otto/route_handlers/base.rb +121 -0
  98. data/lib/otto/route_handlers/class_method.rb +89 -0
  99. data/lib/otto/route_handlers/factory.rb +42 -0
  100. data/lib/otto/route_handlers/instance_method.rb +69 -0
  101. data/lib/otto/route_handlers/lambda.rb +59 -0
  102. data/lib/otto/route_handlers/logic_class.rb +93 -0
  103. data/lib/otto/route_handlers.rb +10 -405
  104. data/lib/otto/security/authentication/auth_strategy.rb +44 -0
  105. data/lib/otto/security/authentication/authentication_middleware.rb +140 -0
  106. data/lib/otto/security/authentication/failure_result.rb +44 -0
  107. data/lib/otto/security/authentication/route_auth_wrapper.rb +149 -0
  108. data/lib/otto/security/authentication/strategies/api_key_strategy.rb +40 -0
  109. data/lib/otto/security/authentication/strategies/noauth_strategy.rb +19 -0
  110. data/lib/otto/security/authentication/strategies/permission_strategy.rb +47 -0
  111. data/lib/otto/security/authentication/strategies/role_strategy.rb +57 -0
  112. data/lib/otto/security/authentication/strategies/session_strategy.rb +41 -0
  113. data/lib/otto/security/authentication/strategy_result.rb +337 -0
  114. data/lib/otto/security/authentication.rb +28 -282
  115. data/lib/otto/security/config.rb +14 -23
  116. data/lib/otto/security/configurator.rb +219 -0
  117. data/lib/otto/security/csrf.rb +8 -143
  118. data/lib/otto/security/middleware/csrf_middleware.rb +151 -0
  119. data/lib/otto/security/middleware/rate_limit_middleware.rb +54 -0
  120. data/lib/otto/security/middleware/validation_middleware.rb +252 -0
  121. data/lib/otto/security/rate_limiter.rb +86 -0
  122. data/lib/otto/security/rate_limiting.rb +10 -105
  123. data/lib/otto/security/validator.rb +8 -253
  124. data/lib/otto/static.rb +3 -0
  125. data/lib/otto/utils.rb +14 -0
  126. data/lib/otto/version.rb +3 -1
  127. data/lib/otto.rb +141 -498
  128. data/otto.gemspec +4 -2
  129. metadata +99 -18
  130. data/examples/dynamic_pages/app.rb +0 -115
  131. data/examples/dynamic_pages/config.ru +0 -30
  132. data/examples/dynamic_pages/routes +0 -21
  133. data/examples/helpers_demo/app.rb +0 -244
  134. data/examples/helpers_demo/config.ru +0 -26
  135. data/examples/helpers_demo/routes +0 -7
  136. data/lib/concurrent_cache_store.rb +0 -68
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Modules
4
+ class Validator
5
+ def validate
6
+ [200, { 'content-type' => 'application/json' }, ['{"validation": "passed", "module": "Validator"}']]
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,232 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+ require 'time'
5
+
6
+ # Main application class demonstrating advanced routes syntax
7
+ class RoutesApp
8
+ # ========================================
9
+ # BASIC ROUTES
10
+ # ========================================
11
+
12
+ def self.index
13
+ [200, { 'content-type' => 'text/html' }, ['<h1>Advanced Routes Syntax Example</h1><p>Otto v1.5.0+ Features</p>']]
14
+ end
15
+
16
+ def self.receive_feedback
17
+ [200, { 'content-type' => 'text/plain' }, ['Feedback received']]
18
+ end
19
+
20
+ # ========================================
21
+ # RESPONSE TYPE ROUTES
22
+ # ========================================
23
+
24
+ def self.list_users
25
+ users = [
26
+ { id: 1, name: 'Alice', role: 'admin' },
27
+ { id: 2, name: 'Bob', role: 'user' },
28
+ ]
29
+ [200, { 'content-type' => 'application/json' }, [users.to_json]]
30
+ end
31
+
32
+ def self.create_user
33
+ [201, { 'content-type' => 'application/json' }, ['{"message": "User created", "id": 3}']]
34
+ end
35
+
36
+ def self.health_check
37
+ [200, { 'content-type' => 'application/json' }, ['{"status": "healthy", "timestamp": "' + Time.now.iso8601 + '"}']]
38
+ end
39
+
40
+ def self.update_user
41
+ [200, { 'content-type' => 'application/json' }, ['{"message": "User updated"}']]
42
+ end
43
+
44
+ def self.delete_user
45
+ [204, {}, ['']]
46
+ end
47
+
48
+ def self.dashboard
49
+ [200, { 'content-type' => 'text/html' }, ['<h1>Dashboard</h1><p>HTML view response</p>']]
50
+ end
51
+
52
+ def self.reports
53
+ [200, { 'content-type' => 'text/html' }, ['<h1>Reports</h1><p>View response type demonstration</p>']]
54
+ end
55
+
56
+ def self.admin_panel
57
+ [200, { 'content-type' => 'text/html' }, ['<h1>Admin Panel</h1><p>Administrative interface</p>']]
58
+ end
59
+
60
+ def self.login_redirect
61
+ [302, { 'location' => '/dashboard' }, ['']]
62
+ end
63
+
64
+ def self.logout_redirect
65
+ [302, { 'location' => '/' }, ['']]
66
+ end
67
+
68
+ def self.home_redirect
69
+ [302, { 'location' => '/dashboard' }, ['']]
70
+ end
71
+
72
+ def self.flexible_data
73
+ data = { message: 'This is flexible data', timestamp: Time.now.iso8601 }
74
+ [200, { 'content-type' => 'application/json' }, [data.to_json]]
75
+ end
76
+
77
+ def self.flexible_content
78
+ [200, { 'content-type' => 'application/json' }, ['{"content": "Auto response type", "format": "negotiated"}']]
79
+ end
80
+
81
+ # ========================================
82
+ # CSRF ROUTES
83
+ # ========================================
84
+
85
+ def self.webhook_handler
86
+ [200, { 'content-type' => 'application/json' }, ['{"message": "Webhook processed (CSRF exempt)"}']]
87
+ end
88
+
89
+ def self.external_update
90
+ [200, { 'content-type' => 'application/json' }, ['{"message": "External update processed"}']]
91
+ end
92
+
93
+ def self.cleanup_data
94
+ [200, { 'content-type' => 'application/json' }, ['{"message": "Data cleanup completed"}']]
95
+ end
96
+
97
+ def self.sync_data
98
+ [200, { 'content-type' => 'application/json' }, ['{"message": "Data sync completed"}']]
99
+ end
100
+
101
+ def self.update_settings
102
+ [200, { 'content-type' => 'text/plain' }, ['Settings updated (CSRF protected)']]
103
+ end
104
+
105
+ def self.change_password
106
+ [200, { 'content-type' => 'text/plain' }, ['Password changed (CSRF protected)']]
107
+ end
108
+
109
+ def self.delete_profile
110
+ [204, {}, ['']]
111
+ end
112
+
113
+ # ========================================
114
+ # MULTIPLE PARAMETER COMBINATIONS
115
+ # ========================================
116
+
117
+ def self.api_data
118
+ [200, { 'content-type' => 'application/json' }, ['{"api": "v1", "data": "response"}']]
119
+ end
120
+
121
+ def self.api_submit
122
+ [201, { 'content-type' => 'application/json' }, ['{"message": "API submission processed"}']]
123
+ end
124
+
125
+ def self.api_update
126
+ [200, { 'content-type' => 'application/json' }, ['{"message": "API update completed"}']]
127
+ end
128
+
129
+ def self.admin_dashboard
130
+ [200, { 'content-type' => 'text/html' }, ['<h1>Admin Dashboard</h1><p>Administrative view</p>']]
131
+ end
132
+
133
+ def self.admin_settings
134
+ [200, { 'content-type' => 'text/html' }, ['<h1>Admin Settings</h1><p>Settings updated</p>']]
135
+ end
136
+
137
+ def self.mixed_content
138
+ [200, { 'content-type' => 'application/json' }, ['{"type": "mixed", "csrf": "exempt", "response": "auto"}']]
139
+ end
140
+
141
+ # ========================================
142
+ # CUSTOM PARAMETERS
143
+ # ========================================
144
+
145
+ def self.show_config
146
+ [200, { 'content-type' => 'application/json' }, ['{"environment": "production", "config": "displayed"}']]
147
+ end
148
+
149
+ def self.debug_info
150
+ [200, { 'content-type' => 'application/json' }, ['{"environment": "development", "debug": true}']]
151
+ end
152
+
153
+ def self.update_config
154
+ [200, { 'content-type' => 'application/json' }, ['{"message": "Config updated", "environment": "production"}']]
155
+ end
156
+
157
+ def self.feature_flags
158
+ [200, { 'content-type' => 'application/json' }, ['{"feature": "advanced", "mode": "enabled", "flags": []}']]
159
+ end
160
+
161
+ def self.toggle_feature
162
+ [200, { 'content-type' => 'application/json' }, ['{"feature": "beta", "mode": "test", "toggled": true}']]
163
+ end
164
+
165
+ # ========================================
166
+ # PARAMETER VALUE VARIATIONS
167
+ # ========================================
168
+
169
+ def self.api_v1
170
+ [200, { 'content-type' => 'application/json' }, ['{"version": "1.0", "api": "v1"}']]
171
+ end
172
+
173
+ def self.api_v2
174
+ [200, { 'content-type' => 'application/json' }, ['{"version": "2.0", "api": "v2"}']]
175
+ end
176
+
177
+ def self.api_legacy
178
+ [200, { 'content-type' => 'application/json' }, ['{"version": "legacy", "deprecated": true}']]
179
+ end
180
+
181
+ def self.complex_query
182
+ [200, { 'content-type' => 'application/json' }, ['{"query": "complex", "filter": "key=value"}']]
183
+ end
184
+
185
+ def self.config_db
186
+ [200, { 'content-type' => 'application/json' }, ['{"connection": "host=localhost", "configured": true}']]
187
+ end
188
+
189
+ # ========================================
190
+ # ERROR HANDLERS
191
+ # ========================================
192
+
193
+ def self.not_found
194
+ [404, { 'content-type' => 'text/html' }, ['<h1>404 - Page Not Found</h1><p>Advanced routes syntax example</p>']]
195
+ end
196
+
197
+ def self.server_error
198
+ [500, { 'content-type' => 'text/html' }, ['<h1>500 - Server Error</h1><p>Something went wrong</p>']]
199
+ end
200
+
201
+ # ========================================
202
+ # TESTING ROUTES
203
+ # ========================================
204
+
205
+ def self.test_json
206
+ [200, { 'content-type' => 'application/json' }, ['{"test": "json", "response_type": "json"}']]
207
+ end
208
+
209
+ def self.test_view
210
+ [200, { 'content-type' => 'text/html' }, ['<h1>Test View</h1><p>HTML view response</p>']]
211
+ end
212
+
213
+ def self.test_redirect
214
+ [302, { 'location' => '/' }, ['']]
215
+ end
216
+
217
+ def self.test_auto
218
+ [200, { 'content-type' => 'application/json' }, ['{"test": "auto", "response_type": "auto"}']]
219
+ end
220
+
221
+ def self.test_csrf
222
+ [200, { 'content-type' => 'text/html' }, ['<h1>CSRF Test</h1><p>POST request (CSRF protected)</p>']]
223
+ end
224
+
225
+ def self.test_no_csrf
226
+ [200, { 'content-type' => 'text/html' }, ['<h1>No CSRF Test</h1><p>POST request (CSRF exempt)</p>']]
227
+ end
228
+
229
+ def self.test_everything
230
+ [200, { 'content-type' => 'application/json' }, ['{"message": "All parameters tested", "csrf": "exempt", "custom": "value"}']]
231
+ end
232
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module V2
4
+ class Admin
5
+ def self.show
6
+ [200, { 'content-type' => 'text/html' }, ['<h1>V2 Admin</h1><p>Class method implementation</p>']]
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module V2
4
+ class Config
5
+ def self.update
6
+ [200, { 'content-type' => 'application/json' }, ['{"message": "V2 config updated"}']]
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module V2
4
+ class Settings
5
+ def self.modify
6
+ [200, { 'content-type' => 'application/json' }, ['{"message": "V2 settings modified", "csrf": "exempt"}']]
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Admin
4
+ module Logic
5
+ class Manager
6
+ attr_reader :context, :params, :locale
7
+
8
+ def initialize(context, params, locale)
9
+ @context = context
10
+ @params = params
11
+ @locale = locale
12
+ end
13
+
14
+ def process
15
+ {
16
+ admin_manager: 'Active',
17
+ namespace: 'Admin::Logic',
18
+ management_tools: ['users', 'settings', 'logs'],
19
+ }
20
+ end
21
+
22
+ def response_data
23
+ { admin_logic_manager: process }
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Admin
4
+ class Panel
5
+ attr_reader :context, :params, :locale
6
+
7
+ def initialize(context, params, locale)
8
+ @context = context
9
+ @params = params
10
+ @locale = locale
11
+ end
12
+
13
+ def process
14
+ {
15
+ admin_panel: 'Logic processed',
16
+ namespace: 'Admin',
17
+ access_level: 'admin',
18
+ authenticated: @context.authenticated?,
19
+ has_admin_role: @context.has_role?('admin'),
20
+ }
21
+ end
22
+
23
+ def response_data
24
+ { admin_panel_logic: process }
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Analytics
4
+ class Processor
5
+ attr_reader :context, :params, :locale
6
+
7
+ def initialize(context, params, locale)
8
+ @context = context
9
+ @params = params
10
+ @locale = locale
11
+ end
12
+
13
+ def process
14
+ {
15
+ analytics: 'Processed',
16
+ metrics: { users: 123, events: 456 },
17
+ period: @params['period'] || 'today',
18
+ }
19
+ end
20
+
21
+ def response_data
22
+ { analytics_processor: process }
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Complex
4
+ module Business
5
+ class Handler
6
+ attr_reader :context, :params, :locale
7
+
8
+ def initialize(context, params, locale)
9
+ @context = context
10
+ @params = params
11
+ @locale = locale
12
+ end
13
+
14
+ def process
15
+ {
16
+ complex_business: 'Handled',
17
+ namespace: 'Complex::Business',
18
+ business_logic: 'executed',
19
+ }
20
+ end
21
+
22
+ def response_data
23
+ { complex_business_handler: process }
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ class DataLogic
4
+ attr_reader :context, :params, :locale
5
+
6
+ def initialize(context, params, locale)
7
+ @context = context
8
+ @params = params
9
+ @locale = locale
10
+ end
11
+
12
+ def process
13
+ {
14
+ data_logic: 'Processed',
15
+ response_format: 'json',
16
+ input_data: @params,
17
+ }
18
+ end
19
+
20
+ def response_data
21
+ { data_logic_result: process }
22
+ end
23
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ class DataProcessor
4
+ attr_reader :context, :params, :locale
5
+
6
+ def initialize(context, params, locale)
7
+ @context = context
8
+ @params = params
9
+ @locale = locale
10
+ end
11
+
12
+ def process
13
+ {
14
+ processed: 'Data processing complete',
15
+ input_params: @params.keys,
16
+ timestamp: Time.now.iso8601,
17
+ authenticated: @context.authenticated?,
18
+ user_id: @context.user_id,
19
+ }
20
+ end
21
+
22
+ def response_data
23
+ { data_processor: process }
24
+ end
25
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ class InputValidator
4
+ attr_reader :context, :params, :locale
5
+
6
+ def initialize(context, params, locale)
7
+ @context = context
8
+ @params = params
9
+ @locale = locale
10
+ end
11
+
12
+ def process
13
+ {
14
+ validation: 'Input validated successfully',
15
+ validated_fields: @params.keys,
16
+ locale: @locale,
17
+ authenticated: @context.authenticated?,
18
+ }
19
+ end
20
+
21
+ def response_data
22
+ { validator: process }
23
+ end
24
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nested
4
+ module Feature
5
+ class Logic
6
+ attr_reader :context, :params, :locale
7
+
8
+ def initialize(context, params, locale)
9
+ @context = context
10
+ @params = params
11
+ @locale = locale
12
+ end
13
+
14
+ def process
15
+ {
16
+ nested_feature: 'Processed',
17
+ depth: 3,
18
+ namespace: 'Nested::Feature',
19
+ }
20
+ end
21
+
22
+ def response_data
23
+ { nested_feature_logic: process }
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Reports
4
+ class Generator
5
+ attr_reader :context, :params, :locale
6
+
7
+ def initialize(context, params, locale)
8
+ @context = context
9
+ @params = params
10
+ @locale = locale
11
+ end
12
+
13
+ def process
14
+ {
15
+ report_generation: 'Complete',
16
+ namespace: 'Reports',
17
+ data_points: 100,
18
+ authenticated: @context.authenticated?,
19
+ user_permissions: @context.permissions,
20
+ }
21
+ end
22
+
23
+ def response_data
24
+ { report_generator: process }
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ class SimpleLogic
4
+ attr_reader :context, :params, :locale
5
+
6
+ def initialize(context, params, locale)
7
+ @context = context
8
+ @params = params
9
+ @locale = locale
10
+ end
11
+
12
+ def process
13
+ {
14
+ message: 'Simple logic processed',
15
+ params: @params,
16
+ locale: @locale,
17
+ authenticated: @context.authenticated?,
18
+ user: @context.user_name,
19
+ }
20
+ end
21
+
22
+ def response_data
23
+ { simple_logic: process }
24
+ end
25
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module System
4
+ module Config
5
+ class Manager
6
+ attr_reader :context, :params, :locale
7
+
8
+ def initialize(context, params, locale)
9
+ @context = context
10
+ @params = params
11
+ @locale = locale
12
+ end
13
+
14
+ def process
15
+ {
16
+ system_config: 'Updated',
17
+ namespace: 'System::Config',
18
+ csrf_exempt: true,
19
+ }
20
+ end
21
+
22
+ def response_data
23
+ { system_config_manager: process }
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ class TestLogic
4
+ attr_reader :context, :params, :locale
5
+
6
+ def initialize(context, params, locale)
7
+ @context = context
8
+ @params = params
9
+ @locale = locale
10
+ end
11
+
12
+ def process
13
+ {
14
+ test: 'Logic class test',
15
+ params_received: @params,
16
+ processing_complete: true,
17
+ }
18
+ end
19
+
20
+ def response_data
21
+ { test_logic: process }
22
+ end
23
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ class TransformLogic
4
+ attr_reader :context, :params, :locale
5
+
6
+ def initialize(context, params, locale)
7
+ @context = context
8
+ @params = params
9
+ @locale = locale
10
+ end
11
+
12
+ def process
13
+ {
14
+ transformation: 'Complete',
15
+ input_size: @params.to_s.length,
16
+ output_format: 'json',
17
+ }
18
+ end
19
+
20
+ def response_data
21
+ { transform_result: process }
22
+ end
23
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ class UploadLogic
4
+ attr_reader :context, :params, :locale
5
+
6
+ def initialize(context, params, locale)
7
+ @context = context
8
+ @params = params
9
+ @locale = locale
10
+ end
11
+
12
+ def process
13
+ {
14
+ upload: 'Processing complete',
15
+ csrf_exempt: true,
16
+ files_processed: @params.keys.count,
17
+ }
18
+ end
19
+
20
+ def response_data
21
+ { upload_result: process }
22
+ end
23
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module V2
4
+ module Logic
5
+ class Dashboard
6
+ attr_reader :context, :params, :locale
7
+
8
+ def initialize(context, params, locale)
9
+ @context = context
10
+ @params = params
11
+ @locale = locale
12
+ end
13
+
14
+ def process
15
+ {
16
+ v2_dashboard: 'Rendered',
17
+ version: '2.0',
18
+ features: ['metrics', 'charts', 'reports'],
19
+ }
20
+ end
21
+
22
+ def response_data
23
+ { v2_dashboard: process }
24
+ end
25
+ end
26
+ end
27
+ end