fix: vendor scoping, sidebar visibility, and landing redirect
All checks were successful
CI / build (push) Successful in 50s
CI / docker (push) Successful in 41s

- OrgResolver merges global + org-scoped token scopes so vendor's
  platform:admin (from global saas-vendor role) is always visible
- LandingRedirect waits for scopes to load before redirecting
  (prevents premature redirect to server dashboard)
- Layout hides tenant portal sidebar items when vendor is on
  /vendor/* routes; shows them when navigating to tenant context

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
hsiegeln
2026-04-09 23:39:12 +02:00
parent c674785c82
commit 00476c974f
2 changed files with 11 additions and 2 deletions

View File

@@ -35,6 +35,9 @@ export function Layout() {
const isVendor = scopes.has('platform:admin');
const isTenantAdmin = scopes.has('tenant:manage');
const onVendorRoute = location.pathname.startsWith('/vendor');
// Vendor on vendor routes: show only TENANTS. On tenant routes: show tenant portal too (for debugging).
const showTenantPortal = isTenantAdmin && (!isVendor || !onVendorRoute);
// Determine current org slug for server dashboard link
const currentOrg = organizations.find((o) => o.id === currentOrgId);
@@ -68,8 +71,8 @@ export function Layout() {
</Sidebar.Section>
)}
{/* Tenant portal — only visible to tenant admins (tenant:manage scope) */}
{isTenantAdmin && (
{/* Tenant portal — visible to tenant admins; hidden for vendor on vendor routes */}
{showTenantPortal && (
<>
<Sidebar.Section
icon={<LayoutDashboard size={16} />}

View File

@@ -22,6 +22,12 @@ function LandingRedirect() {
const { organizations, currentOrgId } = useOrgStore();
const currentOrg = organizations.find((o) => o.id === currentOrgId);
// Wait for scopes to be resolved — they're loaded async by OrgResolver.
// An empty set means "not yet loaded" (even viewer gets observe:read).
if (scopes.size === 0) {
return null; // OrgResolver is still fetching tokens
}
// Vendor → vendor console
if (scopes.has('platform:admin')) {
return <Navigate to="/vendor/tenants" replace />;