otto 2.0.0.pre3 → 2.0.0.pre8

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 (104) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +1 -1
  3. data/.github/workflows/claude-code-review.yml +1 -1
  4. data/.github/workflows/code-smells.yml +143 -0
  5. data/.gitignore +4 -0
  6. data/.pre-commit-config.yaml +2 -2
  7. data/.reek.yml +99 -0
  8. data/CHANGELOG.rst +156 -0
  9. data/CLAUDE.md +74 -540
  10. data/Gemfile +4 -2
  11. data/Gemfile.lock +58 -19
  12. data/README.md +49 -1
  13. data/examples/advanced_routes/README.md +137 -20
  14. data/examples/authentication_strategies/README.md +212 -19
  15. data/examples/backtrace_sanitization_demo.rb +86 -0
  16. data/examples/basic/README.md +61 -10
  17. data/examples/error_handler_registration.rb +136 -0
  18. data/examples/logging_improvements.rb +76 -0
  19. data/examples/mcp_demo/README.md +187 -27
  20. data/examples/security_features/README.md +249 -30
  21. data/examples/simple_geo_resolver.rb +107 -0
  22. data/lib/otto/core/configuration.rb +15 -20
  23. data/lib/otto/core/error_handler.rb +138 -8
  24. data/lib/otto/core/file_safety.rb +2 -2
  25. data/lib/otto/core/freezable.rb +2 -2
  26. data/lib/otto/core/middleware_stack.rb +2 -2
  27. data/lib/otto/core/router.rb +61 -8
  28. data/lib/otto/core/uri_generator.rb +2 -2
  29. data/lib/otto/core.rb +2 -0
  30. data/lib/otto/design_system.rb +2 -2
  31. data/lib/otto/env_keys.rb +61 -12
  32. data/lib/otto/helpers/base.rb +2 -2
  33. data/lib/otto/helpers/request.rb +8 -3
  34. data/lib/otto/helpers/response.rb +2 -2
  35. data/lib/otto/helpers/validation.rb +2 -2
  36. data/lib/otto/helpers.rb +2 -0
  37. data/lib/otto/locale/config.rb +2 -2
  38. data/lib/otto/locale/middleware.rb +160 -0
  39. data/lib/otto/locale.rb +10 -0
  40. data/lib/otto/logging_helpers.rb +273 -0
  41. data/lib/otto/mcp/auth/token.rb +2 -2
  42. data/lib/otto/mcp/protocol.rb +2 -2
  43. data/lib/otto/mcp/rate_limiting.rb +2 -2
  44. data/lib/otto/mcp/registry.rb +2 -2
  45. data/lib/otto/mcp/route_parser.rb +2 -2
  46. data/lib/otto/mcp/schema_validation.rb +2 -2
  47. data/lib/otto/mcp/server.rb +2 -2
  48. data/lib/otto/mcp.rb +2 -0
  49. data/lib/otto/privacy/config.rb +2 -0
  50. data/lib/otto/privacy/geo_resolver.rb +199 -29
  51. data/lib/otto/privacy/ip_privacy.rb +2 -0
  52. data/lib/otto/privacy/redacted_fingerprint.rb +18 -8
  53. data/lib/otto/privacy.rb +2 -0
  54. data/lib/otto/response_handlers/auto.rb +2 -0
  55. data/lib/otto/response_handlers/base.rb +2 -0
  56. data/lib/otto/response_handlers/default.rb +2 -0
  57. data/lib/otto/response_handlers/factory.rb +2 -0
  58. data/lib/otto/response_handlers/json.rb +2 -0
  59. data/lib/otto/response_handlers/redirect.rb +2 -0
  60. data/lib/otto/response_handlers/view.rb +2 -0
  61. data/lib/otto/response_handlers.rb +2 -2
  62. data/lib/otto/route.rb +4 -4
  63. data/lib/otto/route_definition.rb +42 -15
  64. data/lib/otto/route_handlers/base.rb +2 -0
  65. data/lib/otto/route_handlers/class_method.rb +26 -26
  66. data/lib/otto/route_handlers/factory.rb +2 -2
  67. data/lib/otto/route_handlers/instance_method.rb +16 -6
  68. data/lib/otto/route_handlers/lambda.rb +8 -20
  69. data/lib/otto/route_handlers/logic_class.rb +33 -8
  70. data/lib/otto/route_handlers.rb +2 -2
  71. data/lib/otto/security/authentication/auth_failure.rb +2 -2
  72. data/lib/otto/security/authentication/auth_strategy.rb +11 -4
  73. data/lib/otto/security/authentication/route_auth_wrapper/response_builder.rb +123 -0
  74. data/lib/otto/security/authentication/route_auth_wrapper/role_authorization.rb +120 -0
  75. data/lib/otto/security/authentication/route_auth_wrapper/strategy_resolver.rb +69 -0
  76. data/lib/otto/security/authentication/route_auth_wrapper.rb +185 -195
  77. data/lib/otto/security/authentication/strategies/api_key_strategy.rb +2 -0
  78. data/lib/otto/security/authentication/strategies/noauth_strategy.rb +2 -0
  79. data/lib/otto/security/authentication/strategies/permission_strategy.rb +2 -0
  80. data/lib/otto/security/authentication/strategies/role_strategy.rb +2 -0
  81. data/lib/otto/security/authentication/strategies/session_strategy.rb +2 -0
  82. data/lib/otto/security/authentication/strategy_result.rb +6 -5
  83. data/lib/otto/security/authentication.rb +2 -2
  84. data/lib/otto/security/authorization_error.rb +73 -0
  85. data/lib/otto/security/config.rb +2 -2
  86. data/lib/otto/security/configurator.rb +17 -2
  87. data/lib/otto/security/csrf.rb +2 -2
  88. data/lib/otto/security/middleware/csrf_middleware.rb +11 -1
  89. data/lib/otto/security/middleware/ip_privacy_middleware.rb +31 -11
  90. data/lib/otto/security/middleware/rate_limit_middleware.rb +2 -0
  91. data/lib/otto/security/middleware/validation_middleware.rb +15 -0
  92. data/lib/otto/security/rate_limiter.rb +2 -2
  93. data/lib/otto/security/rate_limiting.rb +2 -2
  94. data/lib/otto/security/validator.rb +2 -2
  95. data/lib/otto/security.rb +3 -0
  96. data/lib/otto/static.rb +2 -2
  97. data/lib/otto/utils.rb +27 -2
  98. data/lib/otto/version.rb +3 -3
  99. data/lib/otto.rb +174 -14
  100. data/otto.gemspec +7 -3
  101. metadata +25 -15
  102. data/benchmark_middleware_wrap.rb +0 -163
  103. data/changelog.d/20251014_144317_delano_54_thats_a_wrapper.rst +0 -36
  104. data/changelog.d/20251014_161526_delano_54_thats_a_wrapper.rst +0 -5
