RepoPilotOpen in app →

ankane/blazer

Business intelligence made simple

Healthy

Healthy across all four use cases

Use as dependencyHealthy

Permissive license, no critical CVEs, actively maintained — safe to depend on.

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture — runnable as-is.

  • Last commit 3w ago
  • 5 active contributors
  • MIT licensed
Show 3 more →
  • CI configured
  • Tests present
  • Single-maintainer risk — top contributor 96% of recent commits

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Healthy" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Healthy
[![RepoPilot: Healthy](https://repopilot.app/api/badge/ankane/blazer)](https://repopilot.app/r/ankane/blazer)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/ankane/blazer on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: ankane/blazer

Generated by RepoPilot · 2026-05-10 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/ankane/blazer shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

GO — Healthy across all four use cases

  • Last commit 3w ago
  • 5 active contributors
  • MIT licensed
  • CI configured
  • Tests present
  • ⚠ Single-maintainer risk — top contributor 96% of recent commits

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live ankane/blazer repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/ankane/blazer.

What it runs against: a local clone of ankane/blazer — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in ankane/blazer | Confirms the artifact applies here, not a fork | | 2 | License is still MIT | Catches relicense before you depend on it | | 3 | Default branch master exists | Catches branch renames | | 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 5 | Last commit ≤ 49 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>ankane/blazer</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of ankane/blazer. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/ankane/blazer.git
#   cd blazer
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of ankane/blazer and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "ankane/blazer(\\.git)?\\b" \\
  && ok "origin remote is ankane/blazer" \\
  || miss "origin remote is not ankane/blazer (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
  && ok "license is MIT" \\
  || miss "license drift — was MIT at generation time"

# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
  && ok "default branch master exists" \\
  || miss "default branch master no longer exists"

# 4. Critical files exist
test -f "app/controllers/blazer/queries_controller.rb" \\
  && ok "app/controllers/blazer/queries_controller.rb" \\
  || miss "missing critical file: app/controllers/blazer/queries_controller.rb"
test -f "app/models/blazer/query.rb" \\
  && ok "app/models/blazer/query.rb" \\
  || miss "missing critical file: app/models/blazer/query.rb"
test -f "app/models/blazer/connection.rb" \\
  && ok "app/models/blazer/connection.rb" \\
  || miss "missing critical file: app/models/blazer/connection.rb"
test -f "app/controllers/blazer/base_controller.rb" \\
  && ok "app/controllers/blazer/base_controller.rb" \\
  || miss "missing critical file: app/controllers/blazer/base_controller.rb"
test -f "app/models/blazer/dashboard.rb" \\
  && ok "app/models/blazer/dashboard.rb" \\
  || miss "missing critical file: app/models/blazer/dashboard.rb"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 49 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~19d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/ankane/blazer"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

Blazer is a Rails engine that transforms raw SQL queries into an interactive business intelligence platform with built-in charting, dashboards, and alerts. It connects to PostgreSQL, MySQL, Redshift, and other databases to let teams explore data without leaving their Rails app, featuring variable substitution, read-only query execution, audit trails, and scheduled checks that email on anomalies. Rails engine structure: core logic in app/ (controllers, models, views), assets in app/assets/ (JavaScript for Ace SQL editor, Chartkick charting, Selectize dropdowns; stylesheets for Bootstrap-based UI), with generators under lib/generators/ to scaffold migrations and configuration. No monorepo—single unified engine mounted via routes.rb.

👥Who it's for

Data analysts and product managers at Rails-based companies who need to create ad-hoc SQL queries, visualize results as charts/dashboards, and share insights with non-technical stakeholders—without requiring separate BI tool infrastructure like Tableau or Looker.

🌱Maturity & risk

Highly mature and production-ready. Created and battle-tested at Instacart, it has been actively maintained with regular updates (CHANGELOG.md present), GitHub Actions CI/CD configured (.github/workflows/build.yml), and is distributed as a well-documented gem. The codebase is stable with 175KB+ of Ruby code and established patterns.

Low risk overall due to mature codebase and Instacart backing, but single-maintainer model (ankane) and reliance on Rails version compatibility pose moderate risk. The gem's tight Rails coupling means breaking Rails updates require prompt maintenance. No vendored dependencies visible in assets, though it bundles third-party JS libraries (Chart.js, Ace editor) that may have their own CVE histories.

Active areas of work

Repository includes active GitHub workflows (build.yml), ongoing documentation in README and CHANGELOG, and support for modern features like Solid Queue integration for scheduled checks. Recent commits likely address database compatibility, security hardening for query execution (transaction rollback protection), and UI polish.

🚀Get running

Clone the repo, add gem 'blazer' to a Rails Gemfile, run rails generate blazer:install && rails db:migrate, mount it in config/routes.rb with mount Blazer::Engine, at: 'blazer', set ENV['BLAZER_DATABASE_URL'] for production, and visit /blazer.

Daily commands: rails generate blazer:install (generator), rails db:migrate (migrations), then start your Rails dev server (rails s). For checks: rake blazer:run_checks SCHEDULE='5 minutes' or rake blazer:send_failing_checks. Requires a Rails app context.

🗺️Map of the codebase

  • app/controllers/blazer/queries_controller.rb — Entry point for query execution, variable substitution, and result formatting; every contributor must understand the request flow
  • app/models/blazer/query.rb — Core Query model with SQL parsing, validation, and execution logic; foundational to all Blazer functionality
  • app/models/blazer/connection.rb — Abstraction for multi-database connections (PostgreSQL, MySQL, Redshift, etc.); critical for data source routing
  • app/controllers/blazer/base_controller.rb — Base controller handling authentication, authorization, and common request setup for all Blazer controllers
  • app/models/blazer/dashboard.rb — Dashboard aggregation model that composes multiple queries; key to understanding the dashboard feature
  • app/models/blazer/check.rb — Check/alert model with scheduling and state management logic; critical for the alerts feature
  • config/initializers/blazer.rb — Main configuration file where data sources and Blazer settings are defined

🛠️How to make changes

Add a new query data source (database connection)

  1. Register the new connection in Blazer.configure block in config/initializers/blazer.rb with a name and connection string or object (config/initializers/blazer.rb)
  2. If using custom adapter logic, create or extend app/models/blazer/connection.rb to handle dialect-specific SQL or connection details (app/models/blazer/connection.rb)
  3. Test by creating a new Query in the UI and selecting the data source from the dropdown; the connection list is auto-populated from Blazer config (app/controllers/blazer/queries_controller.rb)

Add a new dashboard

  1. Submit the dashboard creation form in app/views/blazer/dashboards/_form.html.erb with name and optional description (app/views/blazer/dashboards/_form.html.erb)
  2. The DashboardsController creates a new Dashboard record in the database via app/models/blazer/dashboard.rb (app/controllers/blazer/dashboards_controller.rb)
  3. Add queries to the dashboard by linking existing Query records through the dashboard_queries association in app/models/blazer/dashboard_query.rb (app/models/blazer/dashboard_query.rb)
  4. View the dashboard at /blazer/dashboards/:id; the show template renders query results in a grid (app/views/blazer/dashboards/show.html.erb)

Add a check (alert) on a query result

  1. Navigate to a saved Query and create a new Check via app/views/blazer/checks/_form.html.erb with a threshold condition (app/views/blazer/checks/_form.html.erb)
  2. The Check model in app/models/blazer/check.rb stores the query reference and alert condition (e.g., result > 100) (app/models/blazer/check.rb)
  3. A background job (typically Delayed Job or ActiveJob) runs the check query and evaluates the condition; on failure, it emails recipients (app/views/blazer/check_mailer/state_change.html.erb)

Customize query result formatting and visualization

  1. Query results are returned as JSON by QueryController.run; inspect the result format in app/controllers/blazer/queries_controller.rb (app/controllers/blazer/queries_controller.rb)
  2. Chart type and options are passed to Chartkick (app/assets/javascripts/blazer/chartkick.js) which renders via Chart.js or other backends (app/assets/javascripts/blazer/chartkick.js)
  3. Modify the query run view template app/views/blazer/queries/run.html.erb to customize how results are displayed (table, chart, map, etc.) (app/views/blazer/queries/run.html.erb)

🔧Why these technologies

  • Rails (ERB, ActiveRecord, ActionController) — Provides rapid development of CRUD interfaces, ORM for audit/check/dashboard models, and request routing without extra configuration overhead
  • ACE SQL Editor — Lightweight, JavaScript-based SQL editor with syntax highlighting and autocomplete; avoids server-side parsing dependencies
  • Chartkick + Chart.js — Decouples chart rendering from server; supports multiple backends (Google Charts, Chart.js, Mapkick) with minimal code changes
  • Sequel gem (implicit from Connection abstraction) — Provides low-level, database-agnostic query execution and result marshalling across PostgreSQL, MySQL, Redshift, and others
  • Delayed Job / ActiveJob — Asynchronous check execution and email delivery without blocking user requests; enables periodic alert polling

⚖️Trade-offs already made

  • Multi-tenant data sources in a single Rails app vs. separate service per data source

    • Why: Single codebase is simpler to deploy and maintain; Connection abstraction allows swapping backends without code changes
    • Consequence: Risk of one slow query blocking others; requires careful connection pooling and query timeouts
  • Query caching at model level (in-process or Redis) vs. in-database views

    • Why: Caching in Blazer allows versioning and granular TTL control; avoids DBA overhead for view creation
    • Consequence: Cache staleness is explicit but requires manual refresh; not suitable for always-current data
  • Variable substitution via string interpolation vs. parameterized queries

    • Why: String interpolation is simpler for ad-hoc SQL and allows users to see the final query before execution
    • Consequence: Potential SQL injection risk if user input is not validated; requires stringent audit logging
  • Checks run on a schedule (background job) vs. real-time streaming

    • Why: Scheduled checks are simple to implement and cost-effective; Delayed Job is lightweight
    • Consequence: Alerts may be delayed by minutes; not suitable for real-time anomaly detection

🚫Non-goals (don't propose these)

  • Does not provide user authentication; assumes integration with existing auth system (Devise, OAuth, etc.)
  • Does not execute arbitrary Ruby code; query logic is pure SQL only
  • Not a real-time analytics engine; optimized for ad-hoc analytical queries, not streaming or sub-second latency
  • Does not manage data warehouse infrastructure; assumes data sources already exist and are accessible
  • Does not auto-detect schema changes; users must manually refresh schema browser
  • Not a replacement for BI tools like Tableau or Looker; simpler, SQL-first interface with lower feature breadth

🪤Traps & gotchas

  1. Query execution runs in a transaction and rolls back by default—modifying data is prevented but can fail silently if rollback is misconfigured. 2) BLAZER_DATABASE_URL env var must be set in production; missing it will cause queries to use the Rails app's primary database, a security risk. 3) Checks require cron/scheduler setup outside Rails; forgetting to add tasks means alerts never run. 4) Read-only database users are recommended but not enforced; a misconfigured user with write permissions defeats the rollback protection. 5) Asset pipeline must include Blazer assets in config/initializers/assets.rb for CSS/JS to load in production.

🏗️Architecture

💡Concepts to learn

  • SQL Query Rollback Protection — Blazer prevents accidental data modifications by wrapping user queries in transactions and rolling them back; understanding this mechanism is critical to knowing the security model and its limitations
  • Read-Only Database Users — Blazer relies on database-level access control to enforce query safety; a production deployment must use a role with SELECT-only permissions, a concept often overlooked by beginners
  • Rails Engines — Blazer is a Rails engine, a modular plugin architecture; understanding how engines mount routes, load migrations, and share assets is essential to customizing or extending it
  • SQL Parameterization / Prepared Statements — Blazer handles variable substitution in queries (e.g., {{user_id}}); knowing how to safely bind parameters prevents SQL injection attacks
  • Chartkick Data Format — Blazer charts are powered by Chartkick, which requires data in a specific JSON structure (arrays of hashes with keys like 'name' and 'data'); misunderstanding this format breaks visualizations
  • Cron / Scheduled Task Execution — Checks and alerts require external task scheduling (cron, Solid Queue, or Heroku Scheduler); Blazer does not manage scheduling itself, a design choice that shifts responsibility to DevOps
  • Asset Pipeline / Sprockets — Blazer bundles third-party JS libraries (Ace, Chartkick, Selectize) and stylesheets via the Rails asset pipeline; the bundling process must be understood to debug missing CSS or JavaScript in production
  • metabase/metabase — Standalone open-source BI tool with similar SQL-to-dashboard capabilities but engine-agnostic, not Rails-integrated; main competitor for teams needing external BI infrastructure
  • apache/superset — Python/Flask-based BI platform with SQL and visualization features; alternative for non-Rails stacks or teams wanting cloud-native deployment
  • ankane/searchkick — Companion gem by same author; provides Elasticsearch integration for Rails, often paired with Blazer for full-text search on dashboards
  • ankane/ahoy — Analytics tracking gem by same author; captures event data that Blazer queries can then analyze and visualize
  • ankane/blazer-docker — Official Docker containerization of Blazer; enables deployment outside a Rails app as a standalone service

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add comprehensive test coverage for Blazer controllers

The repo has 4 main controllers (base_controller.rb, checks_controller.rb, dashboards_controller.rb, queries_controller.rb, uploads_controller.rb) but no visible test files in the file structure. Given this is a security-sensitive gem dealing with SQL execution and authentication, controller tests are critical for validating authorization, query execution safety, and audit logging.

  • [ ] Create test/controllers/blazer/queries_controller_test.rb with tests for query creation, execution, and audit logging
  • [ ] Create test/controllers/blazer/dashboards_controller_test.rb with tests for dashboard CRUD operations
  • [ ] Create test/controllers/blazer/checks_controller_test.rb with tests for check creation and alert triggering
  • [ ] Add tests for authentication/authorization flows using the base_controller
  • [ ] Ensure test coverage for malicious SQL injection attempts and variable sanitization

Add integration tests for multiple database adapters

The README claims support for PostgreSQL, MySQL, Redshift, and 'many more' databases, but there's no visible test infrastructure to verify adapter compatibility. This is critical for maintaining compatibility as adapters are added or updated.

  • [ ] Create test/support/database_setup.rb to configure test databases (PostgreSQL, MySQL, SQLite)
  • [ ] Add test/integration/query_execution_test.rb with adapter-specific query execution tests
  • [ ] Create GitHub Actions workflow in .github/workflows/ to run tests against multiple databases in CI
  • [ ] Test variable substitution, result parsing, and error handling for each adapter
  • [ ] Add documentation to CONTRIBUTING.md about running integration tests locally

Document the Blazer model layer and add missing model tests

The file structure shows app/models/blazer/audit.rb but the full model layer is unclear from the partial listing. The audit feature is a core security/compliance feature, but there's no visible test coverage for the Audit model or documentation of the complete data model.

  • [ ] Map out all models in app/models/blazer/ (likely Query, Dashboard, Check, Audit, User, etc.) and document their relationships
  • [ ] Create test/models/blazer/audit_test.rb with tests for audit log creation, querying, and retention
  • [ ] Create test/models/blazer/query_test.rb with tests for query validation, variable handling, and result storage
  • [ ] Add validation tests for security-critical models (ensure queries can't be executed without proper authorization tracking)
  • [ ] Update README.md with a 'Data Model' section documenting the schema relationships

🌿Good first issues

  • Add test coverage for lib/blazer/data_source.rb—currently visible in file list but likely lacks unit tests for each adapter (PostgreSQL, MySQL, Redshift); contributor could write adapter-specific connection and query safety tests.
  • Create documentation or example SQL snippets for common analytics patterns (cohort analysis, funnel analysis, retention curves) in a new docs/examples/ directory; currently only README exists without hands-on walkthroughs.
  • Improve error messaging in app/models/blazer/query.rb when SQL syntax errors occur; add user-friendly error hints instead of raw database exceptions, with tests in spec/models/blazer/query_spec.rb.

Top contributors

Click to expand

📝Recent commits

Click to expand
  • a35536b — Version bump to 3.4.0 [skip ci] (ankane)
  • 1040a45 — Updated safely_block [skip ci] (ankane)
  • aadb521 — Updated license year [skip ci] (ankane)
  • 9a9108a — Dropped support for Ruby < 3.3 and Rails < 7.2 (ankane)
  • fed70e1 — Allow test environment for adapter_instance (#518) (JunichiIto)
  • c17d8ec — Removed dev dependency on minitest-mock (ankane)
  • e5515ec — Test with Ruby 4.0 on CI (ankane)
  • e448bbc — Updated tests for minitest 6 (ankane)
  • cda46c5 — Removed stub calls for minitest 6 [skip ci] (ankane)
  • 0ca353b — Moved protect_from_forgery after authentication (ankane)

🔒Security observations

  • Critical · SQL Injection Risk in Query Execution — app/controllers/blazer/queries_controller.rb, app/models/blazer/query.rb. Blazer is a Business Intelligence tool that allows users to write and execute SQL queries. The codebase structure suggests direct SQL query execution against multiple database types (PostgreSQL, MySQL, Redshift). Without visible parameterization patterns in the file listing, there is a high risk of SQL injection if user inputs are not properly sanitized and parameterized. Fix: Ensure all SQL queries use parameterized statements or prepared statements. Implement strict input validation and use an ORM or query builder that handles escaping automatically. Review query execution logic for any raw string concatenation with user input.
  • Critical · Cross-Site Scripting (XSS) Risk in Dashboard/Query Display — app/views/blazer/, app/assets/javascripts/blazer/queries.js, app/controllers/blazer/dashboards_controller.rb. The application displays user-generated content (queries, dashboards, results) in views. The presence of Vue.js and jQuery without obvious sanitization of query results and dashboard content creates XSS vulnerabilities. Results from database queries are likely rendered without proper encoding. Fix: Implement proper output encoding for all user-generated and database content. Use Rails' html_escape and sanitize helpers. Ensure Vue.js templates use v-text instead of v-html. Content Security Policy (CSP) headers should be implemented.
  • High · Insecure File Upload Functionality — app/controllers/blazer/uploads_controller.rb, app/models/blazer/upload.rb. The presence of app/models/blazer/upload.rb and app/controllers/blazer/uploads_controller.rb indicates file upload functionality. Without visible security controls in file naming, the codebase may be vulnerable to file upload attacks including arbitrary file upload, path traversal, and execution of malicious files. Fix: Implement strict file type validation, store uploads outside the web root, sanitize filenames, set proper file permissions, and implement virus scanning if applicable. Validate file content, not just extensions.
  • High · Missing or Insufficient Authentication/Authorization — app/controllers/blazer/base_controller.rb, app/controllers/blazer/. While README mentions 'works with your authentication system', the codebase structure shows no visible OAuth/authentication middleware in the provided file listing. Base controller exists but authorization implementation is unclear. This could allow unauthorized access to sensitive data and queries. Fix: Implement comprehensive authentication (OAuth2, SAML) and role-based authorization (RBAC) controls. Ensure all controllers require authentication. Implement query-level access controls. Add API authentication tokens if applicable.
  • High · Database Connection Information Exposure — app/models/blazer/connection.rb, app/models/blazer/uploads_connection.rb. The app/models/blazer/connection.rb file handles multiple database connections. Configuration of database credentials is not visible in the file listing, suggesting they may be hardcoded in configuration files, environment variables without proper protection, or stored insecurely. Fix: Store database credentials in environment variables or a secure vault. Never commit credentials to version control. Implement connection pooling and encryption for credentials in transit. Use IAM roles where available (AWS RDS, etc.).
  • High · No Visible Query Rate Limiting or DoS Protection — app/controllers/blazer/queries_controller.rb. A BI tool allowing arbitrary SQL execution without visible rate limiting could be abused for Denial of Service attacks through resource-intensive queries, or for resource exhaustion. Fix: Implement rate limiting on query endpoints. Add query timeout settings. Implement resource quotas per user/API key. Monitor slow queries and add alerts for excessive resource consumption.
  • Medium · Audit Trail Integrity — app/models/blazer/audit.rb. While app/models/blazer/audit.rb exists for tracking queries, the implementation details are not visible. Audit logs may not be immutable or protected against tampering, and may not capture sufficient context. Fix: Implement immutable audit logging. Store audit logs in a separate, secured database. Include all relevant context (user, timestamp, query, results summary, IP address). Implement log rotation and retention policies.
  • Medium · Missing Security Headers — undefined. undefined Fix: undefined

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Healthy signals · ankane/blazer — RepoPilot