← All cases
Case 015 Community Tooling

Discord Server Manager

Running a curated Discord server means authoring inside Discord's own chat box. Long rules or guide posts hit the 2,000-character limit and get split by hand; editing one means deleting and reposting, which loses the pin and scrambles the order; and channel structure is built by right-clicking one channel at a time with permission overwrites set from memory.

A local web dashboard with the bot embedded in it. You write the content and plan the channel tree in the browser; the bot renders it into Discord and keeps it in sync. Long markdown is split into message-sized chunks, posted and pinned once, then edited in place on every later publish — so pins survive and nothing is ever reposted. Channel plans preview before they apply and travel between servers as blueprints.

Exhibit pending Visual evidence to be filed
Post engine
markdown split into ≤2,000-char messages, pinned once, then edited in place
Change detection
per-message content hash — unchanged chunks are never touched, so no repost churn
Access modes
Open / Read-only / Hidden, applied as Discord permission overwrites
Safety model
adopt existing channels, preview before apply, never delete a channel
Blueprints
a server plan exports as a file — channel tree plus seeded posts, published on apply
Architecture
the core has no Discord.Net reference; the bot sits behind an IDiscordGateway seam
Tests passing
37 xUnit against the core with a fake gateway — no network, no live server

.NET 10 Blazor Server hosting a Discord.Net bot in-process, EF Core over SQLite, multi-tenant by guild id with the token held in user-secrets. The gateway seam was drawn first precisely so agents could build and regression-test the whole post and structure engine against a fake Discord instead of a live server.

An unhandled error has occurred. Reload 🗙

Rejoining the server...

Rejoin failed... trying again in seconds.

Failed to rejoin.
Please retry or reload the page.

The session has been paused by the server.

Failed to resume the session.
Please retry or reload the page.