Economy overview with a trend chart
Nine headline numbers, then the same silver charted settle by settle.
Raids settled, Gross silver, Merchant bank, Regear bank, Repairs, Payouts, Merchant tax, Regear tax and Paid to outsiders, aggregated straight off the settlement history and the guild banks. Below them a line chart plots gross, merchant tax and regear tax cumulatively, one point per settlement. Casual raids are excluded from every guild money figure and from the chart, because a casual settle credits nobody and fills no bank — yet its gross is a number typed by whoever ran the raid, with no officer review.
Who got regeared, who won what
The Regear tab by player or by event; the Giveaways tab with every recent draw and what it actually paid.
The Regear tab has a Players view and an Events view, filtered by All time, This week or the active season, with cards for Regeared, Claims, Drives and Biggest regear, a death-versus-overcharge split bar and a "Regear paid over time" chart. Names resolve in-game-name first, because a regear board is about the player, not the Discord account, and your own row is highlighted. Officers get two extra columns nobody else sees — an approval rate per player and a turnaround time per drive — because those measure the staff, not the members. Both tabs are open to members, because the same data was already public in Discord.
Ranks resolved exactly as the bot resolves them
Admin, officer, regear staff and recruiter — four separate bits, not one.
The dashboard mirrors the bot’s permission module field for field. Administrator is a separate bit from officer on purpose: the bot draws a hard line where a recruiter owns every action and an admin owns every setting, and settings that could escalate privilege gate on admin alone. A dashboard that only knew "officer" could not express that line at all. The role lookup is skipped entirely when a server has configured no tier roles, and a failed role fetch falls closed to member tier rather than guessing.
Plans, stored per server
Free, Pro and Enterprise exist as plans — today the paid feature is white-label.
Each server carries one plan, stored on its row and shown in /settings and on the dashboard’s server picker. The rule that turns a plan into features is a tiny pure function with its own tests, so gating a feature is one line, not a refactor — and an unknown or legacy plan string always reads as Free, never as more. What sits behind each paid tier is still being settled; today the paid feature is the white-label bot.
Your dedicated bot asks Discord for less Pro
It asks Discord only for what its own application has switched on, and if the gateway refuses, it steps down and stays online instead of dying.
Before login the runtime reads the tenant application’s advertised flags and picks the largest intent set it can plausibly use. If the gateway refuses that set because a privileged intent is switched off in the portal, the bot steps down a ladder and tries again, so it ends up online rather than becoming a dead shard. The ladder protects screenshot capture: server-member access is dropped first, message content last. The floor is two non-privileged intents — servers and voice states — which is lighter than the shared bot runs on.
One deploy updates the whole fleet Pro
Every dedicated bot is a separate Discord client in the same process, wired to the same handler.
There is no per-tenant code anywhere: brand and plan are rows in the database, and the interaction handler is client-agnostic. So a dedicated bot never falls a version behind the shared one — they update together. Command definitions can also be pushed to every tenant on demand, as a bulk overwrite rather than create-each, so an unchanged command set costs nothing against Discord’s daily budget. Tenant startup is isolated too: a bad or revoked token is logged and skipped, never taking down the shared bot or the other tenants.
The hardening two security reviews asked for
24-hour cap, constant-time state compare, 60-second Discord cache, errors that leak nothing.
Two adversarial security reviews were run against this surface — one on cross-guild isolation, sessions and SQL, one on the token-intake path. Neither found a leak, and the hardening they did ask for is in place: the OAuth state is compared in constant time, sessions expire at 24 hours regardless of Discord’s longer token life and a sweeper evicts dead ones, your server list and roles are cached on the session for 60 seconds so reads do not re-hit Discord, and Discord upstream failures map to a clean 502 or 503 instead of a 500 that leaks internal paths.
💬 Feedback and “what’s new” on the same board
A Feedback button rides on the status board, and each release posts its notes there once.
The Feedback button is rebuilt with the board on every state change, so it survives the 🟢 / 🟠 / 🔧 flips. Release notes are posted once per release into servers that installed the board, and the claim is made in the database before the message is sent — the shared client and the tenant clients boot in the same process and could otherwise both reach the same server, so exactly one wins and the loser skips. A send that fails releases the claim and retries on the next boot.
Six languages, one server-wide setting
English, Ukrainian, French, Russian, Portuguese (BR) and German, across 2,351 message keys.
An admin picks the server’s language in /settings → 👥 Server. That choice is authoritative for everything the bot says in that server, including private replies — a Ukrainian guild speaks Ukrainian to a member whose Discord client is set to English, which is what guilds actually expect. This was a deliberate reversal of an earlier version that followed each member’s own client language. Every key carries all six languages, and any gap falls back to English rather than rendering blank.