schema_reaper 1.0.16 → 2.0.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: df6a3127bc5e379e183a6f525870c5726bbf016223b6c8531b1be8cb97da8ca5
4
- data.tar.gz: 2810a69e8b382c10ecf52bc35717efd53fc9b826b8aae580b15773f4ffb8e246
3
+ metadata.gz: 89431a69d7cd997b743e0a7996ce1bae64244946dbea4d0683f8beb477ad1498
4
+ data.tar.gz: d43309fe35f2f6b4c669e21413c300997fdabf03f3d77f3295a6742de5f3cea2
5
5
  SHA512:
6
- metadata.gz: f4dc2789fcdd897e213a4b050ef98a05d94f6c213e145bdc6ac6e8a5168d355b7fc86a2b18aa0799b76ff1183255e64b5d6bbc2789c9d5a063dac91c9fcabdf9
7
- data.tar.gz: f8026dcfb27f4a9a828f519bef9a78f8e626522f8cadb5082ee39b393652d5ff0224a669fc8a4b7d109f20f5b6bc910bcea336971de0603a85af4d1c4ad2280a
6
+ metadata.gz: 6d2c527fc15a64ce62680a96a989c1ba0fbda445fd216afe590dd95e3344b1a8c2ef271a102eed01626b1cac1b0e9400874c8cc177f71d1d27efa32fda79e6fb
7
+ data.tar.gz: 777a1561b89af7d5795a326d9c30d6764190b14f6a3dbb1af5f22d2fb525f3959d73e2f3beaa25262a9508f94958a1c1cad42d908f879855f1643f0206bc1208
data/CHANGELOG.md CHANGED
@@ -1,5 +1,103 @@
1
1
  # Changelog
2
2
 
