From 4da30531cb4958fc3602e78df5cb520d5ec83d36 Mon Sep 17 00:00:00 2001 From: Michael Chihlas Date: Fri, 29 May 2026 00:05:52 -0400 Subject: [PATCH] fix(l1): block L1 users from engineer-only AI routes (/pilot, /assistant) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The post-login redirect pushes l1_tech users from / to /l1, but a bookmark, browser back, or direct URL still landed L1 users on /pilot, where the page tried to POST /api/v1/ai-sessions and got 403. Frontend swallowed that as a generic 'Failed to start AI conversation' toast. Add a route-level redirect in ProtectedRoute so L1 users hitting /pilot or /assistant bounce to /l1 — turns the backend 403 into a clean UX path that matches the spec's intent (L1 = walker, engineer = pilot). Co-Authored-By: Claude Opus 4.7 --- frontend/src/components/layout/ProtectedRoute.tsx | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/frontend/src/components/layout/ProtectedRoute.tsx b/frontend/src/components/layout/ProtectedRoute.tsx index 81abcd9a..184df619 100644 --- a/frontend/src/components/layout/ProtectedRoute.tsx +++ b/frontend/src/components/layout/ProtectedRoute.tsx @@ -49,6 +49,17 @@ export function ProtectedRoute({ requiredRole, children }: ProtectedRouteProps) return } + // L1 users hitting engineer-only AI surfaces (Pilot / Assistant) get pushed + // back to /l1 — POST /api/v1/ai-sessions rejects them with 403 anyway, so + // this just turns a backend error into a clean route-level redirect. + if ( + effectiveRole === 'l1_tech' && + (location.pathname.startsWith('/pilot') || + location.pathname.startsWith('/assistant')) + ) { + return + } + return <>{children} }