Skip to content

Discourse config for organizations - #15

Merged
camdendotlol merged 7 commits into
developfrom
cm/discourse-app-grid
Aug 4, 2026
Merged

Discourse config for organizations#15
camdendotlol merged 7 commits into
developfrom
cm/discourse-app-grid

Conversation

@camdendotlol

@camdendotlol camdendotlol commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator

Summary

This PR adds support for org admins to manage Discourse groups from within Performant Studio.

  • New grid UI based on Chelsea's original design from last year, including an item for Discourse only if the current org has Discourse enabled
  • New Settings page with a tabbed UI. Discourse settings are the only tab currently, but there's room to add more tabs in the future.
    • If the current org has Discourse enabled, org admins can create and delete groups, and configure the list of group owners for a group. The owners will have the ability to manage group members from within Discourse.
  • Updated the DiscourseConnect SSO edge function to manage group membership
    • Clerk metadata is used as the source of truth for who the owner of a group is, so users don't need to have signed into Discourse yet to be made group owners
  • New /api/discourse/groups edge function that handles the form input, talking to the Discourse API to create/destroy groups
  • Added documentation in /docs/discourse.md

Note

Some of the behavior involving logging into Discourse is hard/impossible to test before merging to staging, so I will likely need to put up a bugfix PR later.

Secondly, in theory we could make Discourse entirely self-serve by exposing the domain/secret/key fields in the Discourse settings page too. 🤔

Screenshots

App grid

Screenshot 2026-08-03 at 1 23 44 PM

Discourse config

Screenshot 2026-08-03 at 1 12 29 PM

Testing notes

Performant Studio UI

  • Discourse should not appear in the homepage app grid unless Discourse is enabled on groups according to /docs/discourse.md
  • org admins should be able to see the "Manage groups" button on the Discourse grid item
  • non-admins should not be able to see the "Manage groups" button on the Discourse grid item
  • on an org without Discourse, navigating to /settings should render a "This organization is not connected to a Discourse server" notice
  • non-admins should be redirected back to the homepage when attempting to access /settings
  • I didn't accidentally call it Discord anywhere in the UI labels

Discourse config

  • a new community appears in Discourse after creating it via Performant Studio
  • adding a user with an existing Discourse account as group owner correctly makes them group owner
  • adding a user without an existing Discourse account (i.e. a Clerk user who hasn't signed into Discourse yet) as group owner correctly makes them group owner once they sign into Discourse
  • removing an owner correctly removes them as owner of the group in Discourse
  • deleting a group works
    • deleting a group does not delete any posts and does not delete the Discourse category
    • deleting a group correctly hides the posts from everyone on the forum except for staff (admins and global mods)
    • creating a new group with the same name as the old deleted one correctly retains the posts of the old one
  • general spot checking with various inputs for group names in the Discourse config UI

@netlify

netlify Bot commented Aug 3, 2026

Copy link
Copy Markdown

Deploy Preview for performant-studio-staging ready!

Name Link
🔨 Latest commit cc0f328
🔍 Latest deploy log https://app.netlify.com/projects/performant-studio-staging/deploys/6a7239f810bef3000837b7d7
😎 Deploy Preview https://deploy-preview-15--performant-studio-staging.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@camdendotlol
camdendotlol requested a review from blms August 3, 2026 17:32

@blms blms left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is looking really good! Just wondering about a couple of areas of name collision that seem possible with the tight character limits and slugification of Discourse names.

async function ensureGroup(config: DiscourseConfig, name: string, fullName: string) {
const existing = await find(config, `/groups/${encodeURIComponent(name)}.json`)

if (existing) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this lookup by name, is it possible that a Performant Studio user could take over any existing Discourse group by accident just by reusing a name?

Wondering if it should only become editable/deletable if this Performant Studio user created it—like maybe we store the id somewhere with the Performant Studio user, or something like that. And if this is expected to be a creation step, then throw if it returns an existing record.

Maybe it's an edge case we don't need to account for, since presumably if someone can create groups on a discourse instance they should have the full access to edit/delete any group—but just thinking about name collisions producing unexpected behavior.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Discourse group creation is only for org admins, i.e. users can't self-serve Discourse groups. So I don't think we need to worry about users taking over groups, but name collisions do seem like an issue. I'm working on error handling for it now.

if ('error' in result) {
return json(result, 400)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should there be a check for name collisions after the groups are normalized? Thinking especially about truncated, slugified group and mod-group names accidentally colliding. I'm assuming the character limits come from Discourse, but they're pretty tight, and since things are being queried/keyed on name I could see this becoming a problem.

Comment thread netlify/edge-functions/discourse-groups.ts
@camdendotlol
camdendotlol requested a review from blms August 4, 2026 19:16

@blms blms left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, thanks!

@camdendotlol
camdendotlol merged commit d3df4fe into develop Aug 4, 2026
6 checks passed
@camdendotlol
camdendotlol deleted the cm/discourse-app-grid branch August 4, 2026 20:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants