and_one 0.1.0 → 0.3.0

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.
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: and_one
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Keith Thompson
@@ -10,7 +10,7 @@ cert_chain: []
10
10
  date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
- name: railties
13
+ name: activerecord
14
14
  requirement: !ruby/object:Gem::Requirement
15
15
  requirements:
16
16
  - - ">="
@@ -24,7 +24,7 @@ dependencies:
24
24
  - !ruby/object:Gem::Version
25
25
  version: '7.0'
26
26
  - !ruby/object:Gem::Dependency
27
- name: activerecord
27
+ name: activesupport
28
28
  requirement: !ruby/object:Gem::Requirement
29
29
  requirements:
30
30
  - - ">="
@@ -38,7 +38,7 @@ dependencies:
38
38
  - !ruby/object:Gem::Version
39
39
  version: '7.0'
40
40
  - !ruby/object:Gem::Dependency
41
- name: activesupport
41
+ name: railties
42
42
  requirement: !ruby/object:Gem::Requirement
43
43
  requirements:
44
44
  - - ">="
@@ -60,12 +60,12 @@ executables: []
60
60
  extensions: []
61
61
  extra_rdoc_files: []
62
62
  files:
63
+ - ".githooks/pre-commit"
63
64
  - CHANGELOG.md
64
65
  - CODE_OF_CONDUCT.md
65
66
  - LICENSE.txt
66
67
  - README.md
67
68
  - Rakefile
68
- - TODO.md
69
69
  - lib/and_one.rb
70
70
  - lib/and_one/active_job_hook.rb
71
71
  - lib/and_one/aggregate.rb
@@ -73,6 +73,7 @@ files:
73
73
  - lib/and_one/console.rb
74
74
  - lib/and_one/detection.rb
75
75
  - lib/and_one/detector.rb
76
+ - lib/and_one/dev_toast.rb
76
77
  - lib/and_one/dev_ui.rb
77
78
  - lib/and_one/fingerprint.rb
78
79
  - lib/and_one/formatter.rb
@@ -93,6 +94,7 @@ metadata:
93
94
  homepage_uri: https://github.com/keiththomps/and_one
94
95
  source_code_uri: https://github.com/keiththomps/and_one
95
96
  changelog_uri: https://github.com/keiththomps/and_one/blob/main/CHANGELOG.md
97
+ rubygems_mfa_required: 'true'
96
98
  rdoc_options: []
97
99
  require_paths:
98
100
  - lib