3
+ ## [2.0.1] - 2026-09-23
4
+
5
+ ### Fixed
6
+ - **Report emails now use the app's `ApplicationMailer`.** `SchemaReaper::Mailer`
7
+ was defined while the gem loaded (`Bundler.require`), before the app's
8
+ autoloader could see `app/mailers/application_mailer.rb`, so it always
9
+ inherited `ActionMailer::Base` and sent from the `schema_reaper@localhost`
10
+ placeholder -- which most SMTP relays reject. It is now autoloaded on first
11
+ use, after boot. The install generator's `from:` check now also accepts
12
+ `config.action_mailer.default_options` for apps without an
13
+ `ApplicationMailer`. 2.0.0 workaround: add
14
+ `SchemaReaper::Mailer.default from: "..."` to the initializer.
15
+ - **`rake schema_reaper:alert` no longer silently drops the scan on the
16
+ `:async` ActiveJob adapter** (the default before Rails 8). The job ran on a
17
+ thread inside the rake process, which exited first -- so the whenever and
18
+ plain-cron schedules never scanned. The task now runs the scan inline (with
19
+ email delivered immediately) when the adapter is `:async`, and enqueues as
20
+ before otherwise.
21
+ - **A missing `pg` gem now gives a clear error.** `pg` is deliberately not a
22
+ runtime dependency (the gem uses the host app's own), but without it the
23
+ scan failed with `NameError: uninitialized constant ...::PG` from the
24
+ connection rescue. It now says to add `gem "pg"`.
25
+ - **`min_age_days` in `.schema_reaper.yml` now takes effect.** It was defined
26
+ and documented since 1.0.0 but never read -- `dead_column` used its own
27
+ hardcoded 14-day threshold for trusting runtime data. The analyzer now reads
28
+ the config key (default still 14, so nothing changes unless you set it).
29
+
30
+ ### Changed
31
+ - README rewritten around a quickstart, with animated SVG illustrations
32
+ (`docs/assets/`, excluded from the packaged gem) and corrected details on
33
+ scheduling, the manual trigger's cooldown, CI and gem awareness. Diagrams
34
+ for each major section; animations loop with a long hold on the finished
35
+ frame, since GitHub can't start a README image's animation on scroll.
36
+ Documents the `pg` requirement, that only the `public` schema is scanned, and
37
+ that lists in `.schema_reaper.yml` replace their defaults, and what
38
+ `min_age_days` controls.
39
+ - The `automation`, `safety` and `ci` section diagrams carry label text meant
40
+ to be read, so they no longer loop a fade in/out -- the reveal plays once
41
+ and holds the finished frame, instead of pulling attention away from the
42
+ text every 12s. The safety timeline's progress line keeps a continuous
43
+ moving-dash accent once grown in, since that's motion, not text.
44
+
45
+ ## [2.0.0] - 2026-09-23
46
+
47
+ ### Added
48
+ - **`rails generate schema_reaper:install`** — one-time setup for running
49
+ `schema_reaper` unattended in production, with zero ongoing DevOps
50
+ dependency: a scheduled scan, results delivered automatically, and an
51
+ on-demand manual trigger, none of it gated behind infrastructure a given
52
+ project may not have (Slack, a CI pipeline with prod network access,
53
+ etc.).
54
+ - `SchemaReaper::AlertConfig` / `config/initializers/schema_reaper.rb` —
55
+ where reports go (`emails`, `webhook_url`). Plain committed config, not
56
+ secrets; commented out by default so an unfilled-in initializer is a
57
+ safe no-op.
58
+ - `SchemaReaper::Notifier` — delivers a scan's findings through whichever
59
+ channels are configured. Both fire when both are set (two audiences —
60
+ a dev-facing chat channel and a formal inbox record — not a fallback
61
+ chain). Webhook: a Slack-compatible `{"text": ...}` POST, with a 10s
62
+ timeout so a dead host can't hang a queue worker indefinitely. Email:
63
+ reuses the host app's own ActionMailer setup via `SchemaReaper::Mailer`
64
+ (inherits `ApplicationMailer` when the host app defines one, falls back
65
+ to a placeholder `default from:` otherwise so delivery degrades to a
66
+ normal SMTP rejection instead of a hard crash). Delivery failures are
67
+ logged, never raised, so a flaky endpoint can't fail the scan job.
68
+ - `SchemaReaper::ScanJob` / `rake schema_reaper:alert` — the one job both
69
+ the schedule and the manual trigger enqueue.
70
+ - Generated `app/controllers/schema_reaper_controller.rb` + a route for
71
+ the manual trigger — bearer-token protected via
72
+ `Rails.application.credentials` (decrypted with the `RAILS_MASTER_KEY`
73
+ every Rails app already has, so this introduces zero new production
74
+ configuration), checked with `ActiveSupport::SecurityUtils
75
+ .secure_compare`, and a shared 5-minute cooldown via `Rails.cache` so a
76
+ valid or leaked token can't be POSTed repeatedly to stack up scans
77
+ against production.
78
+ - A schedule entry in whichever of `config/schedule.rb` (`whenever`) or
79
+ `config/schedule.yml` (`sidekiq-cron`) the app's `Gemfile.lock` says it
80
+ has; prints manual instructions instead of guessing when neither gem is
81
+ present. Warns at install time if the Gemfile scopes `schema_reaper` to
82
+ `group: :development` (most production deploy pipelines strip dev/test
83
+ groups) or if no `ApplicationMailer` `default from:` is detected (email
84
+ reports would otherwise silently never arrive).
85
+ - Re-running the generator is safe — every step checks for its own
86
+ marker before writing, so nothing gets duplicated.
87
+
88
+ CI/SARIF stays a separate, already-documented path for PR/staging checks
89
+ — this is for production, where GitHub-hosted runners don't have prod
90
+ network access by default.
91
+
92
+ Verified against a real booted `Rails::Application` (not just specs):
93
+ the manual-trigger endpoint correctly rejects requests without hitting
94
+ Rails' CSRF protection, a valid token enqueues and a second one within
95
+ the cooldown 429s without enqueuing twice, and wrong-token requests
96
+ during the cooldown still 401 rather than being masked by the lock.
97
+ Reviewed by @aksshatt; three follow-up findings (a stale doc comment, the
98
+ mailer `from:` gap, and the missing rate limit) addressed and verified
99
+ the same way. (#20, mitkush)
100
+
3
101
  ## [1.0.16] - 2026-09-22
4
102
 
5
103
  ### Fixed
data/PRO.md CHANGED
@@ -24,7 +24,7 @@ work that only pays off at scale and that individuals rarely need.
24
24
  | History / trend | local JSONL + `trend` | hosted timeline, burndown charts, per-team dashboards |
25
25
  | Baseline gate | one file | per-branch baselines, ownership routing (CODEOWNERS) |
26
26
  | Multi-database / shards | one DB per run | fan-out across N databases, divergence report |
27
- | Scheduled scans + alerts | — | ✅ (cron runner, "queue breached", "new dead column in `billing`") |
27
+ | Scheduled scans + alerts | ✅ self-hosted (`rails g schema_reaper:install`: whenever/sidekiq-cron + webhook/email) | ✅ hosted, zero-install + native Slack/Jira routing + per-team alert rules |
28
28
  | Mountable dashboard engine | — | ✅ `mount SchemaReaper::Pro::Engine` |
29
29
  | SSO, audit log, RBAC | — | ✅ (Enterprise) |
30
30
  | Support | GitHub issues, best effort | private issues, SLA |
@@ -59,7 +59,7 @@ team-scale.
59
59
  | Tier | Who | Price | Limits |
60
60
  |---|---|---|---|
61
61
  | **Solo Pro** | 1 dev, unlimited personal/side projects | $9 / mo ($90 / yr) | 3 databases |
62
- | **Team** | up to 10 devs | $49 / mo ($490 / yr) | 15 databases, Slack/Jira, scheduled scans |
62
+ | **Team** | up to 10 devs | $49 / mo ($490 / yr) | 15 databases, Slack/Jira, hosted scheduled scans |
63
63
  | **Business** | up to 50 devs | $199 / mo | unlimited databases, dashboard engine, priority support |
64
64
  | **Enterprise** | 50+ / regulated | custom (from ~$12k / yr) | SSO, audit log, RBAC, on-prem license server, SLA |
65
65
 
@@ -82,10 +82,15 @@ scheduler + a web app.
82
82
  1. **Now**: Sponsor button, `PRO.md`, "Pro" section in README (waitlist link).
83
83
  2. **v1.1 (OSS)**: MySQL adapter groundwork, real size math — proves demand,
84
84
  some lands free.
85
- 3. **Pro 0.1**: private gem = MySQL + Slack reporter + scheduled scans + license
86
- key. Sell to the first 10 teams at half price for feedback.
87
- 4. **Pro 0.2**: dashboard engine, multi-DB fan-out, per-branch baselines.
88
- 5. **SaaS beta**: once ~25 paying teams self-host.
85
+ 3. **v2.0 (OSS, shipped)**: self-hosted scheduled scans + webhook/email alerts
86
+ (`rails g schema_reaper:install`) — this landed free rather than Pro; it's
87
+ the kind of single-app automation the "anything a single app genuinely
88
+ needs stays free" principle below is about.
89
+ 4. **Pro 0.1**: private gem = MySQL + Slack/Jira reporters + hosted scan
90
+ runner + license key. Sell to the first 10 teams at half price for
91
+ feedback.
92
+ 5. **Pro 0.2**: dashboard engine, multi-DB fan-out, per-branch baselines.
93
+ 6. **SaaS beta**: once ~25 paying teams self-host.
89
94
 
90
95
  ---
91
96