otto 1.5.0 → 2.0.0.pre1

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 +44 -5
  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 +24 -345
  7. data/CHANGELOG.rst +83 -0
  8. data/CLAUDE.md +56 -0
  9. data/Gemfile +21 -5
  10. data/Gemfile.lock +69 -31
  11. data/README.md +2 -0
  12. data/bin/rspec +16 -0
  13. data/changelog.d/20250911_235619_delano_next.rst +28 -0
  14. data/changelog.d/20250912_123055_delano_remove_ostruct.rst +21 -0
  15. data/changelog.d/20250912_175625_claude_delano_remove_ostruct.rst +21 -0
  16. data/changelog.d/README.md +120 -0
  17. data/changelog.d/scriv.ini +5 -0
  18. data/docs/.gitignore +1 -0
  19. data/docs/migrating/v2.0.0-pre1.md +276 -0
  20. data/examples/.gitignore +1 -0
  21. data/examples/advanced_routes/README.md +33 -0
  22. data/examples/advanced_routes/app/controllers/handlers/async.rb +9 -0
  23. data/examples/advanced_routes/app/controllers/handlers/dynamic.rb +9 -0
  24. data/examples/advanced_routes/app/controllers/handlers/static.rb +9 -0
  25. data/examples/advanced_routes/app/controllers/modules/auth.rb +9 -0
  26. data/examples/advanced_routes/app/controllers/modules/transformer.rb +9 -0
  27. data/examples/advanced_routes/app/controllers/modules/validator.rb +9 -0
  28. data/examples/advanced_routes/app/controllers/routes_app.rb +232 -0
  29. data/examples/advanced_routes/app/controllers/v2/admin.rb +9 -0
  30. data/examples/advanced_routes/app/controllers/v2/config.rb +9 -0
  31. data/examples/advanced_routes/app/controllers/v2/settings.rb +9 -0
  32. data/examples/advanced_routes/app/logic/admin/logic/manager.rb +27 -0
  33. data/examples/advanced_routes/app/logic/admin/panel.rb +27 -0
  34. data/examples/advanced_routes/app/logic/analytics_processor.rb +25 -0
  35. data/examples/advanced_routes/app/logic/complex/business/handler.rb +27 -0
  36. data/examples/advanced_routes/app/logic/data_logic.rb +23 -0
  37. data/examples/advanced_routes/app/logic/data_processor.rb +25 -0
  38. data/examples/advanced_routes/app/logic/input_validator.rb +24 -0
  39. data/examples/advanced_routes/app/logic/nested/feature/logic.rb +27 -0
  40. data/examples/advanced_routes/app/logic/reports_generator.rb +27 -0
  41. data/examples/advanced_routes/app/logic/simple_logic.rb +25 -0
  42. data/examples/advanced_routes/app/logic/system/config/manager.rb +27 -0
  43. data/examples/advanced_routes/app/logic/test_logic.rb +23 -0
  44. data/examples/advanced_routes/app/logic/transform_logic.rb +23 -0
  45. data/examples/advanced_routes/app/logic/upload_logic.rb +23 -0
  46. data/examples/advanced_routes/app/logic/v2/logic/dashboard.rb +27 -0
  47. data/examples/advanced_routes/app/logic/v2/logic/processor.rb +27 -0
  48. data/examples/advanced_routes/app.rb +33 -0
  49. data/examples/advanced_routes/config.rb +23 -0
  50. data/examples/advanced_routes/config.ru +7 -0
  51. data/examples/advanced_routes/puma.rb +20 -0
  52. data/examples/advanced_routes/routes +167 -0
  53. data/examples/advanced_routes/run.rb +39 -0
  54. data/examples/advanced_routes/test.rb +58 -0
  55. data/examples/authentication_strategies/README.md +32 -0
  56. data/examples/authentication_strategies/app/auth.rb +68 -0
  57. data/examples/authentication_strategies/app/controllers/auth_controller.rb +29 -0
  58. data/examples/authentication_strategies/app/controllers/main_controller.rb +28 -0
  59. data/examples/authentication_strategies/config.ru +24 -0
  60. data/examples/authentication_strategies/routes +37 -0
  61. data/examples/basic/README.md +29 -0
  62. data/examples/basic/app.rb +7 -35
  63. data/examples/basic/routes +0 -9
  64. data/examples/mcp_demo/README.md +87 -0
  65. data/examples/mcp_demo/app.rb +51 -0
  66. data/examples/mcp_demo/config.ru +17 -0
  67. data/examples/mcp_demo/routes +9 -0
  68. data/examples/security_features/README.md +46 -0
  69. data/examples/security_features/app.rb +23 -24
  70. data/examples/security_features/config.ru +8 -10
  71. data/lib/otto/core/configuration.rb +167 -0
  72. data/lib/otto/core/error_handler.rb +86 -0
  73. data/lib/otto/core/file_safety.rb +61 -0
  74. data/lib/otto/core/middleware_stack.rb +157 -0
  75. data/lib/otto/core/router.rb +183 -0
  76. data/lib/otto/core/uri_generator.rb +44 -0
  77. data/lib/otto/design_system.rb +7 -5
  78. data/lib/otto/helpers/base.rb +3 -0
  79. data/lib/otto/helpers/request.rb +10 -8
  80. data/lib/otto/helpers/response.rb +5 -4
  81. data/lib/otto/helpers/validation.rb +85 -0
  82. data/lib/otto/mcp/auth/token.rb +77 -0
  83. data/lib/otto/mcp/protocol.rb +164 -0
  84. data/lib/otto/mcp/rate_limiting.rb +155 -0
  85. data/lib/otto/mcp/registry.rb +100 -0
  86. data/lib/otto/mcp/route_parser.rb +77 -0
  87. data/lib/otto/mcp/server.rb +206 -0
  88. data/lib/otto/mcp/validation.rb +123 -0
  89. data/lib/otto/response_handlers/auto.rb +39 -0
  90. data/lib/otto/response_handlers/base.rb +16 -0
  91. data/lib/otto/response_handlers/default.rb +16 -0
  92. data/lib/otto/response_handlers/factory.rb +39 -0
  93. data/lib/otto/response_handlers/json.rb +28 -0
  94. data/lib/otto/response_handlers/redirect.rb +25 -0
  95. data/lib/otto/response_handlers/view.rb +24 -0
  96. data/lib/otto/response_handlers.rb +9 -135
  97. data/lib/otto/route.rb +9 -9
  98. data/lib/otto/route_definition.rb +30 -33
  99. data/lib/otto/route_handlers/base.rb +121 -0
  100. data/lib/otto/route_handlers/class_method.rb +89 -0
  101. data/lib/otto/route_handlers/factory.rb +29 -0
  102. data/lib/otto/route_handlers/instance_method.rb +69 -0
  103. data/lib/otto/route_handlers/lambda.rb +59 -0
  104. data/lib/otto/route_handlers/logic_class.rb +93 -0
  105. data/lib/otto/route_handlers.rb +10 -376
  106. data/lib/otto/security/authentication/auth_strategy.rb +44 -0
  107. data/lib/otto/security/authentication/authentication_middleware.rb +123 -0
  108. data/lib/otto/security/authentication/failure_result.rb +36 -0
  109. data/lib/otto/security/authentication/strategies/api_key_strategy.rb +40 -0
  110. data/lib/otto/security/authentication/strategies/permission_strategy.rb +47 -0
  111. data/lib/otto/security/authentication/strategies/public_strategy.rb +19 -0
  112. data/lib/otto/security/authentication/strategies/role_strategy.rb +57 -0
  113. data/lib/otto/security/authentication/strategies/session_strategy.rb +41 -0
  114. data/lib/otto/security/authentication/strategy_result.rb +223 -0
  115. data/lib/otto/security/authentication.rb +28 -282
  116. data/lib/otto/security/config.rb +15 -11
  117. data/lib/otto/security/configurator.rb +219 -0
  118. data/lib/otto/security/csrf.rb +8 -143
  119. data/lib/otto/security/middleware/csrf_middleware.rb +151 -0
  120. data/lib/otto/security/middleware/rate_limit_middleware.rb +38 -0
  121. data/lib/otto/security/middleware/validation_middleware.rb +252 -0
  122. data/lib/otto/security/rate_limiter.rb +86 -0
  123. data/lib/otto/security/rate_limiting.rb +16 -0
  124. data/lib/otto/security/validator.rb +8 -292
  125. data/lib/otto/static.rb +3 -0
  126. data/lib/otto/utils.rb +14 -0
  127. data/lib/otto/version.rb +3 -1
  128. data/lib/otto.rb +184 -414
  129. data/otto.gemspec +11 -6
  130. metadata +134 -25
  131. data/examples/dynamic_pages/app.rb +0 -115
  132. data/examples/dynamic_pages/config.ru +0 -30
  133. data/examples/dynamic_pages/routes +0 -21
  134. data/examples/helpers_demo/app.rb +0 -244
  135. data/examples/helpers_demo/config.ru +0 -26
  136. data/examples/helpers_demo/routes +0 -7
