Discord: no self-serve guild->org link and no admin UI for radio channels/bots (follow-up to #203/#204) #213

Open
opened 2026-10-04 18:10:01 -04:00 by logan · 5 comments
Owner

Follow-up left open by the feat/discord-system PR (server-26#203/#204, node-26#25).

What exists after that PR: discord_guilds/{guild_id}.org_id scopes every bot command; a platform admin can set it with PUT /discord/guilds/{id}/link. A guild with no link falls back to DISCORD_UNLINKED_GUILD_ORG_ID (default founding), which keeps today's single-org deployment working but means any server the DRB bot is invited to acts for the founding org until linked. Set it to "" once real links exist.

Not built (design-canvas/discord-system-notes.md Phase 1 items 1 and 6):

  1. /drb link code: in the Discord bot + web-side code generation (reuse the /auth/link pattern), so an org owner links their own server; unlinked servers see only /drb link and /help.
  2. Frontend admin page: linked guilds, streams (desired vs actual), radio bots with valid / guild membership / invite_url / lease. /tokens page still shows only the legacy in_use/assigned_node_id mirrors; the new token fields (valid, guild_ids, check_error, invite_url, lease) and POST /tokens/{id}/refresh have no UI.
  3. Node page "Join Discord" still takes raw guild/channel IDs (also #109 item 13); it now maps onto a stream pinned to that node.
  4. GET /tokens is now platform-admin only (#204 item 6) — the systems page preferred-token picker (app/systems/page.tsx ~L1227) will error for a non-admin.

Unverified: frontend has no typecheck on this box.

Follow-up left open by the feat/discord-system PR (server-26#203/#204, node-26#25). **What exists after that PR:** `discord_guilds/{guild_id}.org_id` scopes every bot command; a platform admin can set it with `PUT /discord/guilds/{id}/link`. A guild with no link falls back to `DISCORD_UNLINKED_GUILD_ORG_ID` (default `founding`), which keeps today's single-org deployment working but means **any** server the DRB bot is invited to acts for the founding org until linked. Set it to `""` once real links exist. **Not built (design-canvas/discord-system-notes.md Phase 1 items 1 and 6):** 1. `/drb link code:` in the Discord bot + web-side code generation (reuse the `/auth/link` pattern), so an org owner links their own server; unlinked servers see only `/drb link` and `/help`. 2. Frontend admin page: linked guilds, streams (desired vs actual), radio bots with `valid` / guild membership / `invite_url` / lease. `/tokens` page still shows only the legacy `in_use`/`assigned_node_id` mirrors; the new token fields (`valid`, `guild_ids`, `check_error`, `invite_url`, `lease`) and `POST /tokens/{id}/refresh` have no UI. 3. Node page "Join Discord" still takes raw guild/channel IDs (also #109 item 13); it now maps onto a stream pinned to that node. 4. `GET /tokens` is now platform-admin only (#204 item 6) — the systems page preferred-token picker (`app/systems/page.tsx` ~L1227) will error for a non-admin. Unverified: frontend has no typecheck on this box.
Author
Owner

PR for item 1 (self-serve /drb link + web code generation + unlinked-server gate): #218 — branch feat/213-guild-link. Items 2-4 remain for the sibling slices.

PR for item 1 (self-serve /drb link + web code generation + unlinked-server gate): https://git.vpn.cusano.net/logan/server-26/pulls/218 — branch feat/213-guild-link. Items 2-4 remain for the sibling slices.
Author
Owner

PR #219 (feat/213-discord-admin): item 4 fixed (systems-page preferred-token picker, /tokens and the /network Bot Tokens card are now admin-only; no non-admin listing endpoint, because the save behind the picker is admin-only too) and item 2 built (Settings > Discord: radio channels desired vs actual, servers + link, radio bots with valid / membership / invite links / lease / refresh; /tokens shows the same table). Items 1 and 3 are not in it. Unlink + org-owner view filed as #221.

PR #219 (`feat/213-discord-admin`): item 4 fixed (systems-page preferred-token picker, `/tokens` and the `/network` Bot Tokens card are now admin-only; no non-admin listing endpoint, because the save behind the picker is admin-only too) and item 2 built (Settings > Discord: radio channels desired vs actual, servers + link, radio bots with valid / membership / invite links / lease / refresh; `/tokens` shows the same table). Items 1 and 3 are not in it. Unlink + org-owner view filed as #221.
Author
Owner

Item 3 is in PR #220 (feat/213-node-join-picker): #220

  • The raw-ID modal is replaced by a picker over the org's servers and the voice channels the DRB bot pushes (PUT /discord/guilds/{id}/directory). A pick becomes a stream pinned to the node through the #216 desired-state API.
  • Pairs with #218 (item 1): the picker reads #218's guild_name and skips fallback for servers with unlinked_at. The two PRs merge without conflicts.
  • Start/stop is now allowed for the org owner and the owning operator, not only platform admins.
  • The legacy raw-ID discord_join now refuses servers outside the node's org.
  • Prod needs the discord-bot image redeployed before any channels show up.

Items 2 and 4 are still open (other slices).

Item 3 is in PR #220 (`feat/213-node-join-picker`): https://git.vpn.cusano.net/logan/server-26/pulls/220 - The raw-ID modal is replaced by a picker over the org's servers and the voice channels the DRB bot pushes (`PUT /discord/guilds/{id}/directory`). A pick becomes a stream pinned to the node through the #216 desired-state API. - Pairs with #218 (item 1): the picker reads #218's `guild_name` and skips fallback for servers with `unlinked_at`. The two PRs merge without conflicts. - Start/stop is now allowed for the org owner and the owning operator, not only platform admins. - The legacy raw-ID `discord_join` now refuses servers outside the node's org. - Prod needs the discord-bot image redeployed before any channels show up. Items 2 and 4 are still open (other slices).
Author
Owner

Follow-up PR #224 (feat/discord-stream-logging-remove): #224

  • c2-core now logs every node-reported radio-channel state transition with the node's error text and reason code, plus a line naming the token when a radio bot fails to log in.
  • Remove a radio channel: admin on Settings > Discord, org owner on the node page. It is stopped through desired state first, then deleted.
  • Remove a server: admin, Servers tab. It is unlinked with no fallback org, and the radio bots can optionally leave.

The live "bot online but never in voice" symptom is node-26#37.

Follow-up PR #224 (`feat/discord-stream-logging-remove`): https://git.vpn.cusano.net/logan/server-26/pulls/224 - c2-core now logs every node-reported radio-channel state transition with the node's error text and reason code, plus a line naming the token when a radio bot fails to log in. - Remove a radio channel: admin on Settings > Discord, org owner on the node page. It is stopped through desired state first, then deleted. - Remove a server: admin, Servers tab. It is unlinked with no fallback org, and the radio bots can optionally leave. The live "bot online but never in voice" symptom is node-26#37.
Author
Owner

Owner-reported overwrite bug (adding a radio channel to a voice channel that already had one replaced it and kicked its bot) is fixed in PR #227: #227 (branch fix/213-multi-stream-per-channel). Per the owner decision, a voice channel can carry several streams, each with its own bot and system. Stream ids are now unique per stream; old guild:channel ids keep working. Picking a bot that is already in the server returns a 409 that names the stream using it. No Client change needed.

Owner-reported overwrite bug (adding a radio channel to a voice channel that already had one replaced it and kicked its bot) is fixed in PR #227: https://git.vpn.cusano.net/logan/server-26/pulls/227 (branch fix/213-multi-stream-per-channel). Per the owner decision, a voice channel can carry several streams, each with its own bot and system. Stream ids are now unique per stream; old guild:channel ids keep working. Picking a bot that is already in the server returns a 409 that names the stream using it. No Client change needed.
logan added the area/discordarea/frontend
priority
p2
type
feature
labels 2026-10-05 02:05:03 -04:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: logan/server-26#213