feat(admin): add admin dashboard with auth spoofed#335
Conversation
- Add admin dashboard with shadcn sidebar layout - Implement mock auth with MOCK_USER_ID and @superset.sh domain validation - Add proxy.ts for Next.js 16 middleware with auth check - Create protectedProcedure (session check) and adminProcedure (domain validation) in tRPC - Add COMPANY constants in @superset/shared - Bump all apps to Next.js 16.0.10 and React 19.2.3 - Move reactCompiler from experimental to top-level config - Fix globals.css with proper shadcn oklch colors - Update desktop app to use own theme system 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
WalkthroughAdds an admin dashboard surface (sidebar components and layout), client and server auth utilities, route-protecting middleware, TRPC context and procedure changes (including an adminProcedure), shared COMPANY constant, CSS theming updates, and multiple dependency/Next.js config bumps across the monorepo. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant Browser as Client (Browser)
participant Proxy as Admin Middleware (proxy.ts)
participant TRPCCtx as TRPC Context/Server
participant DB as Database
participant Layout as DashboardLayout
participant UI as AppSidebar/NavUser
Browser->>Proxy: Request /admin/*
Proxy->>Proxy: isPublicRoute? (whitelist)
alt public
Proxy-->>Browser: pass-through response
else protected
Proxy->>TRPCCtx: build context (headers) / create caller
TRPCCtx->>DB: caller.user.me()
DB-->>TRPCCtx: user|null
TRPCCtx-->>Proxy: mapped User|null
alt user exists
Proxy->>Proxy: verify COMPANY.emailDomain
alt allowed
Proxy-->>Layout: render dashboard (server)
Layout->>UI: render AppSidebar with user prop (client)
UI-->>Browser: rendered sidebar & NavUser
else denied
Proxy-->>Browser: redirect to web URL
end
else no user
Proxy-->>Browser: redirect to web URL
end
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes
Possibly related PRs
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
packages/trpc/src/router/organization.ts (1)
59-73: Switch todbWsto enable transactional safety, or add explicit error handling withonConflictDoNothing.The org creation and member insert are two separate queries with no rollback capability using the current
neon-httpdriver. If the member insert fails, the organization is left without a creator. Either:
- Use
dbWsinstead to enable.transaction()wrapping both operations, or- Add
.onConflictDoNothing()on the member insert and explicit error handling if needed.apps/desktop/package.json (1)
122-122: Missingtw-animate-cssdependency causes CI failure.The CSS file
apps/desktop/src/renderer/globals.cssimportstw-animate-css, but onlytailwindcss-animateis listed here. Either addtw-animate-cssas a dependency or update the CSS import to usetailwindcss-animate."tailwindcss": "^4.0.9", - "tailwindcss-animate": "^1.0.7", + "tailwindcss-animate": "^1.0.7", + "tw-animate-css": "^1.0.0",
🧹 Nitpick comments (7)
apps/admin/src/lib/auth/server.ts (1)
16-33: Avoid fully silent failure here (optional).
A blanketcatch { return null }makes genuine outages indistinguishable from “not signed in”. Consider at least logging a redacted error (no email/userId) or narrowing catches to expected auth errors.apps/admin/src/app/(dashboard)/page.tsx (1)
1-3: Returningnullis fine as a stub, but consider a minimal placeholder.
Even a small “Select an item from the sidebar” reduces “blank page” confusion.apps/admin/src/app/(dashboard)/components/AppSidebar/components/AppSidebarHeader/AppSidebarHeader.tsx (1)
13-25: Consider using Next.js Link for client-side navigation.The anchor tag works but bypasses Next.js client-side routing, causing a full page reload on navigation. Using
next/linkwould provide a better user experience with instant transitions.Apply this diff:
+import Link from "next/link"; import { SidebarMenu, SidebarMenuButton, SidebarMenuItem, } from "@superset/ui/sidebar"; import Image from "next/image"; export function AppSidebarHeader() { return ( <SidebarMenu> <SidebarMenuItem> <SidebarMenuButton size="lg" asChild> - <a href="/"> + <Link href="/"> <Image src="/icon.png" alt="Superset" width={32} height={32} className="size-8 rounded-lg" /> <div className="flex flex-col gap-0.5 leading-none"> <span className="font-medium">Superset</span> <span className="">Admin Panel</span> </div> - </a> + </Link> </SidebarMenuButton> </SidebarMenuItem> </SidebarMenu> ); }apps/admin/src/app/(dashboard)/components/AppSidebar/components/NavUser/NavUser.tsx (1)
26-26: Use barrel export for consistency.Import from the index barrel (
@/lib/auth) instead of the direct client module for consistency with the established export pattern.Apply this diff:
-import { useSignOut } from "@/lib/auth/client"; +import { useSignOut } from "@/lib/auth";apps/admin/src/app/(dashboard)/components/AppSidebar/AppSidebar.tsx (1)
154-163: Use Next.js Link for navigation items.Similar to AppSidebarHeader, these anchor tags bypass client-side routing. Using Link components would provide instant navigation without full page reloads throughout the sidebar.
Apply this diff:
+import Link from "next/link"; import { Collapsible, CollapsibleContent, CollapsibleTrigger, } from "@superset/ui/collapsible"; // ... other imports <SidebarMenu> {section.items.map((item) => ( <SidebarMenuItem key={item.title}> <SidebarMenuButton asChild> - <a href={item.url}> + <Link href={item.url}> {item.icon && <item.icon className="size-4" />} {item.title} - </a> + </Link> </SidebarMenuButton> </SidebarMenuItem> ))} </SidebarMenu>apps/admin/src/lib/auth/client.tsx (1)
67-73: Use validated env object for consistency.The code accesses
process.env.NEXT_PUBLIC_WEB_URLdirectly, bypassing the validated env configuration. Using the env helper provides type safety and runtime validation.Apply this diff:
"use client"; +import { env } from "@/env"; import { createContext, type ReactNode, useCallback, useContext, useMemo, } from "react"; import type { AuthState, User } from "./types"; // ... rest of file export function useSignOut() { const signOut = useCallback(() => { // Mock: redirect to web app - window.location.href = process.env.NEXT_PUBLIC_WEB_URL || "/"; + window.location.href = env.NEXT_PUBLIC_WEB_URL; }, []); return { signOut }; }Note: Ensure the env object is accessible in client components by importing from a client-safe module or mark relevant env vars for client access.
packages/trpc/src/trpc.ts (1)
77-80: Consider caching user data for performance.The DB query runs on every admin API call. For high-traffic admin endpoints, consider caching user data in the session/JWT or using a short-lived in-memory cache to reduce DB load.
This is acceptable for now, but as the admin panel scales, you may want to:
- Store user email/domain in the session payload
- Use a Redis cache with TTL
- Implement a request-scoped cache
Not blocking, but worth considering for future optimization.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (4)
apps/admin/public/favicon.icois excluded by!**/*.icoapps/admin/public/icon.pngis excluded by!**/*.pngapps/admin/src/app/favicon.icois excluded by!**/*.icobun.lockis excluded by!**/*.lock
📒 Files selected for processing (42)
apps/admin/next-env.d.ts(1 hunks)apps/admin/next.config.ts(1 hunks)apps/admin/package.json(2 hunks)apps/admin/src/app/(dashboard)/components/AppSidebar/AppSidebar.tsx(1 hunks)apps/admin/src/app/(dashboard)/components/AppSidebar/components/AppSidebarHeader/AppSidebarHeader.tsx(1 hunks)apps/admin/src/app/(dashboard)/components/AppSidebar/components/AppSidebarHeader/index.ts(1 hunks)apps/admin/src/app/(dashboard)/components/AppSidebar/components/NavUser/NavUser.tsx(1 hunks)apps/admin/src/app/(dashboard)/components/AppSidebar/components/NavUser/index.ts(1 hunks)apps/admin/src/app/(dashboard)/components/AppSidebar/components/SearchForm/SearchForm.tsx(1 hunks)apps/admin/src/app/(dashboard)/components/AppSidebar/components/SearchForm/index.ts(1 hunks)apps/admin/src/app/(dashboard)/components/AppSidebar/index.ts(1 hunks)apps/admin/src/app/(dashboard)/layout.tsx(1 hunks)apps/admin/src/app/(dashboard)/page.tsx(1 hunks)apps/admin/src/app/page.tsx(0 hunks)apps/admin/src/env.ts(1 hunks)apps/admin/src/lib/auth/client.tsx(1 hunks)apps/admin/src/lib/auth/index.ts(1 hunks)apps/admin/src/lib/auth/server.ts(1 hunks)apps/admin/src/lib/auth/types.ts(1 hunks)apps/admin/src/proxy.ts(1 hunks)apps/api/next-env.d.ts(1 hunks)apps/api/next.config.ts(1 hunks)apps/api/package.json(1 hunks)apps/cli/package.json(1 hunks)apps/desktop/package.json(2 hunks)apps/desktop/src/renderer/globals.css(2 hunks)apps/docs/package.json(1 hunks)apps/marketing/next.config.ts(1 hunks)apps/marketing/package.json(2 hunks)apps/web/next.config.ts(1 hunks)apps/web/package.json(2 hunks)packages/queries/package.json(1 hunks)packages/shared/src/constants.ts(1 hunks)packages/trpc/package.json(1 hunks)packages/trpc/src/env.ts(1 hunks)packages/trpc/src/index.ts(1 hunks)packages/trpc/src/router/organization.ts(1 hunks)packages/trpc/src/router/task.ts(1 hunks)packages/trpc/src/router/user.ts(1 hunks)packages/trpc/src/trpc.ts(4 hunks)packages/ui/package.json(1 hunks)packages/ui/src/globals.css(2 hunks)
💤 Files with no reviewable changes (1)
- apps/admin/src/app/page.tsx
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx,js,jsx,json}
📄 CodeRabbit inference engine (AGENTS.md)
Use Biome for code formatting and linting, running at root level for speed
Files:
apps/admin/src/app/(dashboard)/page.tsxapps/admin/src/app/(dashboard)/components/AppSidebar/AppSidebar.tsxapps/admin/src/lib/auth/types.tspackages/trpc/src/index.tsapps/admin/src/app/(dashboard)/components/AppSidebar/components/NavUser/NavUser.tsxapps/admin/src/app/(dashboard)/components/AppSidebar/components/AppSidebarHeader/index.tsapps/web/next.config.tsapps/admin/src/app/(dashboard)/components/AppSidebar/components/SearchForm/index.tsapps/admin/src/lib/auth/server.tsapps/admin/src/lib/auth/index.tsapps/admin/src/env.tsapps/api/next-env.d.tspackages/ui/package.jsonapps/docs/package.jsonpackages/trpc/package.jsonpackages/trpc/src/router/user.tsapps/admin/src/proxy.tspackages/trpc/src/router/organization.tsapps/admin/src/app/(dashboard)/components/AppSidebar/components/AppSidebarHeader/AppSidebarHeader.tsxapps/admin/next-env.d.tsapps/web/package.jsonapps/marketing/package.jsonpackages/trpc/src/env.tsapps/admin/src/app/(dashboard)/layout.tsxapps/admin/src/app/(dashboard)/components/AppSidebar/components/SearchForm/SearchForm.tsxapps/admin/src/lib/auth/client.tsxapps/admin/src/app/(dashboard)/components/AppSidebar/index.tspackages/trpc/src/router/task.tsapps/api/next.config.tspackages/queries/package.jsonapps/admin/src/app/(dashboard)/components/AppSidebar/components/NavUser/index.tspackages/shared/src/constants.tspackages/trpc/src/trpc.tsapps/api/package.jsonapps/cli/package.jsonapps/admin/next.config.tsapps/desktop/package.jsonapps/marketing/next.config.tsapps/admin/package.json
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Avoid
anytype and prioritize type safety in TypeScript code
Files:
apps/admin/src/app/(dashboard)/page.tsxapps/admin/src/app/(dashboard)/components/AppSidebar/AppSidebar.tsxapps/admin/src/lib/auth/types.tspackages/trpc/src/index.tsapps/admin/src/app/(dashboard)/components/AppSidebar/components/NavUser/NavUser.tsxapps/admin/src/app/(dashboard)/components/AppSidebar/components/AppSidebarHeader/index.tsapps/web/next.config.tsapps/admin/src/app/(dashboard)/components/AppSidebar/components/SearchForm/index.tsapps/admin/src/lib/auth/server.tsapps/admin/src/lib/auth/index.tsapps/admin/src/env.tsapps/api/next-env.d.tspackages/trpc/src/router/user.tsapps/admin/src/proxy.tspackages/trpc/src/router/organization.tsapps/admin/src/app/(dashboard)/components/AppSidebar/components/AppSidebarHeader/AppSidebarHeader.tsxapps/admin/next-env.d.tspackages/trpc/src/env.tsapps/admin/src/app/(dashboard)/layout.tsxapps/admin/src/app/(dashboard)/components/AppSidebar/components/SearchForm/SearchForm.tsxapps/admin/src/lib/auth/client.tsxapps/admin/src/app/(dashboard)/components/AppSidebar/index.tspackages/trpc/src/router/task.tsapps/api/next.config.tsapps/admin/src/app/(dashboard)/components/AppSidebar/components/NavUser/index.tspackages/shared/src/constants.tspackages/trpc/src/trpc.tsapps/admin/next.config.tsapps/marketing/next.config.ts
**/components/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/components/**/*.{ts,tsx}: Structure project folders as one folder per component with PascalCase naming (ComponentName/ComponentName.tsx + index.ts barrel export)
Co-locate component dependencies (utils, hooks, constants, config, tests, stories) next to the file using them
Use one component per file (no multi-component files)
Files:
apps/admin/src/app/(dashboard)/components/AppSidebar/AppSidebar.tsxapps/admin/src/app/(dashboard)/components/AppSidebar/components/NavUser/NavUser.tsxapps/admin/src/app/(dashboard)/components/AppSidebar/components/AppSidebarHeader/index.tsapps/admin/src/app/(dashboard)/components/AppSidebar/components/SearchForm/index.tsapps/admin/src/app/(dashboard)/components/AppSidebar/components/AppSidebarHeader/AppSidebarHeader.tsxapps/admin/src/app/(dashboard)/components/AppSidebar/components/SearchForm/SearchForm.tsxapps/admin/src/app/(dashboard)/components/AppSidebar/index.tsapps/admin/src/app/(dashboard)/components/AppSidebar/components/NavUser/index.ts
🧠 Learnings (10)
📚 Learning: 2025-12-12T05:45:09.672Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-12T05:45:09.672Z
Learning: Applies to packages/ui/**/*.{ts,tsx} : Use React + TailwindCSS v4 + shadcn/ui for UI components in `packages/ui`
Applied to files:
apps/admin/src/app/(dashboard)/components/AppSidebar/AppSidebar.tsxpackages/ui/package.jsonapps/docs/package.jsonapps/web/package.jsonapps/marketing/package.jsonapps/desktop/src/renderer/globals.csspackages/queries/package.jsonapps/api/package.jsonapps/cli/package.jsonapps/desktop/package.jsonapps/admin/package.json
📚 Learning: 2025-12-12T05:45:09.672Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-12T05:45:09.672Z
Learning: Applies to **/components/**/*.{ts,tsx} : Structure project folders as one folder per component with PascalCase naming (ComponentName/ComponentName.tsx + index.ts barrel export)
Applied to files:
apps/admin/src/app/(dashboard)/components/AppSidebar/components/AppSidebarHeader/index.ts
📚 Learning: 2025-12-12T05:45:09.672Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-12T05:45:09.672Z
Learning: Applies to **/components/**/*.{ts,tsx} : Co-locate component dependencies (utils, hooks, constants, config, tests, stories) next to the file using them
Applied to files:
apps/web/next.config.tsapps/api/next-env.d.tsapps/admin/next-env.d.ts
📚 Learning: 2025-12-12T05:45:09.673Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-12T05:45:09.673Z
Learning: Applies to **/tsconfig.json : Use TypeScript config from packages/typescript-config for all workspaces
Applied to files:
apps/web/next.config.tsapps/admin/next.config.ts
📚 Learning: 2025-11-24T21:33:13.267Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: apps/desktop/AGENTS.md:0-0
Timestamp: 2025-11-24T21:33:13.267Z
Learning: Applies to apps/desktop/**/*.{ts,tsx} : Please use alias as defined in `tsconfig.json` when possible
Applied to files:
apps/api/next-env.d.tsapps/admin/next-env.d.ts
📚 Learning: 2025-12-12T05:45:09.672Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-12T05:45:09.672Z
Learning: Applies to apps/desktop/src/renderer/**/*.{ts,tsx,js,jsx} apps/desktop/src/lib/**/*.{ts,tsx,js,jsx} apps/desktop/src/shared/**/*.{ts,tsx,js,tsx} : Never import Node.js modules in renderer process or shared code, only in main process
Applied to files:
apps/admin/next-env.d.tsapps/desktop/src/renderer/globals.css
📚 Learning: 2025-12-12T05:45:09.673Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-12T05:45:09.673Z
Learning: Applies to apps/desktop/src/main/index.ts : Load environment variables in apps/desktop/src/main/index.ts with override: true before any imports
Applied to files:
apps/admin/next-env.d.ts
📚 Learning: 2025-12-12T05:45:09.672Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-12T05:45:09.672Z
Learning: Applies to **/*.{ts,tsx} : Avoid `any` type and prioritize type safety in TypeScript code
Applied to files:
apps/admin/next-env.d.ts
📚 Learning: 2025-11-24T21:33:13.267Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: apps/desktop/AGENTS.md:0-0
Timestamp: 2025-11-24T21:33:13.267Z
Learning: Applies to apps/desktop/**/*.{ts,tsx,js,jsx} : For Electron interprocess communication, ALWAYS use tRPC as defined in `src/lib/trpc`
Applied to files:
packages/trpc/src/trpc.ts
📚 Learning: 2025-12-12T05:45:09.672Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-12T05:45:09.672Z
Learning: Applies to packages/db/src/**/*.{ts,tsx} : Use Drizzle ORM for all database operations in the `packages/db` package
Applied to files:
packages/trpc/src/trpc.ts
🧬 Code graph analysis (5)
apps/admin/src/lib/auth/types.ts (1)
apps/admin/src/lib/auth/index.ts (2)
User(5-5)AuthState(5-5)
apps/admin/src/app/(dashboard)/components/AppSidebar/components/NavUser/NavUser.tsx (6)
apps/admin/src/lib/auth/index.ts (2)
User(5-5)useSignOut(4-4)apps/admin/src/lib/auth/types.ts (1)
User(1-6)packages/ui/src/components/ui/sidebar.tsx (3)
useSidebar(726-726)SidebarMenu(713-713)SidebarMenuButton(716-716)apps/admin/src/lib/auth/client.tsx (1)
useSignOut(67-74)packages/ui/src/components/ui/dropdown-menu.tsx (7)
DropdownMenu(249-249)DropdownMenuTrigger(251-251)DropdownMenuContent(252-252)DropdownMenuLabel(254-254)DropdownMenuSeparator(259-259)DropdownMenuGroup(253-253)DropdownMenuItem(255-255)packages/ui/src/components/ui/avatar.tsx (3)
Avatar(53-53)AvatarImage(53-53)AvatarFallback(53-53)
packages/trpc/src/router/organization.ts (1)
packages/db/src/schema/schema.ts (1)
organizationMembers(54-74)
apps/admin/src/app/(dashboard)/components/AppSidebar/components/AppSidebarHeader/AppSidebarHeader.tsx (2)
apps/admin/src/app/(dashboard)/components/AppSidebar/components/AppSidebarHeader/index.ts (1)
AppSidebarHeader(1-1)packages/ui/src/components/ui/sidebar.tsx (3)
SidebarMenu(713-713)SidebarMenuItem(717-717)SidebarMenuButton(716-716)
apps/admin/src/app/(dashboard)/layout.tsx (6)
apps/admin/src/lib/auth/server.ts (1)
currentUser(16-33)apps/admin/src/env.ts (1)
env(5-34)packages/ui/src/components/ui/sidebar.tsx (3)
SidebarProvider(722-722)SidebarInset(712-712)SidebarTrigger(725-725)apps/admin/src/app/(dashboard)/components/AppSidebar/AppSidebar.tsx (1)
AppSidebar(126-177)packages/ui/src/components/ui/separator.tsx (1)
Separator(28-28)packages/ui/src/components/ui/breadcrumb.tsx (6)
Breadcrumb(103-103)BreadcrumbList(104-104)BreadcrumbItem(105-105)BreadcrumbLink(106-106)BreadcrumbSeparator(108-108)BreadcrumbPage(107-107)
🪛 GitHub Actions: CI
apps/desktop/src/renderer/globals.css
[error] 1-1: Can't resolve 'tw-animate-css' in '/home/runner/work/superset/superset/apps/desktop/src/renderer'.
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: Deploy Docs
- GitHub Check: Deploy Admin
- GitHub Check: Deploy Marketing
- GitHub Check: Deploy API
- GitHub Check: Deploy Web
🔇 Additional comments (41)
packages/trpc/package.json (1)
18-18: LGTM!The addition of
@superset/sharedworkspace dependency correctly supports the admin authentication feature by providing access to COMPANY constants used for domain validation.apps/admin/src/env.ts (1)
17-18: LGTM!The optional
MOCK_USER_IDenvironment variable is correctly configured with UUID validation and clear documentation. The optional nature appropriately defaults to unauthenticated state when omitted.packages/trpc/src/env.ts (1)
6-6: LGTM!Making
MOCK_USER_IDoptional aligns with the admin app's environment configuration and correctly enables flexible authentication behavior for development and testing.apps/admin/src/app/(dashboard)/components/AppSidebar/components/SearchForm/SearchForm.tsx (1)
11-24: Verify that this is an intentional UI placeholder.The search form renders a visual input but has no submit handler, value state, or onChange logic. Ensure this is intentional placeholder UI and consider adding a TODO comment if search functionality is planned for a future iteration.
apps/admin/src/app/(dashboard)/components/AppSidebar/components/NavUser/index.ts (1)
1-1: LGTM!The barrel export follows the project's component structure guidelines with proper PascalCase naming and index.ts re-export pattern.
Based on learnings, this aligns with the established convention for component organization.
apps/admin/src/app/(dashboard)/components/AppSidebar/components/AppSidebarHeader/index.ts (1)
1-1: LGTM!The barrel export follows the project's component structure guidelines with proper PascalCase naming and index.ts re-export pattern.
Based on learnings, this aligns with the established convention for component organization.
apps/admin/src/app/(dashboard)/components/AppSidebar/components/SearchForm/index.ts (1)
1-1: LGTM!The barrel export follows the project's component structure guidelines with proper PascalCase naming and index.ts re-export pattern.
Based on learnings, this aligns with the established convention for component organization.
packages/trpc/src/router/user.ts (1)
9-13:protectedProcedureguaranteesuserIdis defined and safe to use.The middleware at lines 57-71 explicitly validates that
ctx.session?.userIdexists and throwsUNAUTHORIZEDif missing (line 58-64). Only after this guard passes does the code proceed withctx.sessionguaranteed to contain a non-nullable stringuserId. The type system reinforces this:TRPCContextdefinessession: { userId: string } | null, and the middleware ensures the session object always hasuserIdwhen control flow continues. The refactored code at line 79 inadminProcedure(also usingctx.session.userIddirectly) confirms this pattern is already in use throughout the codebase.packages/trpc/src/router/task.ts (1)
61-83: Session shape alignment looks correct (creatorId: ctx.session.userId).
AssumingprotectedProcedureguaranteesctx.session.userIdis a valid UUID-ish string, this is the right update.packages/trpc/src/index.ts (1)
6-13: New public exportadminProcedure: verify API surface + downstream compatibility.
This is a breaking-ish change for consumers if there are symbol conflicts or barrel export assumptions; worth a quick downstream compile check.apps/admin/src/app/(dashboard)/components/AppSidebar/index.ts (1)
1-1: Good barrel export forAppSidebar.packages/shared/src/constants.ts (1)
1-6: CentralizingCOMPANYconstants is clean; keep email checks case-insensitive.
If domain enforcement doesendsWith(COMPANY.emailDomain), ensure the email is normalized (e.g.,toLowerCase()) before comparison.apps/admin/src/lib/auth/types.ts (1)
1-12: Auth types look good and stay type-safe (noany).apps/admin/src/lib/auth/server.ts (1)
16-33: The emptyHeaders()object passed tocreateTRPCContextdoesn't actually prevent authentication.getServerSession(auth)doesn't use the headers parameter—it auto-detects the session from the implicit request context available to async Server Components. The headers stored in the context object are not used by the TRPC router or user endpoint. While the headers parameter is unnecessary and could be removed for clarity, this is not a functional authentication issue.Likely an incorrect or invalid review comment.
apps/admin/src/lib/auth/index.ts (1)
1-8: LGTM! Clean separation of client and server exports.The barrel export correctly re-exports only client-safe utilities and types, while explicitly documenting that server utilities must be imported directly. This follows Next.js App Router best practices and prevents server code from being bundled into the client.
apps/admin/src/app/(dashboard)/layout.tsx (2)
22-32: LGTM! Proper server-side authentication check.The layout correctly fetches the current user server-side and redirects unauthorized users before rendering any admin content. This follows Next.js 15 App Router patterns for protected routes.
34-56: Well-structured dashboard layout.Clean composition using SidebarProvider, AppSidebar, and SidebarInset with proper breadcrumb navigation. The layout provides a consistent shell for admin pages.
apps/admin/src/proxy.ts (2)
24-50: LGTM! Solid authentication middleware.The proxy correctly:
- Bypasses public routes
- Validates user authentication via tRPC
- Enforces domain-based access control
- Handles errors gracefully with redirects
This provides a good defense-in-depth layer before the API's adminProcedure validation.
52-57: Verify matcher pattern excludes static assets correctly.The matcher pattern is comprehensive but complex. Ensure it properly excludes Next.js internals and static assets while catching all routes that need auth.
Test the middleware with various URL patterns:
- Static assets:
/icon.png,/favicon.ico- Next.js internals:
/_next/static/...- API routes:
/api/...,/trpc/...- Dashboard routes:
/,/users,/analyticsThe current pattern should work correctly, but it's worth validating in development that static assets load without auth checks.
packages/trpc/src/trpc.ts (3)
57-71: LGTM! Clean session validation in protectedProcedure.The lightweight session check is appropriate for procedures that don't need full user data. Good separation of concerns.
73-101: Solid admin authorization with defense-in-depth.The adminProcedure correctly:
- Extends protectedProcedure (session check)
- Fetches user from DB for freshness
- Validates domain access with clear error messages
This provides proper authorization beyond the proxy layer.
14-31: Breaking change is complete and properly propagated across the codebase.The session structure has been successfully updated from
{ user: { id } }to{ userId }throughout the tRPC context and all consuming code. All references in packages/trpc/src/router/*.ts and packages/trpc/src/trpc.ts correctly usectx.session.userId.packages/ui/package.json (1)
78-79: LGTM! Properly coordinated React version update.The devDependencies and peerDependencies for React are correctly aligned at version 19.2.3, ensuring consuming apps use compatible versions.
Also applies to: 84-84
apps/admin/next.config.ts (1)
4-4: LGTM! Correct reactCompiler configuration for Next.js 16.Moving
reactCompilerfromexperimental.reactCompilerto a top-level property aligns with Next.js 15+ configuration requirements, as documented in the Next.js 15 upgrade guide.apps/web/next.config.ts (1)
4-4: LGTM! Correct reactCompiler configuration for Next.js 16.Moving
reactCompilerto a top-level property is the correct configuration format for Next.js 15+ and aligns with the same change in apps/admin/next.config.ts.apps/web/package.json (1)
27-30: The Next.js 16 upgrade appears compatible with the existing app code.No deprecated patterns were detected: the app uses the modern App Router (with layout.tsx), no legacy Pages Router API routes, no middleware patterns that changed between versions, and next.config.ts uses only stable features (reactCompiler). The React 19.2.3 upgrade is also compatible with the current setup.
apps/admin/package.json (1)
27-30: No Next.js 16 compatibility action needed for the admin app.The upgrade to Next.js 16.0.10 and React 19.2.3 is compatible with the admin app's current implementation. The auth flows use standard tRPC patterns with server/client components that are fully compatible with Next.js 16. The proxy.ts function, while defined with correct NextRequest/NextResponse APIs, is currently unused—it appears to be placeholder code for future Clerk integration (as noted in the source comment). The layout.tsx and auth implementations follow Next.js 16 conventions without requiring changes.
apps/marketing/package.json (1)
21-24: framer-motion and @react-three/fiber are compatible with React 19.2.3.framer-motion 12.23.24 declares React 18 and React 19 in its peerDependencies, and @react-three/fiber 9.4.0 is the React 19 release line. Note that @react-three/fiber v9 contains breaking changes around StrictMode handling; verify these changes don't affect the marketing app's 3D components during testing.
apps/cli/package.json (1)
36-36: LGTM! Coordinated React upgrade across the monorepo.The React and React types version bumps align with the monorepo-wide upgrade to React 19.2.3. Ink 6.5.0 requires React >=19.0.0, so the updated versions are fully compatible.
Also applies to: 42-42
apps/desktop/src/renderer/globals.css (2)
5-5: LGTM!The
@sourcepath addition correctly includes the shared UI package so Tailwind can detect and generate styles for classes used inpackages/ui.
133-136: LGTM!Simplifying the base styles by removing
outline-ring/50and keepingborder-border antialiasedis a reasonable change that aligns with the theme token updates.apps/marketing/next.config.ts (1)
3-7: LGTM!Moving
reactCompilerfromexperimentalto a top-level property aligns with Next.js 16 where the React Compiler is no longer experimental. This change is consistent across all app configs in this PR.packages/queries/package.json (1)
21-27: LGTM!React and type definition updates are consistent between
devDependenciesandpeerDependencies, aligning with the monorepo-wide upgrade to React 19.2.3.apps/desktop/package.json (1)
77-81: LGTM on the React version bumps.The React and React-DOM updates to 19.2.3 with matching type definitions are consistent with the monorepo-wide upgrade.
Also applies to: 106-107
apps/api/next.config.ts (1)
11-13: LGTM!Moving
reactCompilerto the top level is consistent with Next.js 16 where the React Compiler is stable. The CORS configuration remains unchanged.apps/admin/next-env.d.ts (1)
3-3: No action needed. This file is auto-generated by Next.js and should not be committed. The.next/dev/types/routes.d.tspath and import statement are correct for Next.js 16. Runnext buildornext typegento regenerate this file, and add.next/to.gitignoreif not already present.Likely an incorrect or invalid review comment.
packages/ui/src/globals.css (3)
44-111: OKLCH color values and dark mode mappings look well-structured.All color tokens defined in :root (light mode) and .dark (dark mode) are properly cross-referenced in the @theme block. The OKLCH values follow a consistent pattern: grayscale tokens use 0 saturation (lines 45–47, 49–51, etc.), while accent colors leverage full saturation and hue angles (e.g., destructive, chart, and sidebar-primary). Dark mode opacity syntax (e.g.,
oklch(1 0 0 / 10%)) aligns with Tailwind v4 semantics.
115-115: Verify thatborder-borderutility is available in the current Tailwind v4 setup.The change from
@apply outline-ring/50to@apply border-borderassumes theborder-borderutility exists. Given the updated theme tokens, confirm that theborder-colorutility correctly resolves to the--color-borderCSS variable.
6-42: Implementation correctly uses Tailwind v4 CSS-first syntax; no validation needed.The
@custom-variantat line 4 and@theme inlineblock are both valid, well-documented Tailwind v4 features. The@theme inlineapproach is the correct choice here since the theme variables reference other CSS variables (e.g.,var(--radius),var(--background)), which avoids double-indirection and unresolved fallback behavior. The semantic token mapping is sound and enables consistent theming across light and dark modes.apps/api/package.json (2)
28-29: Verify type definitions match runtime versions.The @types/react (19.2.7) and @types/react-dom (19.2.3) versions align with the runtime versions (19.2.3). Confirm that these type versions are compatible with Next.js 16.0.10's internal type expectations and that no type conflicts arise during the build/typecheck step.
20-23: No action required — Next.js 16.0.10 is stable and proxy.ts is already correctly migrated.Next.js 16.0.10 is a stable LTS patch (published Dec 11, 2025) and is available on npm. The breaking changes from Next.js 15→16 (middleware→proxy migration, async request APIs) are already reflected in apps/admin/src/proxy.ts, which correctly exports
async function proxy(request: NextRequest)and awaits dynamic APIs. React 19.2.3 is explicitly supported with Next.js 16. The package versions are compatible.
| const userInitials = user.name | ||
| .split(" ") | ||
| .map((name) => name[0]) | ||
| .join(""); |
There was a problem hiding this comment.
Handle edge cases in userInitials calculation.
The current implementation could throw if user.name contains empty strings after splitting (e.g., "John Doe" with double space) or if name is empty.
Apply this diff to add defensive handling:
const userInitials = user.name
+ .trim()
.split(" ")
+ .filter((name) => name.length > 0)
.map((name) => name[0])
+ .slice(0, 2)
.join("");This ensures:
- Trimmed whitespace
- Empty segments filtered out
- Maximum 2 initials (common UX pattern)
- No crash on edge case names
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const userInitials = user.name | |
| .split(" ") | |
| .map((name) => name[0]) | |
| .join(""); | |
| const userInitials = user.name | |
| .trim() | |
| .split(" ") | |
| .filter((name) => name.length > 0) | |
| .map((name) => name[0]) | |
| .slice(0, 2) | |
| .join(""); |
🤖 Prompt for AI Agents
In
apps/admin/src/app/(dashboard)/components/AppSidebar/components/NavUser/NavUser.tsx
around lines 37 to 40, the userInitials computation must be made defensive: trim
the full name, split on whitespace, filter out any empty segments, map to the
first character of each non-empty segment, take at most the first two initials,
and join them; also handle an empty or missing name by returning an empty string
or a sensible fallback (e.g., "?") so the code cannot throw on edge-case names
like "" or "John Doe".
| export function useSignOut() { | ||
| const signOut = useCallback(() => { | ||
| // Mock: redirect to web app | ||
| window.location.href = process.env.NEXT_PUBLIC_WEB_URL || "/"; | ||
| }, []); | ||
|
|
||
| return { signOut }; |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Search for env.ts file in apps/admin
fd -n "env\.ts$" apps/admin/src/
# Check env.ts if it exists
if [ -f "apps/admin/src/env.ts" ]; then
echo "=== env.ts content ==="
cat -n apps/admin/src/env.ts
fi
# Also check if env.js exists
fd -n "env\.js$" apps/admin/src/Repository: superset-sh/superset
Length of output: 1711
🏁 Script executed:
#!/bin/bash
# Check TypeScript config for path aliases
if [ -f "apps/admin/tsconfig.json" ]; then
echo "=== apps/admin tsconfig.json ==="
cat apps/admin/tsconfig.json | jq '.compilerOptions.paths // empty' 2>/dev/null || cat apps/admin/tsconfig.json
fi
# Check for root tsconfig
if [ -f "tsconfig.json" ]; then
echo "=== root tsconfig.json paths ==="
cat tsconfig.json | jq '.compilerOptions.paths // empty' 2>/dev/null || grep -A5 '"paths"' tsconfig.json
fiRepository: superset-sh/superset
Length of output: 129
🏁 Script executed:
#!/bin/bash
# Check if @/env is used elsewhere in the codebase
rg -n "from ['\"]@/env['\"]" apps/admin/src/ | head -20
# Check what process.env vars are used
rg -n "process\.env\.NEXT_PUBLIC" apps/admin/src/ | head -20Repository: superset-sh/superset
Length of output: 402
Use env.NEXT_PUBLIC_WEB_URL from @/env instead of process.env.NEXT_PUBLIC_WEB_URL.
The apps/admin/src/env.ts is properly configured with @t3-oss/env-nextjs and exports NEXT_PUBLIC_WEB_URL in the client section with runtime validation via experimental__runtimeEnv. This provides type safety and validation. Import and use env from @/env (already configured as a path alias) for consistency with the rest of the codebase.
🤖 Prompt for AI Agents
In apps/admin/src/lib/auth/client.tsx around lines 67 to 73, the signOut
function reads NEXT_PUBLIC_WEB_URL directly from process.env; replace that with
the validated runtime env import by importing env from "@/env" and using
env.NEXT_PUBLIC_WEB_URL (fallback to "/" if undefined). Update the file to
import the env module at top, reference env.NEXT_PUBLIC_WEB_URL in the redirect,
and remove the direct process.env usage so the code uses the typed, validated
env value.
- Desktop: add tw-animate-css dependency (replaces tailwindcss-animate) - Docs: upgrade to Next.js 16 with nextra 4.6.1 - Docs: use webpack for build (Turbopack doesn't support nextra's MDX yet) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Move favicon.ico to src/app/ for all Next.js apps (app router convention) and remove from public folders. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Auto-generated by Next.js, should not be committed. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Summary
MOCK_USER_IDenvironment variable@superset.shemails only)proxy.tsfor Next.js 16 middleware with auth validationprotectedProcedure(session check) andadminProcedure(domain validation) in tRPCCOMPANYconstants in@superset/sharedreactCompilerfromexperimentalto top-level configglobals.csswith proper shadcn oklch color systemAuth Flow
Test Plan
MOCK_USER_IDto valid user with@superset.shemail → should access dashboardMOCK_USER_IDto user without@superset.shemail → should redirect to web appMOCK_USER_ID→ should redirect to web app🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Chores
✏️ Tip: You can customize this high-level summary in your review settings.