Skip to content

Add super admin console at /-/admin/#9083

Open
ericokuma wants to merge 30 commits intomainfrom
eokuma/admin-console
Open

Add super admin console at /-/admin/#9083
ericokuma wants to merge 30 commits intomainfrom
eokuma/admin-console

Conversation

@ericokuma
Copy link
Contributor

Adds an internal super admin console to web-admin at /-/admin/, giving non-technical staff (CS, account managers) a GUI for operations currently only available via rill sudo CLI commands.

  • New route group /-/admin/ with superuser-gated auth guard (ListSuperusers check)
  • Sidebar navigation layout with 11 sections across 5 groups (Overview, People, Billing & Plans, Resources, Advanced)
  • Full pages for: Users (search/assume/delete), Billing (extend trial, set customer ID, repair, issues), Organizations (lookup, custom domain, join), Quotas (org + user), Projects (search, hibernate, redeploy), Whitelist (add/remove domains), Superusers (list/add/remove), Annotations (load/edit/save)
  • Stub pages for Virtual Files and Runtime (engineer-leaning, deferred)
  • "Admin" link in OrgHeader visible only to superusers
  • 26 new files, ~2000 lines; all using existing Orval-generated API clients with TanStack Query

Checklist:

  • Covered by tests
  • Ran it and it works as intended
  • Reviewed the diff before requesting a review
  • Checked for unhandled edge cases
  • Linked the issues it closes
  • Checked if the docs need to be updated. If so, create a separate Linear DOCS issue
  • Intend to cherry-pick into the release branch
  • I'm proud of this work!

Developed in collaboration with Claude Code

ericokuma and others added 23 commits March 19, 2026 08:30
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…adge, ActionResultBanner, SearchInput)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…d delete

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…, repair, and issue management

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…te, and redeploy

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…agement

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Contributor Author

@ericokuma ericokuma left a comment

Choose a reason for hiding this comment

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

Re-review: Issues Found & Fixed

After re-reviewing the current state of the PR, I identified and fixed the following issues:

Fixed in this pass

  1. Auth guard control flow clarity (+layout.ts): Restructured the catch block so redirectToLogin() is only called inside the 401 branch, with non-401 errors always throwing a redirect. Same behavior, clearer intent.

  2. Unreachable code (+page.svelte Users): Removed notifySuccess() call after assumedUser.assume() — since assume() sets window.location.href, the notification never displays.

  3. Unfiltered invalidateQueries() (superusers/+page.svelte): Both add and remove handlers called queryClient.invalidateQueries() with no filter, invalidating every query in the app. Scoped to /v1/superuser queries.

  4. Unfiltered invalidateQueries() (billing/+page.svelte): handleDeleteIssue invalidated all queries. Scoped to /v1/organizations and /v1/superuser/billing.

  5. ConfirmDialog closes on error (ConfirmDialog.svelte): If onConfirm threw, the dialog would close via the finally block, hiding the error. Added a catch block so the dialog stays open on failure, letting users retry or cancel.

Not applicable

  • Annotations page, whitelist page, and OrgHeader component do not exist in the current diff — these were false positives from the earlier review.
  • superuserForceAccess on getOrgProjects: the AdminServiceListProjectsForOrganizationParams type does not include this field, so no change needed.

Developed in collaboration with Claude Code

…eview issues

- Fix mutateAsync param names: organization → org for hibernate/redeploy
- Fix billing issue type to use V1BillingIssueType enum instead of string
- Fix quota fields: convert API numbers to strings for form binding
- Remove invalid superuserForceAccess from deleteUser call
- Scope invalidateQueries in superusers and billing pages instead of invalidating all
- Fix ConfirmDialog to keep dialog open on error for retry
- Clean up auth guard control flow in admin layout
- Remove unreachable notifySuccess after assume navigation
- Fix a11y: change label to span for non-input billing text

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@ericokuma
Copy link
Contributor Author

ericokuma and others added 2 commits March 20, 2026 23:44
Add new shared components (OrgSearchInput, UserSearchInput, notify,
RepresentingBanner, assume-state) that were missing from previous
commits. Remove obsolete pages (annotations, runtime, users,
virtual-files, whitelist) and unused components (ActionResultBanner,
StatusBadge, whitelist selectors) that were deleted locally but
not staged.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Remove Dashboard, Whitelist, and Advanced nav sections from sidebar
- Point Users link to root admin page (/-/admin)
- Fix users/selectors: use emailPattern with wildcards, threshold >= 3,
  remove unused assume/unassume mutations
- Fix projects/selectors: add wildcard wrapping, threshold >= 3

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
ericokuma and others added 4 commits March 21, 2026 00:06
… mount assume banner

- Move Admin Console link from top nav (OrgHeader) to profile dropdown
  (AvatarButton), removing duplicate ListSuperusers query from OrgHeader
- Add missing getBillingSetupURL function to billing selectors (was
  imported but never defined, causing 500 on billing page)
- Mount RepresentingBanner in root layout so assume-user banner appears
  when browsing as another user

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…sses

svelte-check cannot parse `@apply` with `dark:` variants in `<style lang="postcss">` blocks,
causing 12 CI errors and broken dark mode. Move all utility classes inline across 13 admin
console files and remove `<style>` blocks entirely.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ariants

Add explicit bg-white/dark:bg-slate-900 to admin layout wrapper and
bg-slate-50/dark:bg-slate-950 to content area. Add dark:text-slate-400
to all loading/empty state text that was missing dark variants.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ables

Rill's Tailwind color palette (slate, blue, red, etc.) uses CSS custom
properties that already swap between light and dark values. Using dark:
prefixed classes caused double-inversion. Remove all dark: variants and
replace bg-white with bg-slate-50 which auto-adapts.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@royendo
Copy link
Contributor

royendo commented Mar 21, 2026

ill play with in Monday but from the Video a few comments:
Billing

  • Not sure we need to surface Billing customer ID, very niche; also repair not sure what this does even with the description
    Orgs
  • add ability to assume from there (Maybe thats already there but couldnt see in video)

Projects

  • is this iterating through all orgs; probably fine but as you saw lots of duplicate project names might be confusing
  • Add ability to change prod slots
    rill sudo project edit --prod-slots 4
    Quotas dont actually set the prod slots; those are just maxes

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