data/Gemfile CHANGED
@@ -14,6 +14,7 @@ gem 'rackup'
14
14
  group :test do
15
15
  gem 'rack-test'
16
16
  gem 'rspec', '~> 3.13'
17
+ gem 'user_agent_parser', '~> 2.18' # Validate anonymized UAs preserve semantic info
17
18
  end
18
19
 
19
20
  # bundle config set with 'optional'
@@ -21,17 +22,18 @@ group :development, :test, optional: true do
21
22
  # Keep gems that need to be in both environments
22
23
  gem 'json_schemer'
23
24
  gem 'rack-attack'
25
+ gem 'reek', '~> 6.5'
24
26
  end
25
27
 
26
28
  group :development do
27
29
  gem 'benchmark'
28
30
  gem 'debug'
29
- gem 'rubocop', '~> 1.81.1', require: false
31
+ gem 'rubocop', '~> 1.81.7', require: false
30
32
  gem 'rubocop-performance', require: false
31
33
  gem 'rubocop-rspec', require: false
32
34
  gem 'rubocop-thread_safety', require: false
33
35
  gem 'ruby-lsp', require: false
34
36
  gem 'stackprof', require: false
35
37
  gem 'syntax_tree', require: false
36
- gem 'tryouts', '~> 3.6.1', require: false
38
+ gem 'tryouts', '~> 3.7.1', require: false
37
39
  end
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- otto (2.0.0.pre3)
4
+ otto (2.0.0.pre8)
5
5
  concurrent-ruby (~> 1.3, < 2.0)
6
6
  facets (~> 3.1)
7
7
  ipaddr (~> 1, < 2.0)
@@ -9,13 +9,13 @@ PATH
9
9
  loofah (~> 2.20)
10
10
  rack (~> 3.1, < 4.0)
11
11
  rack-parser (~> 0.7)
12
- rexml (>= 3.3.6)
12
+ rexml (~> 3.4)
13
13
 
14
14
  GEM
15
15
  remote: https://rubygems.org/
16
16
  specs:
17
17
  ast (2.4.3)
18
- benchmark (0.4.1)
18
+ benchmark (0.5.0)
19
19
  bigdecimal (3.2.3)
20
20
  concurrent-ruby (1.3.5)
21
21
  crass (1.0.6)
@@ -24,6 +24,35 @@ GEM
24
24
  irb (~> 1.10)
25
25
  reline (>= 0.3.8)
26
26
  diff-lcs (1.6.2)
27
+ dry-configurable (1.3.0)
28
+ dry-core (~> 1.1)
29
+ zeitwerk (~> 2.6)
30
+ dry-core (1.1.0)
31
+ concurrent-ruby (~> 1.0)
32
+ logger
33
+ zeitwerk (~> 2.6)
34
+ dry-inflector (1.2.0)
35
+ dry-initializer (3.2.0)
36
+ dry-logic (1.6.0)
37
+ bigdecimal
38
+ concurrent-ruby (~> 1.0)
39
+ dry-core (~> 1.1)
40
+ zeitwerk (~> 2.6)
41
+ dry-schema (1.14.1)
42
+ concurrent-ruby (~> 1.0)
43
+ dry-configurable (~> 1.0, >= 1.0.1)
44
+ dry-core (~> 1.1)
45
+ dry-initializer (~> 3.2)
46
+ dry-logic (~> 1.5)
47
+ dry-types (~> 1.8)
48
+ zeitwerk (~> 2.6)
49
+ dry-types (1.8.3)
50
+ bigdecimal (~> 3.0)
51
+ concurrent-ruby (~> 1.0)
52
+ dry-core (~> 1.0)
53
+ dry-inflector (~> 1.0)
54
+ dry-logic (~> 1.4)
55
+ zeitwerk (~> 2.6)
27
56
  erb (5.1.1)
28
57
  facets (3.1.0)
29
58
  hana (1.3.7)
@@ -33,7 +62,7 @@ GEM
33
62
  pp (>= 0.6.0)
34
63
  rdoc (>= 4.0.0)
35
64
  reline (>= 0.4.2)
36
- json (2.15.1)
65
+ json (2.15.2)
37
66
  json_schemer (2.4.0)
38
67
  bigdecimal
39
68
  hana (~> 1.3)
@@ -63,7 +92,7 @@ GEM
63
92
  nokogiri (1.18.10-x86_64-linux-musl)
64
93
  racc (~> 1.4)
65
94
  parallel (1.27.0)
66
- parser (3.3.9.0)
95
+ parser (3.3.10.0)
67
96
  ast (~> 2.4.1)
68
97
  racc
69
98
  pastel (0.8.0)
@@ -72,13 +101,13 @@ GEM
72
101
  prettyprint
73
102
  prettier_print (1.2.1)
74
103
  prettyprint (0.2.0)
75
- prism (1.5.2)
104
+ prism (1.6.0)
76
105
  psych (5.2.6)
77
106
  date
78
107
  stringio
79
108
  racc (1.8.1)
80
- rack (3.2.3)
81
- rack-attack (6.7.0)
109
+ rack (3.2.4)
110
+ rack-attack (6.8.0)
82
111
  rack (>= 1.0, < 4)
83
112
  rack-parser (0.7.0)
84
113
  rack
@@ -93,24 +122,30 @@ GEM
93
122
  erb
94
123
  psych (>= 4.0.0)
95
124
  tsort
125
+ reek (6.5.0)
126
+ dry-schema (~> 1.13)
127
+ logger (~> 1.6)
128
+ parser (~> 3.3.0)
129
+ rainbow (>= 2.0, < 4.0)
130
+ rexml (~> 3.1)
96
131
  regexp_parser (2.11.3)
97
132
  reline (0.6.2)
98
133
  io-console (~> 0.5)
99
134
  rexml (3.4.4)
100
- rspec (3.13.1)
135
+ rspec (3.13.2)
101
136
  rspec-core (~> 3.13.0)
102
137
  rspec-expectations (~> 3.13.0)
103
138
  rspec-mocks (~> 3.13.0)
104
- rspec-core (3.13.5)
139
+ rspec-core (3.13.6)
105
140
  rspec-support (~> 3.13.0)
106
141
  rspec-expectations (3.13.5)
107
142
  diff-lcs (>= 1.2.0, < 2.0)
108
143
  rspec-support (~> 3.13.0)
109
- rspec-mocks (3.13.5)
144
+ rspec-mocks (3.13.6)
110
145
  diff-lcs (>= 1.2.0, < 2.0)
111
146
  rspec-support (~> 3.13.0)
112
147
  rspec-support (3.13.6)
113
- rubocop (1.81.1)
148
+ rubocop (1.81.7)
114
149
  json (~> 2.3)
115
150
  language_server-protocol (~> 3.17.0.2)
116
151
  lint_roller (~> 1.1.0)
@@ -124,10 +159,10 @@ GEM
124
159
  rubocop-ast (1.47.1)
125
160
  parser (>= 3.3.7.2)
126
161
  prism (~> 1.4)
127
- rubocop-performance (1.26.0)
162
+ rubocop-performance (1.26.1)
128
163
  lint_roller (~> 1.1)
129
164
  rubocop (>= 1.75.0, < 2.0)
130
- rubocop-ast (>= 1.44.0, < 2.0)
165
+ rubocop-ast (>= 1.47.1, < 2.0)
131
166
  rubocop-rspec (3.7.0)
132
167
  lint_roller (~> 1.1)
133
168
  rubocop (~> 1.72, >= 1.72.1)
@@ -135,7 +170,7 @@ GEM
135
170
  lint_roller (~> 1.1)
136
171
  rubocop (~> 1.72, >= 1.72.1)
137
172
  rubocop-ast (>= 1.44.0, < 2.0)
138
- ruby-lsp (0.26.1)
173
+ ruby-lsp (0.26.2)
139
174
  language_server-protocol (~> 3.17.0)
140
175
  prism (>= 1.2, < 2.0)
141
176
  rbs (>= 3, < 5)
@@ -145,8 +180,8 @@ GEM
145
180
  stringio (3.1.7)
146
181
  syntax_tree (6.3.0)
147
182
  prettier_print (>= 1.2.0)
148
- tryouts (3.6.1)
149
- concurrent-ruby (~> 1.0)
183
+ tryouts (3.7.1)
184
+ concurrent-ruby (~> 1.0, < 2)
150
185
  irb
151
186
  minitest (~> 5.0)
152
187
  pastel (~> 0.8)
@@ -161,6 +196,8 @@ GEM
161
196
  unicode-display_width (3.2.0)
162
197
  unicode-emoji (~> 4.1)
163
198
  unicode-emoji (4.1.0)
199
+ user_agent_parser (2.20.0)
200
+ zeitwerk (2.7.3)
164
201
 
165
202
  PLATFORMS
166
203
  aarch64-linux-gnu
@@ -180,15 +217,17 @@ DEPENDENCIES
180
217
  rack-attack
181
218
  rack-test
182
219
  rackup
220
+ reek (~> 6.5)
183
221
  rspec (~> 3.13)
184
- rubocop (~> 1.81.1)
222
+ rubocop (~> 1.81.7)
185
223
  rubocop-performance
186
224
  rubocop-rspec
187
225
  rubocop-thread_safety
188
226
  ruby-lsp
189
227
  stackprof
190
228
  syntax_tree
191
- tryouts (~> 3.6.1)
229
+ tryouts (~> 3.7.1)
230
+ user_agent_parser (~> 2.18)
192
231
 
193
232
  BUNDLED WITH
