otto 2.0.0.pre3 → 2.0.0.pre7
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 +4 -4
- data/.github/workflows/ci.yml +1 -1
- data/.github/workflows/claude-code-review.yml +1 -1
- data/.github/workflows/code-smells.yml +146 -0
- data/.gitignore +4 -0
- data/.pre-commit-config.yaml +2 -2
- data/.reek.yml +99 -0
- data/CHANGELOG.rst +90 -0
- data/CLAUDE.md +74 -540
- data/Gemfile +4 -2
- data/Gemfile.lock +58 -19
- data/README.md +49 -1
- data/changelog.d/20251103_235431_delano_86_improve_error_logging.rst +15 -0
- data/changelog.d/20251109_025012_claude_fix_backtrace_sanitization.rst +37 -0
- data/examples/advanced_routes/README.md +137 -20
- data/examples/authentication_strategies/README.md +212 -19
- data/examples/backtrace_sanitization_demo.rb +86 -0
- data/examples/basic/README.md +61 -10
- data/examples/error_handler_registration.rb +136 -0
- data/examples/logging_improvements.rb +76 -0
- data/examples/mcp_demo/README.md +187 -27
- data/examples/security_features/README.md +249 -30
- data/examples/simple_geo_resolver.rb +107 -0
- data/lib/otto/core/configuration.rb +15 -20
- data/lib/otto/core/error_handler.rb +138 -8
- data/lib/otto/core/file_safety.rb +2 -2
- data/lib/otto/core/freezable.rb +2 -2
- data/lib/otto/core/middleware_stack.rb +2 -2
- data/lib/otto/core/router.rb +61 -8
- data/lib/otto/core/uri_generator.rb +2 -2
- data/lib/otto/core.rb +2 -0
- data/lib/otto/design_system.rb +2 -2
- data/lib/otto/env_keys.rb +61 -12
- data/lib/otto/helpers/base.rb +2 -2
- data/lib/otto/helpers/request.rb +8 -3
- data/lib/otto/helpers/response.rb +2 -2
- data/lib/otto/helpers/validation.rb +2 -2
- data/lib/otto/helpers.rb +2 -0
- data/lib/otto/locale/config.rb +2 -2
- data/lib/otto/locale/middleware.rb +160 -0
- data/lib/otto/locale.rb +10 -0
- data/lib/otto/logging_helpers.rb +273 -0
- data/lib/otto/mcp/auth/token.rb +2 -2
- data/lib/otto/mcp/protocol.rb +2 -2
- data/lib/otto/mcp/rate_limiting.rb +2 -2
- data/lib/otto/mcp/registry.rb +2 -2
- data/lib/otto/mcp/route_parser.rb +2 -2
- data/lib/otto/mcp/schema_validation.rb +2 -2
- data/lib/otto/mcp/server.rb +2 -2
- data/lib/otto/mcp.rb +2 -0
- data/lib/otto/privacy/config.rb +2 -0
- data/lib/otto/privacy/geo_resolver.rb +199 -29
- data/lib/otto/privacy/ip_privacy.rb +2 -0
- data/lib/otto/privacy/redacted_fingerprint.rb +18 -8
- data/lib/otto/privacy.rb +2 -0
- data/lib/otto/response_handlers/auto.rb +2 -0
- data/lib/otto/response_handlers/base.rb +2 -0
- data/lib/otto/response_handlers/default.rb +2 -0
- data/lib/otto/response_handlers/factory.rb +2 -0
- data/lib/otto/response_handlers/json.rb +2 -0
- data/lib/otto/response_handlers/redirect.rb +2 -0
- data/lib/otto/response_handlers/view.rb +2 -0
- data/lib/otto/response_handlers.rb +2 -2
- data/lib/otto/route.rb +4 -4
- data/lib/otto/route_definition.rb +42 -15
- data/lib/otto/route_handlers/base.rb +2 -0
- data/lib/otto/route_handlers/class_method.rb +18 -25
- data/lib/otto/route_handlers/factory.rb +2 -2
- data/lib/otto/route_handlers/instance_method.rb +8 -5
- data/lib/otto/route_handlers/lambda.rb +8 -20
- data/lib/otto/route_handlers/logic_class.rb +23 -6
- data/lib/otto/route_handlers.rb +2 -2
- data/lib/otto/security/authentication/auth_failure.rb +2 -2
- data/lib/otto/security/authentication/auth_strategy.rb +11 -4
- data/lib/otto/security/authentication/route_auth_wrapper.rb +230 -78
- data/lib/otto/security/authentication/strategies/api_key_strategy.rb +2 -0
- data/lib/otto/security/authentication/strategies/noauth_strategy.rb +2 -0
- data/lib/otto/security/authentication/strategies/permission_strategy.rb +2 -0
- data/lib/otto/security/authentication/strategies/role_strategy.rb +2 -0
- data/lib/otto/security/authentication/strategies/session_strategy.rb +2 -0
- data/lib/otto/security/authentication/strategy_result.rb +6 -5
- data/lib/otto/security/authentication.rb +2 -2
- data/lib/otto/security/authorization_error.rb +73 -0
- data/lib/otto/security/config.rb +2 -2
- data/lib/otto/security/configurator.rb +17 -2
- data/lib/otto/security/csrf.rb +2 -2
- data/lib/otto/security/middleware/csrf_middleware.rb +11 -1
- data/lib/otto/security/middleware/ip_privacy_middleware.rb +31 -11
- data/lib/otto/security/middleware/rate_limit_middleware.rb +2 -0
- data/lib/otto/security/middleware/validation_middleware.rb +15 -0
- data/lib/otto/security/rate_limiter.rb +2 -2
- data/lib/otto/security/rate_limiting.rb +2 -2
- data/lib/otto/security/validator.rb +2 -2
- data/lib/otto/security.rb +3 -0
- data/lib/otto/static.rb +2 -2
- data/lib/otto/utils.rb +27 -2
- data/lib/otto/version.rb +3 -3
- data/lib/otto.rb +174 -14
- data/otto.gemspec +7 -3
- metadata +24 -15
- data/benchmark_middleware_wrap.rb +0 -163
- data/changelog.d/20251014_144317_delano_54_thats_a_wrapper.rst +0 -36
- data/changelog.d/20251014_161526_delano_54_thats_a_wrapper.rst +0 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 69a46d80f1fcc3f2472c44554fd7102645226e264befdd23af9871ad4f5fafaf
|
|
4
|
+
data.tar.gz: 54d8b433d49b549e17d3406aa011b6f4f80c50eefc5a6fa51dde1772fde8b8f2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b518140043ad7ab983fb99e85ac9643ca4527385930d77a4b01e2b241b7212854fbc5e8875bc58b17e3d17c66fcfc6455b85587d023ceec13006876bec79a0d9
|
|
7
|
+
data.tar.gz: f64b842b58acc746ad39d58eac0fb57c245f1db29755f89d259d64bd127db3043034a9e8ada0ee19c04d969ec1bb34b515f5dfc1fcf36c80ceaeb9123ac2de6e
|
data/.github/workflows/ci.yml
CHANGED
|
@@ -45,7 +45,7 @@ jobs:
|
|
|
45
45
|
bundler-cache: ${{ !matrix.experimental }}
|
|
46
46
|
|
|
47
47
|
- name: Setup tmate session
|
|
48
|
-
uses: mxschmitt/action-tmate@
|
|
48
|
+
uses: mxschmitt/action-tmate@c0afd6f790e3a5564914980036ebf83216678101 # v3
|
|
49
49
|
if: ${{ github.event_name == 'workflow_dispatch' && inputs.debug_enabled }}
|
|
50
50
|
with:
|
|
51
51
|
detached: true
|
|
@@ -54,7 +54,7 @@ jobs:
|
|
|
54
54
|
- name: Remove claude-review label
|
|
55
55
|
# Remove label whether success or failure - prevents getting stuck
|
|
56
56
|
if: always() && github.event.action != 'opened'
|
|
57
|
-
uses: actions/github-script@
|
|
57
|
+
uses: actions/github-script@v8
|
|
58
58
|
with:
|
|
59
59
|
script: |
|
|
60
60
|
try {
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
# .github/workflows/code-smells.yml
|
|
2
|
+
---
|
|
3
|
+
name: Code Smells
|
|
4
|
+
|
|
5
|
+
on:
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
push:
|
|
9
|
+
branches: [main]
|
|
10
|
+
workflow_dispatch:
|
|
11
|
+
|
|
12
|
+
permissions:
|
|
13
|
+
contents: read
|
|
14
|
+
pull-requests: write # Needed to post comments on PRs
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
reek-analysis:
|
|
18
|
+
name: Reek Code Analysis
|
|
19
|
+
runs-on: ubuntu-24.04
|
|
20
|
+
timeout-minutes: 5
|
|
21
|
+
|
|
22
|
+
steps:
|
|
23
|
+
- name: Checkout code
|
|
24
|
+
uses: actions/checkout@v5
|
|
25
|
+
|
|
26
|
+
- name: Set up Ruby
|
|
27
|
+
uses: ruby/setup-ruby@v1
|
|
28
|
+
with:
|
|
29
|
+
ruby-version: 3.4
|
|
30
|
+
bundler-cache: true
|
|
31
|
+
|
|
32
|
+
- name: Configure Bundler for secure gem installation
|
|
33
|
+
run: |
|
|
34
|
+
bundle config set --local path 'vendor/bundle'
|
|
35
|
+
bundle config set --local deployment 'false'
|
|
36
|
+
|
|
37
|
+
- name: Install dependencies
|
|
38
|
+
run: bundle install --jobs 4 --retry 3
|
|
39
|
+
|
|
40
|
+
- name: Run Reek analysis
|
|
41
|
+
run: |
|
|
42
|
+
echo "=== Running Reek code analysis ==="
|
|
43
|
+
echo "This analysis identifies code smells and potential improvements."
|
|
44
|
+
echo "Results are informational and won't fail the build."
|
|
45
|
+
echo ""
|
|
46
|
+
|
|
47
|
+
# Run reek and capture output (don't fail on warnings)
|
|
48
|
+
# Use success-exit-code to prevent failures from stopping the analysis
|
|
49
|
+
bundle exec reek --format=text --success-exit-code 0 --failure-exit-code 0 || true
|
|
50
|
+
|
|
51
|
+
echo ""
|
|
52
|
+
echo "=== Reek analysis complete ==="
|
|
53
|
+
continue-on-error: true # Don't fail the build on code smells
|
|
54
|
+
|
|
55
|
+
- name: Generate Reek report
|
|
56
|
+
run: |
|
|
57
|
+
echo "=== Generating detailed Reek report ==="
|
|
58
|
+
|
|
59
|
+
# Generate JSON report for potential future processing
|
|
60
|
+
bundle exec reek --format=json --success-exit-code 0 --failure-exit-code 0 > reek-report.json || true
|
|
61
|
+
|
|
62
|
+
# If no JSON was generated, create an empty valid JSON array
|
|
63
|
+
if [ ! -s reek-report.json ]; then
|
|
64
|
+
echo "[]" > reek-report.json
|
|
65
|
+
echo "No code smells detected - created empty report"
|
|
66
|
+
else
|
|
67
|
+
echo "Reek JSON report generated: $(wc -l < reek-report.json) lines"
|
|
68
|
+
echo "Top code smell types found:"
|
|
69
|
+
jq -r '.[].smells[].smell_type' reek-report.json 2>/dev/null | sort | uniq -c | sort -rn | head -10 || echo "Unable to parse JSON report"
|
|
70
|
+
fi
|
|
71
|
+
|
|
72
|
+
# Also generate a human-readable HTML report for easier viewing
|
|
73
|
+
bundle exec reek --format=html --success-exit-code 0 --failure-exit-code 0 > reek-report.html || echo "<!-- No code smells detected -->" > reek-report.html
|
|
74
|
+
continue-on-error: true
|
|
75
|
+
|
|
76
|
+
- name: Upload Reek report as artifact
|
|
77
|
+
uses: actions/upload-artifact@v5
|
|
78
|
+
if: always()
|
|
79
|
+
with:
|
|
80
|
+
name: reek-report
|
|
81
|
+
path: |
|
|
82
|
+
reek-report.json
|
|
83
|
+
reek-report.html
|
|
84
|
+
if-no-files-found: ignore
|
|
85
|
+
retention-days: 30
|
|
86
|
+
|
|
87
|
+
additional-checks:
|
|
88
|
+
name: Additional Quality Checks
|
|
89
|
+
runs-on: ubuntu-24.04
|
|
90
|
+
timeout-minutes: 5
|
|
91
|
+
|
|
92
|
+
steps:
|
|
93
|
+
- name: Checkout code
|
|
94
|
+
uses: actions/checkout@v5
|
|
95
|
+
|
|
96
|
+
- name: Set up Ruby
|
|
97
|
+
uses: ruby/setup-ruby@v1
|
|
98
|
+
with:
|
|
99
|
+
ruby-version: 3.4
|
|
100
|
+
bundler-cache: true
|
|
101
|
+
|
|
102
|
+
- name: Configure Bundler for secure gem installation
|
|
103
|
+
run: |
|
|
104
|
+
bundle config set --local path 'vendor/bundle'
|
|
105
|
+
bundle config set --local deployment 'false'
|
|
106
|
+
|
|
107
|
+
- name: Install dependencies
|
|
108
|
+
run: bundle install --jobs 4 --retry 3
|
|
109
|
+
|
|
110
|
+
- name: Check for TODO/FIXME comments
|
|
111
|
+
run: |
|
|
112
|
+
echo "=== Scanning for TODO/FIXME comments ==="
|
|
113
|
+
echo "This helps track technical debt and action items."
|
|
114
|
+
echo ""
|
|
115
|
+
|
|
116
|
+
# Find TODO/FIXME comments (excluding vendor and tmp directories)
|
|
117
|
+
find . -name "*.rb" -not -path "./vendor/*" -not -path "./tmp/*" | \
|
|
118
|
+
xargs grep -Hn -i -E "(TODO|FIXME|HACK|XXX|NOTE):" 2>/dev/null | \
|
|
119
|
+
head -20 || echo "No TODO/FIXME comments found"
|
|
120
|
+
continue-on-error: true
|
|
121
|
+
|
|
122
|
+
- name: Check Ruby file syntax
|
|
123
|
+
run: |
|
|
124
|
+
echo "=== Checking Ruby syntax ==="
|
|
125
|
+
echo "Validates that all Ruby files have correct syntax."
|
|
126
|
+
echo ""
|
|
127
|
+
|
|
128
|
+
find . -name "*.rb" -not -path "./vendor/*" -not -path "./tmp/*" | \
|
|
129
|
+
while read -r file; do
|
|
130
|
+
if ! ruby -c "$file" > /dev/null 2>&1; then
|
|
131
|
+
echo "Syntax error in: $file"
|
|
132
|
+
ruby -c "$file"
|
|
133
|
+
fi
|
|
134
|
+
done
|
|
135
|
+
continue-on-error: true
|
|
136
|
+
|
|
137
|
+
- name: Check for long lines
|
|
138
|
+
run: |
|
|
139
|
+
echo "=== Checking for long lines (>120 characters) ==="
|
|
140
|
+
echo "Identifies potentially hard-to-read code lines."
|
|
141
|
+
echo ""
|
|
142
|
+
|
|
143
|
+
find . -name "*.rb" -not -path "./vendor/*" -not -path "./tmp/*" | \
|
|
144
|
+
xargs grep -Hn "^.\{121,\}$" | \
|
|
145
|
+
head -10 || echo "No overly long lines found"
|
|
146
|
+
continue-on-error: true
|
data/.gitignore
CHANGED
data/.pre-commit-config.yaml
CHANGED
|
@@ -96,12 +96,12 @@ repos:
|
|
|
96
96
|
|
|
97
97
|
# Commit message issue tracking integration
|
|
98
98
|
- repo: https://github.com/avilaton/add-msg-issue-prefix-hook
|
|
99
|
-
rev: v0.0.
|
|
99
|
+
rev: v0.0.13
|
|
100
100
|
hooks:
|
|
101
101
|
- id: add-msg-issue-prefix
|
|
102
102
|
stages: [prepare-commit-msg]
|
|
103
103
|
description: Automatically prefix commits with issue numbers
|
|
104
104
|
args:
|
|
105
105
|
- "--default="
|
|
106
|
-
-
|
|
106
|
+
- "--pattern=(i18n(?=/)|([a-zA-Z0-9]{0,10}-?[0-9]{1,5}))"
|
|
107
107
|
- "--template=[#{}]"
|
data/.reek.yml
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# .reek.yml
|
|
2
|
+
#
|
|
3
|
+
# Reek configuration for Otto
|
|
4
|
+
#
|
|
5
|
+
# Basic commands:
|
|
6
|
+
# bundle exec reek # Analyze all Ruby files
|
|
7
|
+
# bundle exec reek lib/ # Analyze specific directory
|
|
8
|
+
# bundle exec reek lib/otto.rb # Analyze specific file
|
|
9
|
+
# bundle exec reek --help # Show all options
|
|
10
|
+
# bundle exec reek --docs # Open documentation
|
|
11
|
+
#
|
|
12
|
+
# Advanced usage:
|
|
13
|
+
# bundle exec reek --format=html > report.html # Generate HTML report
|
|
14
|
+
# bundle exec reek --format=json # JSON output for CI
|
|
15
|
+
# bundle exec reek --config .reek.yml # Use specific config
|
|
16
|
+
# bundle exec reek --show-docs IrresponsibleModule # Explain specific smell
|
|
17
|
+
# bundle exec reek --failure-exit-code 1 # Exit with error on smells (for CI)
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
detectors:
|
|
21
|
+
# Disable some detectors for initial adoption
|
|
22
|
+
# You can gradually enable these as you clean up the codebase
|
|
23
|
+
|
|
24
|
+
# Class/Module Structure
|
|
25
|
+
IrresponsibleModule:
|
|
26
|
+
enabled: false # Modules without documentation - start with this disabled
|
|
27
|
+
|
|
28
|
+
# Method Complexity
|
|
29
|
+
TooManyStatements:
|
|
30
|
+
enabled: true
|
|
31
|
+
max_statements: 15 # Default is 5, relaxed for initial adoption
|
|
32
|
+
|
|
33
|
+
TooManyMethods:
|
|
34
|
+
enabled: true
|
|
35
|
+
max_methods: 25 # Default is 15, relaxed for ORMs which often have many methods
|
|
36
|
+
|
|
37
|
+
LongParameterList:
|
|
38
|
+
enabled: true
|
|
39
|
+
max_params: 4 # Default is 3, slightly relaxed
|
|
40
|
+
|
|
41
|
+
# Data Classes and Feature Envy
|
|
42
|
+
DataClump:
|
|
43
|
+
enabled: true
|
|
44
|
+
|
|
45
|
+
FeatureEnvy:
|
|
46
|
+
enabled: true
|
|
47
|
+
|
|
48
|
+
# Control Structure
|
|
49
|
+
NestedIterators:
|
|
50
|
+
enabled: true
|
|
51
|
+
max_allowed_nesting: 2 # Default is 1, relaxed for data processing
|
|
52
|
+
|
|
53
|
+
# Variable and Constant Usage
|
|
54
|
+
UnusedParameters:
|
|
55
|
+
enabled: true
|
|
56
|
+
|
|
57
|
+
InstanceVariableAssumption:
|
|
58
|
+
enabled: true
|
|
59
|
+
|
|
60
|
+
# Naming
|
|
61
|
+
UncommunicativeParameterName:
|
|
62
|
+
enabled: true
|
|
63
|
+
reject:
|
|
64
|
+
- "/^.$/" # Single letter names
|
|
65
|
+
- "/[0-9]$/" # Names ending in numbers
|
|
66
|
+
- "/^_/" # Names starting with underscore (common Ruby pattern)
|
|
67
|
+
accept: []
|
|
68
|
+
|
|
69
|
+
UncommunicativeVariableName:
|
|
70
|
+
enabled: true
|
|
71
|
+
reject:
|
|
72
|
+
- "/^.$/" # Single letter names
|
|
73
|
+
- "/[0-9]$/" # Names ending in numbers
|
|
74
|
+
accept:
|
|
75
|
+
- e # Exception variable
|
|
76
|
+
- id # Common identifier
|
|
77
|
+
- db # Database connection
|
|
78
|
+
- op # Operation
|
|
79
|
+
- io # Input/output
|
|
80
|
+
|
|
81
|
+
UncommunicativeMethodName:
|
|
82
|
+
enabled: true
|
|
83
|
+
reject:
|
|
84
|
+
- "/^.$/" # Single letter method names
|
|
85
|
+
- "/[0-9]$/" # Methods ending in numbers
|
|
86
|
+
accept:
|
|
87
|
+
- "<<" # Common Ruby operator overload
|
|
88
|
+
|
|
89
|
+
# Directory and file exclusions
|
|
90
|
+
exclude_paths:
|
|
91
|
+
- "vendor/**/*.rb"
|
|
92
|
+
- "tmp/**/*.rb"
|
|
93
|
+
- "try/**/*.rb" # Test files using tryouts framework
|
|
94
|
+
- "examples/**/*.rb" # Example code files
|
|
95
|
+
- "bin/*" # Executable scripts
|
|
96
|
+
- "*.gemspec" # Gem specification files
|
|
97
|
+
|
|
98
|
+
# Note: For limiting warnings output, use CLI: bundle exec reek | head -50
|
|
99
|
+
# Note: For failure exit codes, use CLI: bundle exec reek --failure-exit-code 1
|
data/CHANGELOG.rst
CHANGED
|
@@ -7,6 +7,95 @@ The format is based on `Keep a Changelog <https://keepachangelog.com/en/1.1.0/>`
|
|
|
7
7
|
|
|
8
8
|
<!--scriv-insert-here-->
|
|
9
9
|
|
|
10
|
+
.. _changelog-2.0.0.pre6:
|
|
11
|
+
|
|
12
|
+
2.0.0.pre6 — TBD
|
|
13
|
+
================
|
|
14
|
+
|
|
15
|
+
Changed
|
|
16
|
+
-------
|
|
17
|
+
|
|
18
|
+
- **BREAKING**: ``Otto.on_request_complete`` is now an instance method instead of a class method. This fixes duplicate callback invocations in multi-app architectures (e.g., Rack::URLMap with multiple Otto instances). Each Otto instance now maintains its own isolated set of callbacks that only fire for requests processed by that specific instance.
|
|
19
|
+
|
|
20
|
+
**Migration**: Change ``Otto.on_request_complete { |req, res, dur| ... }`` to ``otto.on_request_complete { |req, res, dur| ... }``
|
|
21
|
+
|
|
22
|
+
- **Logging**: Eliminated duplicate error logging in route handlers. Previously, errors produced two log lines ("Handler execution failed" + "Unhandled error in request"). Now produces a single comprehensive error log with all context (handler, duration, error_id). Lambda handlers now use centralized error handling for consistency. #86
|
|
23
|
+
|
|
24
|
+
Fixed
|
|
25
|
+
-----
|
|
26
|
+
|
|
27
|
+
- Fixed issue #84 where ``on_request_complete`` callbacks would fire N times per request in multi-app architectures, causing duplicate logging and metrics
|
|
28
|
+
- Fixed ``Otto.structured_log`` to respect ``Otto.debug`` flag - debug logs are now properly skipped when ``Otto.debug = false``
|
|
29
|
+
|
|
30
|
+
AI Assistance
|
|
31
|
+
-------------
|
|
32
|
+
|
|
33
|
+
- This enhancement was developed with assistance from Claude Code (Opus 4.1)
|
|
34
|
+
|
|
35
|
+
.. _changelog-2.0.0.pre5:
|
|
36
|
+
|
|
37
|
+
2.0.0.pre5 — 2025-10-21
|
|
38
|
+
=======================
|
|
39
|
+
|
|
40
|
+
Added
|
|
41
|
+
-----
|
|
42
|
+
|
|
43
|
+
- Added ``Otto::LoggingHelpers.log_timed_operation`` for automatic timing and error handling of operations
|
|
44
|
+
- Added ``Otto::LoggingHelpers.log_backtrace`` for consistent backtrace logging with correlation fields
|
|
45
|
+
- Added microsecond-precision timing to configuration freeze process
|
|
46
|
+
- Added unique error ID generation for nested error handler failures (links via ``original_error_id``)
|
|
47
|
+
|
|
48
|
+
Changed
|
|
49
|
+
-------
|
|
50
|
+
|
|
51
|
+
- Timing precision standardization: All timing calculations now use microsecond precision instead of milliseconds. This affects authentication duration tracking and request lifecycle timing. Duration values are now reported in microseconds as integers (e.g., ``15200`` instead of ``15.2``).
|
|
52
|
+
- Request completion hooks API improvement: ``Otto.on_request_complete`` callbacks now receive a ``Rack::Response`` object instead of the raw ``[status, headers, body]`` tuple. This provides a more developer-friendly API consistent with ``Rack::Request``, allowing clean access via ``res.status``, ``res.headers``, and ``res.body`` instead of array indexing.
|
|
53
|
+
- All timing now uses microseconds (``Otto::Utils.now_in_μs``) for consistency
|
|
54
|
+
- Configuration freeze process now logs detailed timing metrics
|
|
55
|
+
|
|
56
|
+
Documentation
|
|
57
|
+
-------------
|
|
58
|
+
|
|
59
|
+
- Added example application demonstrating three new logging patterns (``examples/logging_improvements.rb``)
|
|
60
|
+
- Documented base context pattern for downstream projects to inject custom correlation fields
|
|
61
|
+
- Added output examples for both structured and standard loggers
|
|
62
|
+
|
|
63
|
+
AI Assistance
|
|
64
|
+
-------------
|
|
65
|
+
|
|
66
|
+
- This enhancement was developed with assistance from Claude Code (Opus 4.1)
|
|
67
|
+
|
|
68
|
+
.. _changelog-2.0.0.pre4:
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
2.0.0.pre4 — 2025-10-20
|
|
72
|
+
=======================
|
|
73
|
+
Changed
|
|
74
|
+
-------
|
|
75
|
+
- Authentication moved from middleware to RouteAuthWrapper at handler level (executes after routing)
|
|
76
|
+
- RouteAuthWrapper now wraps all routes and provides session persistence, security headers, strategy caching, and pattern matching (exact, prefix, fallback)
|
|
77
|
+
- env['otto.strategy_result'] now guaranteed present on all routes (authenticated or anonymous)
|
|
78
|
+
- Renamed MiddlewareStack#build_app to #wrap (reflects per-request wrapping vs one-time initialization)
|
|
79
|
+
|
|
80
|
+
Removed
|
|
81
|
+
-------
|
|
82
|
+
- AuthenticationMiddleware (executed before routing)
|
|
83
|
+
- enable_authentication! (RouteAuthWrapper handles auth automatically)
|
|
84
|
+
- Defensive nil fallback from LogicClassHandler (no longer needed)
|
|
85
|
+
|
|
86
|
+
Fixed
|
|
87
|
+
-----
|
|
88
|
+
- Session persistence: env['rack.session'] now references same object as strategy_result.session
|
|
89
|
+
- Security headers included on all auth failure responses (401/302)
|
|
90
|
+
- Anonymous routes now receive StrategyResult with IP metadata
|
|
91
|
+
|
|
92
|
+
Documentation
|
|
93
|
+
-------------
|
|
94
|
+
- Updated CLAUDE.md with RouteAuthWrapper architecture
|
|
95
|
+
- Updated env_keys.rb to document strategy_result guarantee
|
|
96
|
+
- Added tests for anonymous route handling
|
|
97
|
+
|
|
98
|
+
|
|
10
99
|
.. _changelog-2.0.0.pre2:
|
|
11
100
|
|
|
12
101
|
2.0.0.pre2 — 2025-10-11
|
|
@@ -60,6 +149,7 @@ AI Assistance
|
|
|
60
149
|
- Comprehensive migration of Logic classes and documentation with AI guidance for consistency
|
|
61
150
|
- Automated test validation and intelligent file organization following Ruby conventions
|
|
62
151
|
|
|
152
|
+
|
|
63
153
|
.. _changelog-2.0.0-pre1:
|
|
64
154
|
|
|
65
155
|
2.0.0-pre1 — 2025-09-10
|