data/TODO.md DELETED
@@ -1,52 +0,0 @@
1
- # AndOne — Feature Roadmap
2
-
3
- ## ✅ Completed
4
-
5
- - [x] Core detection engine using `sql.active_record` notifications
6
- - [x] SQL fingerprinting without external dependencies
7
- - [x] Association resolver that suggests exact `.includes()` fixes
8
- - [x] Rich formatted output with query, call stack, and fix suggestions
9
- - [x] Rack middleware that never corrupts error backtraces
10
- - [x] Railtie for zero-config auto-setup in dev/test
11
- - [x] Raises in test env, warns in dev, disabled in production
12
- - [x] Pause/resume support for known N+1s
13
- - [x] ActiveJob `around_perform` hook (works with any backend)
14
- - [x] Sidekiq server middleware (for jobs bypassing ActiveJob)
15
- - [x] `ScanHelper` shared module to DRY up scan lifecycle across entry points
16
- - [x] Double-scan protection (ActiveJob + Sidekiq don't conflict)
17
-
18
- ## 🎯 High Value — Completed
19
-
20
- - [x] **Auto-detect the "fix location"** — Walks the backtrace to identify two key frames: the "origin" (where the N+1 is triggered inside a loop) and the "fix location" (the outer frame where `.includes()` should be added). Both are highlighted in the output.
21
-
22
- - [x] **Ignore file (`.and_one_ignore`)** — Supports four rule types: `gem:` (for N+1s from gems like devise/administrate you can't fix), `path:` (glob patterns for app areas), `query:` (SQL patterns), and `fingerprint:` (specific detections). Checked into source control.
23
-
24
- - [x] **Aggregate mode for development** — `AndOne.aggregate_mode = true` reports each unique N+1 only once per server session. Tracks occurrence counts. `AndOne.aggregate.summary` shows a session overview. Thread-safe.
25
-
26
- - [x] **RSpec / Minitest matchers** — `assert_no_n_plus_one { ... }` / `assert_n_plus_one { ... }` for Minitest. `expect { ... }.not_to cause_n_plus_one` for RSpec. Matchers temporarily disable `raise_on_detect` internally so they work regardless of config.
27
-
28
- ## ✅ Medium Value — Polish & Power User Features (Completed)
29
-
30
- - [x] **`strict_loading` suggestion** — When an N+1 is detected, also suggest the `strict_loading` approach as an alternative: "You could also add `has_many :comments, strict_loading: true` to prevent this at the model level."
31
-
32
- - [x] **Query count in test failure messages** — "N+1 detected: 47 queries to `comments` (expected 1). Add `.includes(:comments)` to reduce to 1 query." Makes severity immediately obvious.
33
-
34
- - [x] **Dev UI endpoint** — A tiny Rack endpoint (e.g., `/__and_one`) in development that shows all N+1s detected in the current server session with fix suggestions. Like a mini BetterErrors for N+1s.
35
-
36
- - [x] **GitHub Actions / CI annotations** — When `GITHUB_ACTIONS` env var is set, output detections in `::warning file=...` format so they appear as annotations on the PR diff.
37
-
38
- - [x] **Ignore by caller pattern** — In addition to `ignore_queries` (SQL patterns), support `ignore_callers` to suppress detections originating from specific paths: "ignore any N+1 from `app/views/admin/*`".
39
-
40
- - [x] **`has_many :through` and polymorphic support** — Extend the association resolver to handle `has_many :through` join chains and polymorphic associations, which are common sources of confusing N+1s.
41
-
42
- - [x] **`preload` vs `includes` vs `eager_load` recommendation** — Suggest the optimal loading strategy based on the query pattern (e.g., `eager_load` when there's a WHERE on the association).
43
-
44
- ## ✅ Lower Priority — Nice to Have (Completed)
45
-
46
- - [x] **Structured JSON logging** — A JSON output mode for log aggregation services (Datadog, Splunk, etc.). Set `AndOne.json_logging = true`. Uses `JsonFormatter` which outputs structured JSON with event, table, fingerprint, query count, suggestion, and backtrace. Also provides `format_hashes` for integrations that accept Ruby hashes directly.
47
-
48
- - [x] **Thread-safety audit for Puma** — Formal audit and stress test suite complete. Found and fixed a **critical cross-thread contamination bug** in `Detector#subscribe`: the `ActiveSupport::Notifications` callback closure captured `self`, causing SQL from one thread to be recorded in another thread's Detector. Fixed by checking `Thread.current[:and_one_detector].object_id` in the callback. Also added Mutex protection for lazy singletons (`aggregate`, `ignore_list`), `AssociationResolver.@table_model_cache`, and report output serialization. 14 concurrent stress tests verify isolation, atomicity, and correctness under Puma-like load.
49
-
50
- - [x] **Rails console integration** — Auto-scan in `rails console` sessions and print warnings inline. Activated automatically by the Railtie in development, or manually via `AndOne::Console.activate!`. Hooks into IRB (via `Context#evaluate` prepend) and Pry (via `:after_eval` hook) to cycle scans between commands.
51
-
52
- - [x] **Configurable per-environment thresholds** — Different `min_n_queries` for dev vs test. Configure via `AndOne.env_thresholds = { "development" => 3, "test" => 2 }`. Falls back to global `min_n_queries` when no env-specific threshold is set. Supports both string and symbol keys.