Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added

- Public API stability policy — `README.md#versioning` documents what is and is not covered by semver guarantees from v1.0.0; `UPGRADING.md` cross-references the policy
- README: Security section covering authentication requirements, `allow_value_preview` caution, CSRF handling, and rate-limiting guidance
- README: Screenshots section with a single `docs/screenshots/demo.gif` slot (animated GIF showing a dashboard tour)
- README: `connects_to` added to the General configuration reference
- Deprecation warning infrastructure — `SolidStackWeb.deprecator` exposes a gem-scoped `ActiveSupport::Deprecation` instance registered with `app.deprecators`; a private `deprecated_config` helper generates forwarding writers with warnings for any config keys renamed before 1.0

### Changed
Expand Down
50 changes: 49 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
[![Ruby](https://img.shields.io/badge/ruby-%3E%3D%203.3-ruby)](https://www.ruby-lang.org)
[![codecov](https://codecov.io/gh/eclectic-coding/solid_stack_web/branch/main/graph/badge.svg)](https://codecov.io/gh/eclectic-coding/solid_stack_web)

A mountable Rails engine that provides a unified web dashboard for the full [Solid Stack](https://github.com/rails/solid_queue) — **Solid Queue**, **Solid Cache**, and **Solid Cable** — in a single interface with no asset pipeline dependency and no JavaScript runtime requirement.
A production-ready operations dashboard for the full Rails Solid Stack. Mount one engine to get deep visibility into **Solid Queue** (job browser, failed job retry, queue controls, recurring tasks, performance stats), **Solid Cache** (entry browser, size distribution, write timeline), and **Solid Cable** (channel browser, message list, purge controls) — with dark mode, CSV export, alert webhooks, and a JSON metrics endpoint, all with no asset pipeline dependency.

## Installation

Expand Down Expand Up @@ -41,6 +41,12 @@ This creates `config/initializers/solid_stack_web.rb` with every configuration o

---

## Screenshots

![SolidStackWeb dashboard](docs/screenshots/demo.gif)

---

## Metrics endpoint

`GET /metrics` (relative to your mount path) returns a JSON payload suitable for external monitoring tools, uptime checkers, or custom alerting:
Expand Down Expand Up @@ -83,6 +89,10 @@ SolidStackWeb.configure do |config|
config.authenticate do
current_user&.admin?
end

# Multi-database — pass a connects_to hash when Solid Queue / Cache / Cable
# live on a separate database from your primary (default: nil, uses primary).
config.connects_to = { database: { writing: :queue, reading: :queue } }
end
```

Expand All @@ -100,6 +110,44 @@ link_to "Queue Dashboard", SolidStackWeb.mount_path

---

## Security

### Authentication

**The dashboard is open to all visitors by default.** Any production deployment must configure an `authenticate` block or the dashboard will be publicly accessible.

```ruby
SolidStackWeb.configure do |config|
# Devise
config.authenticate { current_user&.admin? }

# HTTP Basic fallback (used when no authenticate block is set, or when
# the block returns false/nil and you want a browser credential prompt)
# Configure via HTTP_BASIC_AUTH_NAME / HTTP_BASIC_AUTH_PASSWORD env vars
# in your host app, or use a reverse proxy.
end
```

If the `authenticate` block returns `false` or `nil`, the engine falls back to HTTP Basic authentication. If no block is configured at all, the dashboard is open.

### Sensitive cache values

`allow_value_preview` is `false` by default. Enabling it renders the raw serialised cache value on the entry detail page. Do not enable this if your cache stores session tokens, PII, or other sensitive data.

### CSRF protection

All state-mutating actions (job discard, retry, queue pause/resume, cache flush) use form POST requests. Turbo handles CSRF tokens automatically for any standard Rails app with `protect_from_forgery`.

### Rate limiting and network exposure

The dashboard is designed to be mounted behind your application's existing authentication. For additional hardening, consider:

- Mounting at a non-guessable path (e.g. `at: "/ops/#{Rails.application.credentials.dashboard_token}"`)
- Restricting access by IP at the reverse-proxy level
- Applying [Rack::Attack](https://github.com/rack/rack-attack) rules to the mount path

---

## Solid Queue

### Features
Expand Down
5 changes: 3 additions & 2 deletions ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ The path to v1.0.0 is staged: first achieve feature parity with `solid_queue_das

> _Declare a stable public API and commit to semantic versioning guarantees._

### Added
- Complete README with configuration reference, screenshot gallery, and security guidance
### Remaining

_All items complete._

---

Expand Down
Empty file added docs/screenshots/.gitkeep
Empty file.
Binary file added docs/screenshots/demo.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 9 additions & 4 deletions solid_stack_web.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,22 @@ Gem::Specification.new do |spec|
spec.email = ["eclectic-coding@users.noreply.github.com"]
spec.homepage = "https://github.com/eclectic-coding/solid_stack_web"
spec.summary = "A unified Rails engine dashboard for Solid Queue, Solid Cache, and Solid Cable."
spec.description = "Mount SolidStackWeb in any Rails app using the Solid Stack to get a single " \
"dashboard covering Solid Queue job monitoring, Solid Cache statistics, " \
"and Solid Cable connection observability — all without leaving your app."
spec.description = "SolidStackWeb is a mountable Rails engine that provides a production-ready " \
"operations dashboard for the full Solid Stack. It covers Solid Queue " \
"(job browser, failed job retry with inline argument editing, queue pause/resume, " \
"recurring tasks, performance stats, CSV export, and alert webhooks), " \
"Solid Cache (entry browser, size distribution, 24-hour write timeline, " \
"and optional value preview), and Solid Cable (channel browser, per-channel " \
"message list, and purge controls). Ships with dark mode, Turbo Stream " \
"responses, a JSON metrics endpoint, and no asset pipeline dependency."
spec.license = "MIT"

spec.metadata["homepage_uri"] = spec.homepage
spec.metadata["source_code_uri"] = "https://github.com/eclectic-coding/solid_stack_web"
spec.metadata["changelog_uri"] = "https://github.com/eclectic-coding/solid_stack_web/blob/main/CHANGELOG.md"

spec.files = Dir.chdir(File.expand_path(__dir__)) do
Dir["{app,config,db,lib}/**/*", "MIT-LICENSE", "Rakefile", "README.md"]
Dir["{app,config,db,docs,lib}/**/*", "MIT-LICENSE", "Rakefile", "README.md"]
end

spec.required_ruby_version = ">= 3.3"
Expand Down