Dashboard-first: why we built the web app before the slash commands

April 19, 2026·6 min read·The Kovra team

Discord bot competitors treat the dashboard as a config layer — a place you go to set a welcome channel once and forget about. The real work, they assume, happens in the server itself, via slash commands and reaction menus.

We think that's backwards for any moderation workflow more complex than /ban spammer. Here's how we think about it.

Slash commands optimize for speed, not for thought

A slash command is great when you already know what you want. Someone posts a phishing link, you type /ban @user reason:phishing, it's gone. Three seconds.

But most moderation decisions aren't like that. You're reviewing a report. You're looking at a user's case history before deciding severity. You're trying to find the pattern across last week's AutoMod triggers. You're running a mass-ban sweep with 300 IDs from a raid. None of that fits comfortably in a command-line interface inside a chat app.

The case browser is the work surface

Kovra's case browser is where most of your time will be spent. Every moderation event — whether you triggered it from the dashboard, a slash command, or AutoMod — lands here as a row. You filter by action, by source, by moderator, by user. You click a row and a side sheet opens with the full payload: who got acted on, what the reason was, whether they got DMed, whether a DM failed, what the case number is in your log channel, which AutoMod rule fired (if any), what the user said to trigger it.

You can't build this in slash commands. Or rather — you can, but nobody will use it, because Discord's ephemeral message UI is hostile to dense tabular data.

The Action Queue makes both surfaces equal citizens

When you click "Ban" in the dashboard, Kovra doesn't call Discord's API directly from the web server. It pushes an action into a Redis stream signed with HMAC. Guard (the bot) consumes the stream, verifies the signature, executes the action, and publishes the result back via SSE. The dashboard updates in real time.

The same path runs when you use /mod ban in Discord. Slash command → action executor → same DB row → same case number → same SSE event → dashboard updates. There is no "dashboard path" and "Discord path." There's one path and two entry points.

Live everywhere, not just in config pages

Pick any page in Kovra's dashboard. Members, cases, audit log, overview KPIs. Now run a /ban from Discord. The page updates within a second — no refresh needed. We run a per-guild SSE stream that publishes every Discord event (member join, role change, voice state, channel create) and the frontend subscribes in the guild layout. TanStack Query invalidations fire on receipt, data refetches, UI re-renders.

This is table stakes for a modern moderation tool and the competitors don't have it. It's also the hardest part to build — the easy path is to poll every 30 seconds, which makes the dashboard feel stale. We committed early to "live everywhere" and paid the engineering cost.

What this means for you

Don't bookmark slash commands. Bookmark dash.kovra.xyz. That's where you run your team's moderation. Slash commands are for the single quick action when you're already in Discord reading messages. Everything else — the audit, the tuning, the review, the analytics — lives in the dashboard.

Open Cmd+K on any page, type a name, pick an action. That's the primary workflow.