Skip to content

feat(web): hide personal surface for users with disabled personal account - #4453

Merged
markijbema merged 7 commits into
mainfrom
mark/hide-personal-menu-invited-only
Jul 8, 2026
Merged

feat(web): hide personal surface for users with disabled personal account#4453
markijbema merged 7 commits into
mainfrom
mark/hide-personal-menu-invited-only

Conversation

@markijbema

@markijbema markijbema commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

What

Builds on #4447 (personal_account_disabled). When a user's personal account is disabled — i.e. the login exists only because they were invited to an org — we stop surfacing the personal-account UI and default them into their organization instead.

Approach: we don't link these users to personal pages, but we don't hard-block them either. Direct navigation to a personal route still works and renders the page (with the personal sidebar), it's just no longer reachable through our own navigation.

Changes

  • Default landing (getProfileRedirectPath): users with a disabled personal account are always sent into an organization (their oldest, deterministic ordering) regardless of org count; falls back to /connected-accounts if they somehow belong to no orgs. This is a default-destination choice, not a block.
  • Org switcher: hides the "Personal" entry for these users.
  • Footer user menu (SidebarUserFooter): the avatar/name row becomes a dropdown containing Connected Accounts + Sign out — the home for user-global identity surfaces, shown in both the personal and org sidebars.
  • Personal sidebar: drops the Connected Accounts item (now in the footer for everyone).
  • Sidebar selection (AppSidebar): on /connected-accounts (the one personal route we still link to, from the footer), these users get their default org's sidebar instead of the personal one. Every other personal route falls through to the normal personal sidebar so the page renders.

What this intentionally does NOT do

  • No catch-all server-side redirect guard blocking personal routes. Direct navigation to /profile, /subscriptions, /cost-insights, etc. is allowed and renders normally; those routes are simply not linked for these users.
  • The org menu stays strictly org-scoped and untouched — Connected Accounts lives in the footer, not the org Account group.

Design notes

  • Connected Accounts is genuinely user-global (primary email + linked auth providers), not personal-account-scoped, which is why it moves to the footer user menu.
  • Terminology is kept tied to the personal_account_disabled field (no "invited-only" synonym) so the concept stays greppable.

Testing

  • Added getProfileRedirectPath tests: disabled personal account with multiple orgs (→ an org) and with zero orgs (→ /connected-accounts).
  • pnpm --filter web typecheck, server.test.ts (56/56), pnpm --filter web lint (clean), pnpm format.

When personal_account_disabled is true (accounts created solely to accept
an org invite), redirect these users off personal routes into their
organization and trim the personal-account UI:

- getUserFromAuthOrRedirect redirects invited-only users off personal
  routes (allowlist: /connected-accounts) using x-pathname
- getProfileRedirectPath sends invited-only users to their oldest org
  (stable ordering), falling back to /connected-accounts when they have
  no orgs
- OrganizationSwitcher hides the Personal entry for these users
- SidebarUserFooter becomes a user menu (Connected Accounts + Sign out),
  the home for user-global identity surfaces
- PersonalAppSidebar drops Connected Accounts (now in the footer)
@markijbema
markijbema force-pushed the mark/hide-personal-menu-invited-only branch from c350267 to eaa574a Compare July 8, 2026 12:00
@markijbema
markijbema marked this pull request as ready for review July 8, 2026 12:01
Mark IJbema added 4 commits July 8, 2026 14:08
Connected Accounts (and any allowlisted personal route) has no org id in
the URL, so AppSidebar fell through to the personal sidebar for
invited-only users. Render their default organization's sidebar instead,
using the same oldest-org default as getProfileRedirectPath, and show an
empty sidebar frame while resolving it to avoid flashing the personal
menu. Orphan users with no orgs still fall back to the personal sidebar.
…only

Keep terminology tied to the personal_account_disabled field rather than
introducing an invited-only synonym, so the concept stays greppable.
Instead of blocking direct navigation to personal routes for users with a
disabled personal account, only avoid linking to those pages ourselves
(sidebar, switcher, footer) and keep the default landing redirect. Direct
navigation to a personal route is now allowed rather than redirected.
Only /connected-accounts (the route we link from the footer) keeps a
personal-account-disabled user in their org sidebar. Other personal routes
reached directly now render the personal sidebar so the page loads instead
of erroring; those routes are simply not linked for these users.
@markijbema markijbema changed the title feat(web): hide personal surface for invited-only users feat(web): hide personal surface for users with disabled personal account Jul 8, 2026
@kilo-code-bot

kilo-code-bot Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Executive Summary

Incremental review of the latest commits: AppSidebar.tsx generalizes footer-linked-route handling to /connected-accounts, /install, and /learn, and SidebarUserFooter.tsx adds Install/Learn to the dropdown (with the now-unused Start group cleanly removed from PersonalAppSidebar.tsx). This directly addresses the prior reviewer request; no new issues found with high confidence in the changed code.

Files Reviewed (3 files)
  • apps/web/src/app/(app)/components/AppSidebar.tsx
  • apps/web/src/app/(app)/components/PersonalAppSidebar.tsx
  • apps/web/src/app/(app)/components/SidebarUserFooter.tsx
Previous Review Summary (commit effea99)

Current summary above is authoritative. Previous snapshots are kept for context only.

Previous review (commit effea99)

Status: No Issues Found | Recommendation: Merge

Executive Summary

Reviewed the invited-only (personal-account-disabled) UI/redirect changes across the sidebar, org switcher, footer menu, and profile-redirect logic; the new gating and sorting logic is internally consistent with existing types and no bugs were found with high confidence in the changed code.

Files Reviewed (6 files)
  • apps/web/src/app/(app)/components/AppSidebar.tsx
  • apps/web/src/app/(app)/components/OrganizationSwitcher.tsx
  • apps/web/src/app/(app)/components/PersonalAppSidebar.tsx
  • apps/web/src/app/(app)/components/SidebarUserFooter.tsx
  • apps/web/src/lib/user/server.test.ts
  • apps/web/src/lib/user/server.ts

Reviewed by claude-sonnet-5 · Input: 26 · Output: 3.8K · Cached: 525.8K

Review guidance: REVIEW.md from base branch main

// other personal routes are not linked but remain accessible with the personal
// sidebar if reached directly.
const isLinkedAccountRoute =
pathname === '/connected-accounts' || pathname.startsWith('/connected-accounts/');

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think we should also include /install and /learn and move those to the new dropdown as well

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done in 4d788a2 — moved Install and Learn into the footer user menu alongside Connected Accounts, and removed the Start group from the personal sidebar. They're now available in both the personal and org sidebars.

Mark IJbema added 2 commits July 8, 2026 14:45
Per PR review, relocate the Start group (Install, Learn) from the personal
sidebar into the footer user menu alongside Connected Accounts, so they are
available in both the personal and org sidebars.
Clicking Install or Learn from the footer user menu previously dropped a
personal-account-disabled user back to the personal sidebar. Treat all
footer menu routes (Connected Accounts, Install, Learn) the same, keeping
them in their org sidebar like Connected Accounts already did.
@markijbema
markijbema enabled auto-merge (squash) July 8, 2026 12:56
@markijbema
markijbema merged commit 5746de6 into main Jul 8, 2026
15 checks passed
@markijbema
markijbema deleted the mark/hide-personal-menu-invited-only branch July 8, 2026 12:56
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