Repository navigation
Studio: an admin role, ownership that can be handed on, and a support page - #13
Merged
Merged
Conversation
… page **Roles.** `admin` joins the role list: everything the owner can do except billing's three irreversible acts. There is now exactly one owner, enforced by making the role impossible to grant — it is not invitable and a role change refuses it. It moves only through a handover, which demotes the previous owner to admin in the same batch, so there is never a moment with two owners or none. Admins may manage billing, as the owner does. **Support**, at /admin, for whoever runs a hosted Studio: find any workspace or person, set a plan by hand, hand a workspace over when the owner has gone, take someone out, and read what Stripe says about a customer. It never writes to Stripe. Who counts is the SUPER_ADMINS secret, checked against the signed-in address on every request and deliberately not a column, so editing the database grants nobody access. Every change is recorded in admin_actions with the address that made it, the before and after, and the reason given. A signed-in person who isn't on the list is told the endpoint doesn't exist. **Templates** gain the twelve packs modelled on published design systems, for a team whose product already uses one. shadcn is held back: five of its tokens carry its own `var(--surface)` CSS rather than an alias, so a copy would land with broken aliases showing. **Onboarding.** A new workspace lands on its Home, where the checklist already says what's left, instead of being dropped into the importer with no way out; the importer gains one. **Emails** are rebuilt as tables with inline styles, a mark drawn from table cells so it survives a blocked-images inbox, preview text, and a greeting by first name — including the invitee's, when they already have an account. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Roles
adminjoins the role list. It does everything the owner does except the three irreversible acts: deleting the workspace, handing it on, and — no, admins can manage billing, as you asked. So the owner keeps only deletion and the handover.There is now exactly one owner, enforced by making the role impossible to grant: it isn't in the invite list and a role change refuses it. It moves only through a handover, which demotes the previous owner to admin in the same batch, so there is never a moment with two owners or none. Team gains a role dropdown and a "Make owner" button.
Everyone but a viewer counts as an editor, so an admin takes a paid seat.
Support
/admin, for whoever runs a hosted Studio: find any workspace or person, set a plan by hand, hand a workspace over when the owner has gone, take someone out, and read what Stripe says about a customer.SUPER_ADMINS— addresses separated by commas, checked against the signed-in person on every request. Deliberately not a column, so editing the database grants nobody access.admin_actions(migration 0008): who, what, before, after, and the reason typed into the drawer.A plan set by hand is separate from a subscription.
enterpriseis the one a Stripe event never overwrites, so it's the one for comps and deals invoiced elsewhere.Also
var(--surface)CSS instead of an alias, so a copy would land in a workspace with broken aliases showing. That's a pack bug with its own fix.Checked
84 tests pass, including six new ones covering the admin surface;
tsc -bclean across all four projects; docs check clean. I also ran Studio locally and used the page: signed in as a super admin, opened a workspace, set it to Enterprise with a reason, and confirmed the record showedfree → enterprisewith who and why. The two emails were rendered and looked at.Before this is useful in production
SUPER_ADMINSis already set on the production Worker. Migration 0008 needs applying to the remote D1 after merge.🤖 Generated with Claude Code