@@ -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
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module V2
4
+ module Logic
5
+ class Processor
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_processor: 'Complete',
17
+ csrf_exempt: true,
18
+ processing_time: 0.05,
19
+ }
20
+ end
21
+
22
+ def response_data
23
+ { v2_processor: process }
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Application Loader
4
+
5
+ # Controllers
6
+ require_relative 'app/controllers/routes_app'
7
+ require_relative 'app/controllers/handlers/async'
8
+ require_relative 'app/controllers/handlers/dynamic'
9
+ require_relative 'app/controllers/handlers/static'
10
+ require_relative 'app/controllers/modules/auth'
11
+ require_relative 'app/controllers/modules/transformer'
12
+ require_relative 'app/controllers/modules/validator'
13
+ require_relative 'app/controllers/v2/admin'
14
+ require_relative 'app/controllers/v2/config'
15
+ require_relative 'app/controllers/v2/settings'
16
+
17
+ # Logic Classes
18
+ require_relative 'app/logic/admin/logic/manager'
19
+ require_relative 'app/logic/admin/panel'
20
+ require_relative 'app/logic/analytics_processor'
21
+ require_relative 'app/logic/complex/business/handler'
22
+ require_relative 'app/logic/data_logic'
23
+ require_relative 'app/logic/data_processor'
24
+ require_relative 'app/logic/input_validator'
25
+ require_relative 'app/logic/nested/feature/logic'
26
+ require_relative 'app/logic/reports_generator'
27
+ require_relative 'app/logic/simple_logic'
28
+ require_relative 'app/logic/system/config/manager'
29
+ require_relative 'app/logic/test_logic'
30
+ require_relative 'app/logic/transform_logic'
31
+ require_relative 'app/logic/upload_logic'
32
+ require_relative 'app/logic/v2/logic/dashboard'
33
+ require_relative 'app/logic/v2/logic/processor'
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rack'
4
+ require_relative '../../lib/otto'
5
+ require_relative 'app'
6
+
7
+ # Simple Otto configuration demonstrating advanced routes syntax
8
+ otto = Otto.new('routes')
9
+
10
+ # Enable basic security features to demonstrate CSRF functionality
11
+ otto.enable_csrf_protection!
12
+
13
+ # Set error handlers
14
+ otto.not_found = lambda do |_env|
15
+ RoutesApp.not_found
16
+ end
17
+
18
+ otto.server_error = lambda do |_env, _error|
19
+ RoutesApp.server_error
20
+ end
21
+
22
+ # Return the configured app. This allows runner scripts to use the same instance.
23
+ otto
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Load the app from our shared config file.
4
+ # This returns a configured Otto instance.
5
+ app = require_relative 'config'
6
+
7
+ run app
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'puma'
5
+
6
+ # The shared config file returns the configured Otto app
7
+ otto_app = require_relative 'config'
8
+
9
+ # Configure Puma server
10
+ Puma::Server.new(otto_app).tap do |server|
11
+ server.add_tcp_listener '127.0.0.1', 9292
12
+
13
+ puts "Otto Advanced Routes Example running on http://localhost:9292"
14
+ puts "Press Ctrl+C to stop"
15
+
16
+ # Handle Ctrl+C gracefully
17
+ trap('INT') { server.stop }
18
+
19
+ server.run
20
+ end
@@ -0,0 +1,167 @@
1
+ # Advanced Routes Syntax - Otto v1.5.0+ Features
2
+ # This file demonstrates the advanced routing syntax without complex authentication
3
+
4
+ # ========================================
5
+ # BASIC ROUTES (Original Otto Syntax)
6
+ # ========================================
7
+
8
+ GET / RoutesApp#index
9
+ POST /feedback RoutesApp#receive_feedback
10
+
11
+ # ========================================
12
+ # RESPONSE TYPE ROUTES
13
+ # ========================================
14
+
15
+ # JSON response routes
16
+ GET /api/users RoutesApp#list_users response=json
17
+ POST /api/users RoutesApp#create_user response=json
18
+ GET /api/health RoutesApp#health_check response=json
19
+ PUT /api/users/:id RoutesApp#update_user response=json
20
+ DELETE /api/users/:id RoutesApp#delete_user response=json
21
+
22
+ # View/HTML response routes
23
+ GET /dashboard RoutesApp#dashboard response=view
24
+ GET /reports RoutesApp#reports response=view
25
+ GET /admin RoutesApp#admin_panel response=view
26
+
27
+ # Redirect response routes
28
+ GET /login RoutesApp#login_redirect response=redirect
29
+ GET /logout RoutesApp#logout_redirect response=redirect
30
+ GET /home RoutesApp#home_redirect response=redirect
31
+
32
+ # Auto response type (content negotiation)
33
+ GET /data RoutesApp#flexible_data response=auto
34
+ GET /content RoutesApp#flexible_content response=auto
35
+
36
+ # ========================================
37
+ # CSRF PROTECTION ROUTES
38
+ # ========================================
39
+
40
+ # CSRF exempt routes (useful for APIs and webhooks)
41
+ POST /api/webhook RoutesApp#webhook_handler csrf=exempt
42
+ PUT /api/external RoutesApp#external_update csrf=exempt
43
+ DELETE /api/cleanup RoutesApp#cleanup_data csrf=exempt
44
+ PATCH /api/sync RoutesApp#sync_data csrf=exempt
45
+
46
+ # Standard CSRF protected routes (default behavior)
47
+ POST /settings RoutesApp#update_settings
48
+ PUT /password RoutesApp#change_password
49
+ DELETE /profile RoutesApp#delete_profile
50
+
51
+ # ========================================
52
+ # MULTIPLE PARAMETER COMBINATIONS
53
+ # ========================================
54
+
55
+ # API routes with response type and CSRF exemption
56
+ GET /api/v1/data RoutesApp#api_data response=json
57
+ POST /api/v1/submit RoutesApp#api_submit response=json csrf=exempt
58
+ PUT /api/v1/update RoutesApp#api_update response=json csrf=exempt
59
+
60
+ # View routes with multiple parameters
61
+ GET /admin/dashboard RoutesApp#admin_dashboard response=view
62
+ POST /admin/settings RoutesApp#admin_settings response=view
63
+
64
+ # Mixed content routes
65
+ GET /mixed/endpoint RoutesApp#mixed_content response=auto csrf=exempt
66
+
67
+ # ========================================
68
+ # LOGIC CLASS ROUTES (New in v1.5.0+)
69
+ # ========================================
70
+
71
+ # Simple Logic class (no . or # in target)
72
+ GET /logic/simple SimpleLogic
73
+ POST /logic/process DataProcessor
74
+ PUT /logic/validate InputValidator
75
+
76
+ # Namespaced Logic classes
77
+ GET /logic/admin Admin::Panel
78
+ GET /logic/reports Reports::Generator
79
+ POST /logic/analytics Analytics::Processor
80
+
81
+ # Logic classes with parameters
82
+ GET /logic/data DataLogic response=json
83
+ POST /logic/upload UploadLogic response=json csrf=exempt
84
+ PUT /logic/transform TransformLogic response=json
85
+
86
+ # Complex namespaced Logic routes
87
+ GET /logic/v2/dashboard V2::Logic::Dashboard response=view
88
+ POST /logic/v2/process V2::Logic::Processor response=json csrf=exempt
89
+ GET /logic/admin/manager Admin::Logic::Manager response=json
90
+
91
+ # Deeply nested Logic classes
92
+ GET /logic/nested/feature Nested::Feature::Logic
93
+ POST /logic/complex/handler Complex::Business::Handler response=json
94
+ PUT /logic/system/config System::Config::Manager response=json csrf=exempt
95
+
96
+ # ========================================
97
+ # NAMESPACED CLASS ROUTES
98
+ # ========================================
99
+
100
+ # Class method routes with namespaces
101
+ GET /v2/admin V2::Admin.show response=view
102
+ POST /v2/config V2::Config.update response=json
103
+ PUT /v2/settings V2::Settings.modify response=json csrf=exempt
104
+
105
+ # Instance method routes with namespaces
106
+ GET /modules/auth Modules::Auth#process
107
+ POST /modules/validator Modules::Validator#validate response=json
108
+ PUT /modules/transformer Modules::Transformer#transform response=json csrf=exempt
109
+
110
+ # Mixed class and instance methods
111
+ GET /handlers/static Handlers::Static.serve
112
+ POST /handlers/dynamic Handlers::Dynamic#process response=json
113
+ PUT /handlers/async Handlers::Async#execute response=json csrf=exempt
114
+
115
+ # ========================================
116
+ # CUSTOM PARAMETERS
117
+ # ========================================
118
+
119
+ # Routes with custom configuration parameters
120
+ GET /config/env RoutesApp#show_config env=production
121
+ GET /config/debug RoutesApp#debug_info env=development debug=true
122
+ POST /config/update RoutesApp#update_config env=production response=json
123
+
124
+ # Routes with multiple custom parameters
125
+ GET /feature/flags RoutesApp#feature_flags feature=advanced mode=enabled
126
+ POST /feature/toggle RoutesApp#toggle_feature feature=beta mode=test response=json csrf=exempt
127
+
128
+ # ========================================
129
+ # PARAMETER VALUE VARIATIONS
130
+ # ========================================
131
+
132
+ # Parameters with special values
133
+ GET /api/v1 RoutesApp#api_v1 version=1.0 response=json
134
+ GET /api/v2 RoutesApp#api_v2 version=2.0 response=json
135
+ POST /api/legacy RoutesApp#api_legacy version=legacy response=json csrf=exempt
136
+
137
+ # Parameters with equals in values (edge case)
138
+ GET /query/complex RoutesApp#complex_query filter=key=value response=json
139
+ POST /config/connection RoutesApp#config_db connection=host=localhost csrf=exempt
140
+
141
+ # ========================================
142
+ # ERROR HANDLERS
143
+ # ========================================
144
+
145
+ GET /404 RoutesApp#not_found response=view
146
+ GET /500 RoutesApp#server_error response=view
147
+
148
+ # ========================================
149
+ # TESTING ROUTES
150
+ # ========================================
151
+
152
+ # Routes for testing different parameter combinations
153
+ GET /test/json RoutesApp#test_json response=json
154
+ GET /test/view RoutesApp#test_view response=view
155
+ GET /test/redirect RoutesApp#test_redirect response=redirect
156
+ GET /test/auto RoutesApp#test_auto response=auto
157
+
158
+ POST /test/csrf RoutesApp#test_csrf
159
+ POST /test/no-csrf RoutesApp#test_no_csrf csrf=exempt
160
+
161
+ GET /test/logic TestLogic
162
+ POST /test/logic-json TestLogic response=json
163
+ PUT /test/logic-exempt TestLogic response=json csrf=exempt
164
+
165
+ # Complex test routes
166
+ GET /test/complex TestLogic response=auto
167
+ POST /test/everything RoutesApp#test_everything response=json csrf=exempt custom=value