194
233
  2.7.1
data/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  **Define your rack-apps in plain-text with built-in security.**
4
4
 
5
- > **v2.0.0-pre1 Available**: This pre-release includes major improvements to middleware management and test coverage. See [changelog](CHANGELOG.rst) and [migration guide](docs/migrating/v2.0.0-pre1.md) for upgraders.
5
+ > **v2.0.0-pre6 Available**: This pre-release includes major improvements to middleware management, logging, and request callback handling. See [changelog](CHANGELOG.rst) for details and upgrade notes.
6
6
 
7
7
  ![Otto mascot](public/img/otto.jpg "Otto - All Rack, no Pinion")
8
8
 
@@ -13,6 +13,14 @@ $ cd myapp && ls
13
13
  config.ru app.rb routes
14
14
  ```
15
15
 
16
+ ## Why Otto?
17
+
18
+ - **Security by Default**: Automatic IP masking for public addresses, user agent anonymization, CSRF protection, and input validation
19
+ - **Privacy First**: Masks public IPs, strips user agent versions, provides country-level geo-location only—no external APIs needed
20
+ - **Simple Routing**: Define routes in plain-text files with zero configuration overhead
21
+ - **Built-in Authentication**: Multiple strategies including API keys, tokens, role-based access, and custom implementations
22
+ - **Developer Friendly**: Works with any Rack server, minimal dependencies, easy testing and debugging
23
+
16
24
  ## Routes File
17
25
  ```
18
26
  # routes
