Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Sql Dashboard Laravel Package

amjadiqbal/laravel-sql-dashboard

A Laravel package that adds a SQL dashboard to your application, letting you run queries and inspect database results through a simple web interface. Useful for quick data checks, debugging, and lightweight SQL monitoring.

View on GitHub
Deep Wiki
Context7

Getting Started

  • Install with composer require and pin to ^0.1.1 — this is a 0.x package, so treat the minor version as potentially breaking. Do not float on *.
  • Publish the config (and migrations, if shipped) and run php artisan migrate, then clear caches. The dashboard persists shared queries, dashboards, checks and alert settings, so the storage layer is part of your app's schema — back it up like any other table.
  • Read the README security section first, before pointing the package at anything other than a local scratch DB. It now states plainly that the guard is a tokenizer, not a SQL parser. That single sentence should drive your whole trust model: the deny-list is defence in depth, not the boundary.
  • Understand the gate before you touch it. The default edit gate is app()->environment('local'), so out of the box the dashboard is a local-only tool. Anyone who clears the gate can edit and delete shared queries, dashboards and checks — there is no per-object ownership. Widen it deliberately, and wrap the routes in your app's normal auth (plus 2FA if you have it) so the gate is a second lock, not the only one.
  • First useful flow: create a dedicated read-only DB user, register that connection, write a SELECT against a table you know, save it as a shared query, pin it to a dashboard, then add a check with an alerts.rows_in_alert threshold and a mail alert. That exercises the whole path — connection check, query execution, persistence, alerting — in about ten minutes.
  • If you are upgrading from 0.1.0, do it now (see Gotchas) and then open each configured connection once. The connection check got stricter, so a connection that worked yesterday may be refused today.

Implementation Patterns

  • One low-privilege connection per environment. Create a MySQL/Postgres user with SELECT only on the schemas you want visible. The package refuses superusers and dangerous role memberships, but that refusal is a backstop; the grant is the real control. Never reuse your application's runtime credentials.
  • Shared queries as the reusable unit. Build a library of named, parameterised queries for the handful of metrics your team actually asks about ("signups today", "failed jobs last hour", "orders stuck in pending"), then compose dashboards from them. Treat the shared objects like a wiki page rather than code — they are editable by anyone with the gate and are not versioned.
  • Checks for the "is anything wrong?" questions. A check plus alerts.rows_in_alert is effectively a cron-free assertion: "if this returns more than N rows, tell someone." Set the threshold per check rather than relying on a global default; the failure mode of a shared threshold is either silence or constant noise.
  • Seed your query library. Put the team's baseline queries into a seeder or a small migration so onboarding doesn't involve hand-clicking. This also gives you a reviewable diff when someone changes a query, which the UI does not.
  • Fake the notifiers in tests. Slack is documented as tested only against a faked HTTP client, so treat that assertion as unverified in production. Build a fake-client test for your Slack payload and a Mail::fake() test for the mail path, then verify once by hand in a real workspace.
  • Keep CI cheap. Run query tests against an in-memory SQLite connection rather than a containerised Postgres. Note that SQLite's authorizer layer only applies on PHP 8.5+, so pin your CI PHP version if the read-only guarantee matters to the test.
  • Assert the gate is closed in production. A tiny test that resolves the gate under the production environment and expects false catches the classic mistake of widening the gate for a demo and forgetting to narrow it again.

Gotchas and Tips

  • The 0.1.1 security fix is the reason to upgrade. In 0.1.0 the statement check only matched a bare function name, so quoting, back-ticking, bracketing, schema-qualifying or U&"..."-escaping the name ("pg_advisory_lock"(1), pg_catalog."pg_read_file"(...), `GET_LOCK`(...), [load_extension](...)) slipped straight past the deny-list. If anyone other than you can reach the query box on 0.1.0, assume the deny-list was decorative.
  • Session locks outlive the transaction. PostgreSQL advisory locks and MySQL GET_LOCK are not released by a rollback. 0.1.1 explicitly releases them after each query. If you write your own execution path or wrap the package's runner, replicate that cleanup or a "read-only" query can wedge a connection pool.
  • PROCESS is now a refusal for MySQL. Monitoring and analytics users very often carry PROCESS (alongside the already-refused FILE and SUPER). Expect an upgrade-day surprise where a long-working connection suddenly fails the check; the fix is a fresh, narrower user, not a config workaround.
  • PostgreSQL role checks are membership-based and apply on standbys too. Membership in pg_read_server_files, pg_write_server_files, pg_execute_server_program or pg_signal_backend, dblink execution rights, and USAGE on a foreign server all disqualify the role. Superusers are refused even on a standby, so there is no "it's only a replica" exemption.
  • SQLite is read-only by two mechanisms, one of which is version-gated. Below PHP 8.5 you get the read-only file flag only, not the authorizer. Don't claim a hard guarantee for SQLite on older runtimes.
  • Tokenizer, not parser. Even after 0.1.1, do not expose this to untrusted users. The deny-list covers function families (server-file, large-object, replication, backend-signal, logical decoding, dblink, postgres_fdw, MySQL wait/lock and UDF names) but a tokenizer reasons about tokens, not semantics. Your grant is the control that holds.
  • Config caching. Changing alerts.rows_in_alert or the gate config won't take effect until php artisan config:clear / a redeploy that rebuilds the cache.
  • Alert fatigue is a config problem, not a code problem. A check that returns one row on every poll will page forever. Tune rows_in_alert per check and delete stale checks aggressively — anyone with the gate can create them.
  • Slack is marked untested. The docs now say so; believe them. The mail path is the one the art advertises, and it is the safer default for anything you actually rely on at 3am.
  • No ownership model. There is no per-user scoping of shared queries, dashboards or checks; deletion is one click for anyone through the gate. If you need an audit trail, capture it at the route/middleware level yourself — the package won't do it for you.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect
youbar/easy-crud
c-point-labs/laravel-hostyourai
dbravoan/dbcms-admin-theme-dbcms
dbravoan/dbcms-theme-db-cyber
dbravoan/dbcms-blocks-basic
dbravoan/dbcms-module-content-audit
dbravoan/dbcms-module-ai-assistant
paygate-to/paygate-php
padosoft/askmydocs-connector-base
defstudio/supercharged-carbon
bernskioldmedia/laravel-matomo