laranail/db-console-webui
A thin Livewire + Flux web UI for laranail/db-console. It provides all screens with zero business logic—every action calls the audited core services and shares the same validation, keeping names, hosts, and privileges consistent across CLI, REST API, and UI.
This is the Livewire WebUI for laranail/db-console: a dashboard, database wizard, account manager, role manager, webhook manager and server switcher that sit on top of db-console's admin capabilities. You are not writing SQL in Blade — you are registering the package, granting abilities, and letting operators drive db-console from a browser.
php artisan laranail::db-console-webui.install (the bare db-console-webui:install still works but is a hidden forwarder that prints a deprecation line). Publish config so you can see which servers/routes are registered, then publish views and translations only if you intend to override them.php artisan route:list | grep db-console-webui), the access middleware, and the abilities it checks. As of 0.1.1 the scoped abilities are laranail-db-console.database.view and laranail-db-console.server.view. db-console still honours the old db-console.* names as deprecated aliases, so an existing policy granting either keeps working — but write new policies against the scoped names.The package requires laranail/db-console ^0.1.1 and now declares illuminate/{console,http,routing} at ^13.0 directly. If you were relying on those arriving transitively, check your Laravel constraint now — this targets Laravel 13.
Host your own screens, not your own controllers. The pages are Livewire components; the integration surface is middleware, policies, and the host's password.confirm route. Keep your own code out of the package's views and let overrides live in resources/views/vendor/laranail-db-console-webui/.
Let the components own the refusal conversation. Since 0.1.1, creating an account or database that already exists is refused rather than silently succeeding — unless the operator is permitted to adopt the resource. The refusal carries the policies the operator may resubmit with (adopt; for an account, adopt and set a new generated password). The UI only renders those choices when the refusal offers them and never sends a policy the refusal did not offer, so a host policy is the single place you widen what operators can do. An adopted resource is reported as adopted, not created — don't assume a success banner means "new". Http\Livewire\Concerns\RespondsToRefusals is the shared handling if you build additional screens in the same style.
Grant least privilege, and mirror it in CI. db-console publishes a recommended minimal MySQL grant with sql_require_primary_key=ON; the package's own live suite runs against MySQL 8.4 and PostgreSQL 18 as a restricted admin (CREATEDB CREATEROLE, not superuser). If you want the same confidence, run the live Pest group against real servers — it skips without DB_CONSOLE_LIVE_* env vars, so wire those into your own CI and use --fail-on-skipped to catch a silently skipped suite. LiveAdminGrantTest asserts the workflow grant equals MinimalAdminGrant, so if you fork the workflow, keep them equal or the test will tell you.
Read hosting facts from the registry, don't hard-code them. The account host starts at ServerRegistry::defaultAccountHost() (% on a managed MySQL) rather than localhost, and is hidden entirely where the engine has no host scoping. The server switcher shows a managed server's provider. On managed servers the database wizard points at the provider's point-in-time recovery as the restore path, and reports a drop stopped by a failed backup as BackupFailed — catch and surface that rather than treating it as a generic failure.
Listen on the canonical event, tolerate the old one during migration. The switcher dispatches laranail-db-console-webui:server-changed and, for now, db-console:server-changed beside it. Use Support\BrowserEvents instead of string literals in your own JS/Alpine, and Support\LivewireNames instead of literal component names.
Identity confirmation is a redirect, not a reimplementation. When db-console needs a recent confirmation, the components render a "Confirm your identity" link to the host's password.confirm route when it exists. The host authenticates; the WebUI only points at it. Make sure that route exists if you expect the flow to complete.
Route::has() and routeIs() no longer see the bare names. route('db-console-webui.dashboard') still resolves the scoped route and logs one warning per name per process — but Route::has('db-console-webui.dashboard') is false and routeIs() won't match. This breaks @if(Route::has(...)) navigation guards and active-link highlighting that people copy-pasted. Switch all of them to laranail-db-console-webui.<page> for dashboard, databases, accounts, roles, webhooks. Use Support\RouteNames (and RouteNames::legacyMap()) as the single source.E_USER_DEPRECATED per name per process on Livewire 4 (Livewire 3 normalises the name first, so no notice there). If you assert on deprecations, expect the once-per-process cadence.lang/vendor/laranail/db-console-webui were never read because the package translated through the hyphenated namespace. That is fixed: the package now translates via laranail/db-console-webui:: and falls back to an override made against laranail-db-console-webui:: when the canonical line is still the packaged default. When both override the same line, the canonical one wins. Route your own string lookups through Support\Translations so this rule stays in one place.laranail/db-console-webui:: and laranail-db-console-webui::). The package's own views use the slash form; overrides in either apply. The correct override directory is resources/views/vendor/laranail-db-console-webui/ — older docs said resources/views/vendor/db-console-webui/, which silently does nothing.vendor/. A previous install-command test left published views in the Testbench skeleton inside vendor/, shadowing package views on later local runs. The test now cleans up after itself; if you hit the symptom on an older checkout, delete the stray published views.Routing\BareRouteNameResolver is deprecated; it now delegates to package-tools' BareRouteNameAliases via URL::resolveMissingNamedRoutesUsing() and defers to any resolver installed before it. Its old bug — passing a foreign resolver's non-string answer straight through and raising TypeError under strict_types — is fixed: a non-string answer reads as "not resolved". If you wrote a resolver assuming it always gets a string, that assumption is now wrong.NamingConventionTest's idea locally against your own additions. It reads the live router, rate limiter, Artisan and middleware registries and fails on bare names the package owns; it also covers Livewire components, view/translation namespaces and the browser event. Adding a screen means touching Support\RouteNames, Support\LivewireNames, Support\BrowserEvents — not sprinkling strings.BareRouteNameResolver as gone in the next minor. Budget the rename now rather than during the upgrade.How can I help you explore Laravel packages today?