@@ -76,6 +84,22 @@ app = Otto.new("./routes", {
76
84
 
77
85
  Security features include CSRF protection, input validation, security headers, and trusted proxy configuration.
78
86
 
87
+ ## Privacy by Default
88
+
89
+ Otto automatically masks public IP addresses and anonymizes user agents to comply with GDPR, CCPA, and other privacy regulations:
90
+
91
+ ```ruby
92
+ # Public IPs are automatically masked (203.0.113.9 → 203.0.113.0)
93
+ # Private IPs are NOT masked by default (127.0.0.1, 192.168.x.x, 10.x.x.x)
94
+ app = Otto.new("./routes")
95
+
96
+ # User agents: versions stripped for privacy
97
+ # Geo-location: country-level only, no external APIs or databases
98
+ # IP hashing: daily-rotating hashes enable analytics without tracking
99
+ ```
100
+
101
+ Private and localhost IPs are exempted by default for development convenience, but this behavior can be customized via `configure_ip_privacy()` method. Geolocation uses CDN headers (Cloudflare, AWS, etc.) with fallback to IP ranges—no external services required. See [CLAUDE.md](CLAUDE.md) for detailed configuration options.
102
+
79
103
  ## Internationalization Support
80
104
 
81
105
  Otto provides built-in locale detection and management:
@@ -132,6 +156,24 @@ end
132
156
 
133
157
  The locale helper checks multiple sources in order of precedence and validates against your configured locales.
134
158
 
159
+ ## Examples
160
+
161
+ Otto includes comprehensive examples demonstrating different features:
162
+
163
+ - **[Basic Example](examples/basic/)** - Get your first Otto app running in minutes
164
+ - **[Advanced Routes](examples/advanced_routes/)** - Response types, CSRF exemption, logic classes, and namespaced routing
165
+ - **[Authentication Strategies](examples/authentication_strategies/)** - Token, API key, and role-based authentication
166
+ - **[Security Features](examples/security_features/)** - CSRF protection, input validation, file uploads, and security headers
167
+ - **[MCP Demo](examples/mcp_demo/)** - JSON-RPC 2.0 endpoints for CLI automation and integrations
168
+
169
+ ### Standalone Tutorials
170
+
171
+ - **[Error Handler Registration](examples/error_handler_registration.rb)** - Prevent 500 errors for expected business exceptions
172
+ - **[Logging Improvements](examples/logging_improvements.rb)** - Structured logging with automatic timing
173
+ - **[Geo-location Extension](examples/simple_geo_resolver.rb)** - Extending geo-location with custom resolvers
174
+
175
+ See the [examples/](examples/) directory for more.
176
+
135
177
  ## Requirements
136
178
 
137
179
  - Ruby 3.2+
@@ -143,6 +185,12 @@ The locale helper checks multiple sources in order of precedence and validates a
143
185
  gem install otto
144
186
  ```
145
187
 
188
+ ## Documentation
189
+
190
+ - **[CLAUDE.md](CLAUDE.md)** - Comprehensive developer guidance covering authentication architecture, configuration freezing, IP privacy, structured logging, and multi-app patterns
191
+ - **[docs/](docs/)** - Technical guides and migration guides
192
+ - **[CHANGELOG.rst](CHANGELOG.rst)** - Version history, breaking changes, and upgrade notes
193
+
146
194
  ## AI Development Assistance
147
195
 
148
196
  Version 1.2.0's security features were developed with AI assistance:
@@ -1,33 +1,150 @@
1
1
  # Otto - Advanced Routes Example
2
2
 
3
- This example demonstrates the advanced routing syntax features available in Otto, such as response type negotiation, CSRF exemptions, and routing to logic classes.
3
+ This example demonstrates advanced routing features in Otto, including response type negotiation, CSRF exemptions, logic classes, and namespaced routing.
4
+
5
+ ## What You'll Learn
6
+
7
+ - How to define response types (JSON, view, redirect) in routes
8
+ - Using logic classes to encapsulate business logic
9
+ - CSRF exemption for APIs and webhooks
10
+ - Routing to namespaced classes with complex hierarchies
11
+ - Custom route parameters for flexible routing
12
+ - How Otto handles multiple controllers and modules
4
13
 
5
14
  ## Project Structure
6
15
 
7
- The example is structured to separate concerns, making it easier to navigate:
16
+ The example is organized to separate concerns:
8
17
 
9
- - `config.ru`: The main Rackup file that loads and runs the Otto application.
10
- - `routes`: A comprehensive file demonstrating various advanced routing syntaxes. This file serves as a good reference.
11
- - `app.rb`: A simple loader that requires all controller and logic files.
12
- - `app/controllers/`: Contains the `RoutesApp` class and other namespaced controller modules that handle incoming requests.
13
- - `app/logic/`: Contains various "Logic Classes". These are special classes that can be routed to directly, encapsulating business logic for a specific route. They are organized into namespaces to show how Otto handles complex class names.
14
- - `run.rb`, `puma.rb`, `test.rb`: Alternative ways to run or test the application.
18
+ - `config.ru`: Rack configuration that loads and runs the Otto application
19
+ - `routes`: Comprehensive reference for advanced routing syntax
20
+ - `app.rb`: Loader that requires all controller and logic files
21
+ - `app/controllers/`: Handler classes (`RoutesApp`, namespaced controllers)
22
+ - `app/logic/`: Business logic classes (simple, nested, namespaced)
23
+ - `run.rb`, `puma.rb`, `test.rb`: Alternative server/test runners
15
24
 
16
25
  ## Key Features Demonstrated
17
26
 
18
- - **Response Types:** Defining `response=json`, `response=view`, etc., directly in the `routes` file.
19
- - **CSRF Exemption:** Using `csrf=exempt` for APIs or webhooks.
20
- - **Logic Classes:** Routing directly to a class (e.g., `GET /logic/simple SimpleLogic`). Otto automatically instantiates it and calls its `process` method.
21
- - **Namespaced Targets:** Routing to deeply namespaced classes and modules (e.g., `GET /logic/v2/dashboard V2::Logic::Dashboard`).
22
- - **Custom Parameters:** Adding arbitrary key-value parameters to a route for custom logic.
27
+ ### Response Types
28
+ Define how responses are formatted directly in routes:
29
+ ```
30
+ GET /api/users UserController#list response=json
31
+ GET /page PageController#show response=view
32
+ GET /old-url PageController#new-url response=redirect
33
+ ```
34
+
35
+ ### Logic Classes
36
+ Route to specialized classes that encapsulate business logic:
37
+ ```
38
+ GET /calculate DataProcessor # Otto auto-instantiates and calls #process
39
+ GET /report ReportGenerator # Same pattern
40
+ ```
41
+
42
+ ### CSRF Exemption
43
+ Mark routes that don't need CSRF tokens (APIs, webhooks):
44
+ ```
45
+ POST /api/webhook WebhookHandler#receive csrf=exempt
46
+ ```
47
+
48
+ ### Namespaced Routing
49
+ Handle complex class hierarchies naturally:
50
+ ```
51
+ GET /v2/dashboard V2::Logic::Dashboard
52
+ GET /admin/panel Admin::Panel#dashboard
53
+ ```
54
+
55
+ ### Custom Parameters
56
+ Add arbitrary key-value pairs for flexible routing:
57
+ ```
58
+ GET /admin AdminPanel#dashboard role=admin
59
+ ```
60
+
61
+ ## How to Run
62
+
63
+ ### Using rackup (recommended)
64
+
65
+ ```sh
66
+ cd examples/advanced_routes
67
+ rackup config.ru
68
+ ```
69
+
70
+ ### Using alternative runners
71
+
72
+ ```sh
73
+ ruby run.rb # Basic rackup
74
+ ruby puma.rb # Using puma server
75
+ ruby test.rb # For testing
76
+ ```
77
+
78
+ The application will be running at `http://localhost:9292`.
79
+
80
+ ## Testing Routes
81
+
82
+ Use curl to test the different routes:
83
+
84
+ ```sh
85
+ # JSON response
86
+ curl http://localhost:9292/json/test
87
+
88
+ # View response
89
+ curl http://localhost:9292/view/test
90
+
91
+ # Logic class routing
92
+ curl http://localhost:9292/logic/simple
93
+
94
+ # Namespaced routing
95
+ curl http://localhost:9292/logic/v2/dashboard
96
+
97
+ # Custom parameters
98
+ curl "http://localhost:9292/custom?role=admin"
99
+ ```
100
+
101
+ ## Expected Output
102
+
103
+ ```
104
+ Listening on 127.0.0.1:9292, CTRL+C to stop
105
+
106
+ [JSON response]
107
+ GET /json/test 200 OK
108
+ Content-Type: application/json
109
+ {"status": "success", "data": {...}}
110
+
111
+ [Logic class routing]
112
+ GET /logic/simple 200 OK
113
+ {"processed": true, "input": "test"}
114
+
115
+ [Namespaced routing]
116
+ GET /logic/v2/dashboard 200 OK
117
+ {"version": "2.0", "dashboard": {...}}
118
+ ```
119
+
120
+ ## File Structure Details
121
+
122
+ ### Routes File
123
+ The `routes` file is extensively commented to explain each feature:
124
+ - Response type specification
125
+ - CSRF exemption for APIs
126
+ - Logic class routing syntax
127
+ - Namespaced class resolution
128
+ - Custom parameter examples
129
+
130
+ ### Controllers (`app/controllers/`)
131
+ - `RoutesApp`: Main controller with basic handlers
132
+ - Namespaced modules: Demonstrate complex class hierarchies
133
+ - Handlers return appropriate responses (JSON, HTML, redirects)
134
+
135
+ ### Logic Classes (`app/logic/`)
136
+ - Simple classes: Basic business logic
137
+ - Nested classes: Show how Otto handles namespace resolution
138
+ - Parameterized logic: Demonstrate custom route parameters
23
139
 
24
- ## Running the Example
140
+ ## Next Steps
25
141
 
26
- 1. Make sure you have the necessary gems installed (`bundle install`).
27
- 2. Run the application from the root of the `otto` project:
142
+ - Review the `routes` file for syntax reference
143
+ - Examine handler methods to see request/response patterns
144
+ - Check logic classes for business logic encapsulation patterns
145
+ - Explore [Authentication](../authentication_strategies/) for protecting routes
146
+ - See [Security Features](../security_features/) for CSRF, validation, file uploads
28
147
 
29
- ```sh
30
- rackup examples/advanced_routes/config.ru
31
- ```
148
+ ## Further Reading
32
149
 
33
- 3. The application will be running at `http://localhost:9292`. You can use `curl` or your browser to test the various routes defined in the `routes` file.
150
+ - [CLAUDE.md](../../CLAUDE.md) - Comprehensive developer guidance