Skip to content

Fix/remove otel deadlock#39

Merged
jeremylongshore merged 4 commits intomainfrom
fix/remove-otel-deadlock
Mar 6, 2026
Merged

Fix/remove otel deadlock#39
jeremylongshore merged 4 commits intomainfrom
fix/remove-otel-deadlock

Conversation

@opeyemiariyo-netizen
Copy link
Contributor

@opeyemiariyo-netizen opeyemiariyo-netizen commented Mar 6, 2026

Summary

Brief description of changes.

Changes Made

  • Change 1
  • Change 2

Testing

  • Tests pass locally
  • Manual testing completed

Risk Assessment

  • Low risk - minor change
  • Medium risk - new feature
  • High risk - breaking change

Rollback Plan

How to revert if needed.

Summary by CodeRabbit

  • New Features

    • Added "Back to Dashboard" navigation on multiple dashboard pages.
  • UI Improvements

    • Header title updated to "Hustle".
    • Sidebar collapse control moved to the right.
    • New sidebar color tokens for improved theming.
  • Authentication

    • Switched to a server-side session cookie flow with stricter session detection and longer server-side timeouts; client-side auth token fallback and client cookie manipulation removed.

opeyemiariyo-netizen and others added 2 commits March 6, 2026 11:52
Remove the firebase-auth-token fallback cookie that was never read by
middleware or auth.ts, causing a false sense of resilience. Remove the
AbortController timeout on the session POST that was aborting before the
server could respond on cold starts. Login now awaits the session POST
fully and surfaces clear error messages on failure.

- Remove firebase-auth-token cookie from login, logout, sidebar, user-nav
- Remove AbortController from login page session POST
- Remove onIdTokenChanged listener from ProtectedRoute
- Remove onIdTokenChange export from client auth module
- Revert middleware to only check __session cookie

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix transparent mobile sidebar by adding --sidebar CSS variable and
  Tailwind color mapping so bg-sidebar resolves correctly
- Add "← Back to Dashboard" link to athletes, analytics, settings,
  profile, and games pages (matching dream-gym style)
- Change header text from "Dashboard" to "Hustle"
- Move sidebar close button to right of HUSTLE logo

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

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

@coderabbitai
Copy link

coderabbitai bot commented Mar 6, 2026

📝 Walkthrough

Walkthrough

Removes client-side firebase-auth-token handling and onIdTokenChange usage, centralizes session to a server-set __session cookie, updates login/logout flows to rely on that cookie, adds a BackToDashboard component across dashboard pages, introduces sidebar theme tokens, and renames header title to "Hustle".

Changes

Cohort / File(s) Summary
Auth API & Middleware
src/app/api/auth/logout/route.ts, src/app/api/auth/set-session/route.ts, src/middleware.ts
Logout and middleware now rely solely on the __session cookie; set-session timeouts increased to 25s. Removed fallback/reading of firebase-auth-token.
Client Auth Utilities & Guards
src/lib/firebase/auth.ts, src/components/ProtectedRoute.tsx, src/components/layout/user-nav.tsx
Removed onIdTokenChange export/import and client-side ID-token cookie refresh/clearing logic; sign-out no longer manipulates firebase-auth-token.
Login Flow (client)
src/app/login/page.tsx
Client now posts ID token to /api/auth/set-session and requires server-set __session before navigation; removed client-side timeout/fallback and firebase-auth-token cookie logic; stricter error handling.
Logout & Sidebar UI
src/components/layout/app-sidebar-simple.tsx, src/components/layout/user-nav.tsx, src/app/api/auth/logout/route.ts
Removed client cookie clearing on sign-out; moved sidebar collapse control to right side of header; sign-out flow simplified to Firebase sign-out + server logout call.
Dashboard Navigation UI
src/components/ui/back-to-dashboard.tsx, src/app/dashboard/analytics/page.tsx, src/app/dashboard/athletes/page.tsx, src/app/dashboard/games/page.tsx, src/app/dashboard/profile/page.tsx, src/app/dashboard/settings/page.tsx
Added new BackToDashboard component and inserted it above headers across dashboard pages; some pages removed previous right-aligned back links.
Styling & Theme
src/app/globals.css, tailwind.config.ts
Added CSS variables --sidebar and --sidebar-foreground and Tailwind sidebar color tokens.
Header Text
src/components/layout/header.tsx
Updated header title text from "Dashboard" to "Hustle".

Sequence Diagram(s)

sequenceDiagram
    participant User as User (Client)
    participant LoginPage as Login Page (client)
    participant Firebase as Firebase Auth
    participant SetSessionAPI as /api/auth/set-session
    participant Server as App Server
    participant Middleware as Edge Middleware
    participant Dashboard as Dashboard (protected)

    User->>LoginPage: Submit credentials / start sign-in
    LoginPage->>Firebase: Sign in / request ID token
    Firebase-->>LoginPage: Return ID token
    LoginPage->>SetSessionAPI: POST ID token
    SetSessionAPI->>Server: Verify token, create __session cookie
    Server-->>LoginPage: 200 OK (sets __session cookie)
    LoginPage->>Dashboard: Navigate to /dashboard (browser sends __session)
    Dashboard->>Middleware: Incoming request with __session cookie
    Middleware->>Server: Verify __session
    Server-->>Middleware: Verification result
    Middleware-->>Dashboard: Allow or deny access
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

🐰 I hopped from token to cookie bright,

traded fiddly jars for server light.
Back-to-Dashboard I dash with cheer,
"Hustle" now greets the header near.
Cookies snug — I thump, sincere.

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Title check ⚠️ Warning The PR title 'Fix/remove otel deadlock' does not relate to the actual changes, which involve authentication cookie management, session handling, and UI navigation components. No OTEL (OpenTelemetry) changes are present in the changeset. Update the title to accurately reflect the main changes, such as 'Migrate to server-side session authentication with BackToDashboard navigation' or 'Replace firebase-auth-token with server-side __session cookie'.
Docstring Coverage ⚠️ Warning Docstring coverage is 41.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/remove-otel-deadlock

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@qodo-code-review
Copy link

Review Summary by Qodo

Remove OTEL deadlock and improve authentication flow with UI enhancements

🐞 Bug fix ✨ Enhancement

Grey Divider

Walkthroughs

Description
• Remove broken firebase-auth-token fallback cookie and AbortController timeout that caused
  deadlocks
  - Eliminates false sense of resilience from unread fallback cookie
  - Removes premature AbortController timeout on session POST
  - Login now awaits session POST fully with clear error messages
• Add sidebar CSS variables and Tailwind color mapping for mobile styling
• Add "Back to Dashboard" navigation links to sub-pages (athletes, analytics, settings, profile,
  games)
• Update header text from "Dashboard" to "Hustle" and reorganize sidebar close button
Diagram
flowchart LR
  A["Auth Flow"] -->|Remove| B["firebase-auth-token cookie"]
  A -->|Remove| C["AbortController timeout"]
  A -->|Simplify| D["Middleware checks __session only"]
  E["UI Improvements"] -->|Add| F["Sidebar CSS variables"]
  E -->|Add| G["Back to Dashboard links"]
  E -->|Update| H["Header text to Hustle"]
  E -->|Reorganize| I["Sidebar close button"]
Loading

Grey Divider

File Changes

1. src/app/api/auth/logout/route.ts 🐞 Bug fix +0/-1

Remove firebase-auth-token cookie from logout

src/app/api/auth/logout/route.ts


2. src/lib/firebase/auth.ts 🐞 Bug fix +0/-11

Remove onIdTokenChanged listener and export

src/lib/firebase/auth.ts


3. src/middleware.ts 🐞 Bug fix +1/-3

Simplify session cookie check to __session only

src/middleware.ts


View more (12)
4. src/app/login/page.tsx 🐞 Bug fix +10/-19

Remove AbortController timeout and fallback cookie logic

src/app/login/page.tsx


5. src/components/ProtectedRoute.tsx 🐞 Bug fix +1/-19

Remove onIdTokenChange listener and cookie refresh

src/components/ProtectedRoute.tsx


6. src/components/layout/app-sidebar-simple.tsx ✨ Enhancement +8/-11

Remove fallback cookie clearing and reorganize close button

src/components/layout/app-sidebar-simple.tsx


7. src/components/layout/user-nav.tsx 🐞 Bug fix +0/-3

Remove fallback cookie clearing from sign out

src/components/layout/user-nav.tsx


8. tailwind.config.ts ✨ Enhancement +4/-0

Add sidebar color configuration to Tailwind

tailwind.config.ts


9. src/app/globals.css ✨ Enhancement +2/-0

Add sidebar CSS custom properties

src/app/globals.css


10. src/app/dashboard/analytics/page.tsx ✨ Enhancement +10/-1

Add back to dashboard navigation link

src/app/dashboard/analytics/page.tsx


11. src/app/dashboard/athletes/page.tsx ✨ Enhancement +9/-1

Add back to dashboard navigation link

src/app/dashboard/athletes/page.tsx


12. src/app/dashboard/games/page.tsx ✨ Enhancement +14/-15

Add back to dashboard navigation link and refactor layout

src/app/dashboard/games/page.tsx


13. src/app/dashboard/profile/page.tsx ✨ Enhancement +10/-0

Add back to dashboard navigation link

src/app/dashboard/profile/page.tsx


14. src/app/dashboard/settings/page.tsx ✨ Enhancement +9/-1

Add back to dashboard navigation link

src/app/dashboard/settings/page.tsx


15. src/components/layout/header.tsx ✨ Enhancement +1/-1

Update header text from Dashboard to Hustle

src/components/layout/header.tsx


Grey Divider

Qodo Logo

@qodo-code-review
Copy link

qodo-code-review bot commented Mar 6, 2026

Code Review by Qodo

🐞 Bugs (3) 📘 Rule violations (1) 📎 Requirement gaps (0)

Grey Divider


Action required

1. Login can hang forever🐞 Bug ⛯ Reliability
Description
The login flow now awaits the session-cookie POST without any client-side timeout/abort; if the
request stalls (hung server, proxy, or network), the UI can remain in a loading state indefinitely.
This is a regression in recoverability for a critical user path (sign-in).
Code

src/app/login/page.tsx[R53-73]

+      // AWAIT the server-side session cookie POST — no timeout, let it complete
+      // This sets __session (14-day, httpOnly) — the ONLY auth mechanism.
+      // Must complete BEFORE router.push() to prevent browser aborting in-flight request.
+      // On cold starts this can take 10-20s while Firebase Admin initializes.
     console.log('[Login] Setting server session cookie...');
     try {
-        const controller = new AbortController();
-        const timeoutId = setTimeout(() => controller.abort(), 15000);
       const response = await fetch('/api/auth/set-session', {
         method: 'POST',
         headers: { 'Content-Type': 'application/json' },
         body: JSON.stringify({ idToken }),
         credentials: 'include',
-          signal: controller.signal,
       });
-        clearTimeout(timeoutId);
       if (!response.ok) {
-          console.error('[Login] Session cookie API error:', response.status);
-        } else {
-          console.log('[Login] Server session cookie set successfully');
+          const body = await response.json().catch(() => ({}));
+          throw new Error(body.error || `Server returned ${response.status}`);
       }
+        console.log('[Login] Server session cookie set successfully');
     } catch (sessionError: any) {
-        // POST timed out or failed — fallback cookie already set, user still gets in
-        console.warn('[Login] Server session cookie failed (non-fatal):', sessionError?.message);
+        console.error('[Login] Session cookie failed:', sessionError?.message);
+        throw new Error('Unable to establish session. Please try again.');
     }
Evidence
Login sets loading=true and then awaits fetch('/api/auth/set-session') without
AbortController/timeout; loading only clears in finally after the awaited call returns/throws, so a
stalled request can block the UI indefinitely.

src/app/login/page.tsx[37-104]
src/lib/utils/timeout.ts[8-18]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`/api/auth/set-session` is awaited during login without any client-side timeout. If the request stalls, the login page remains stuck in a loading state.
### Issue Context
The previous implementation had an AbortController-based timeout; this was removed. Even if we don’t want to abort “too early”, we still need an upper bound and a clean retry path.
### Fix Focus Areas
- src/app/login/page.tsx[53-73]
- src/lib/utils/timeout.ts[8-18]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Session setup times out at 10s🐞 Bug ✓ Correctness
Description
The PR makes __session the only auth mechanism (middleware no longer accepts fallback cookies), but
the set-session API still wraps verifyIdToken/createSessionCookie in 10s timeouts. The login page
even documents 10–20s cold starts; in those cases, logins can fail with 504/500 and there is no
fallback path anymore.
Code

src/middleware.ts[R71-73]

function getSessionCookie(request: NextRequest): string | null {
-  return request.cookies.get('__session')?.value
-    || request.cookies.get('firebase-auth-token')?.value
-    || null;
+  return request.cookies.get('__session')?.value || null;
}
Evidence
Middleware now only considers __session, so access depends entirely on the server-set cookie. The
login flow explicitly expects long cold starts, but the set-session route enforces 10s timeouts for
Firebase Admin operations, which can trigger 504 responses under cold-start conditions—turning
sign-in into a hard failure.

src/middleware.ts[68-73]
src/app/login/page.tsx[53-57]
src/app/api/auth/set-session/route.ts[39-69]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`__session` is now the sole mechanism for middleware auth, but `/api/auth/set-session` times out Firebase Admin operations at 10s despite documented 10–20s cold starts. This can cause systematic login failures.
### Issue Context
- Middleware only reads `__session` now.
- Login removed the fallback cookie and treats session setup as mandatory.
- The set-session handler uses `withTimeout(..., 10000, ...)` for verify/create.
### Fix Focus Areas
- src/app/api/auth/set-session/route.ts[39-69]
- src/app/login/page.tsx[53-73]
- src/middleware.ts[71-73]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

3. toggleSidebar button class order 📘 Rule violation ✓ Correctness
Description
The new className string mixes color utilities (bg-*) before layout utilities (rounded-*,
flex, items-*, justify-*), violating the required Tailwind ordering convention. This reduces
consistency and makes class lists harder to scan and maintain.
Code

src/components/layout/app-sidebar-simple.tsx[102]

+            className='w-8 h-8 bg-zinc-200 hover:bg-zinc-300 rounded-md flex items-center justify-center transition-colors'
Evidence
PR Compliance ID 10 requires Tailwind classes to be ordered/grouped as layout first, then color,
then state/interaction. The added button className places bg-zinc-200 (color) before `rounded-md
flex items-center justify-center` (layout) and mixes state utilities within the sequence.

AGENTS.md
src/components/layout/app-sidebar-simple.tsx[100-106]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The `className` on the sidebar collapse button does not follow the required Tailwind utility ordering (layout → color → state), which reduces consistency.
## Issue Context
The compliance checklist requires consistent ordering/grouping of Tailwind utilities for readability.
## Fix Focus Areas
- src/components/layout/app-sidebar-simple.tsx[100-106]ైర

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


4. Sidebar theme tokens missing 🐞 Bug ✓ Correctness
Description
Tailwind/globals only add sidebar and sidebar-foreground, but the sidebar component uses
additional semantic tokens (e.g., sidebar-border, sidebar-accent, sidebar-accent-foreground,
sidebar-ring). Those classes will not be generated by Tailwind and corresponding CSS vars aren’t
defined, leading to missing hover/focus/separator styling.
Code

tailwind.config.ts[R46-49]

+        sidebar: {
+          DEFAULT: "hsl(var(--sidebar))",
+          foreground: "hsl(var(--sidebar-foreground))",
+        },
Evidence
The sidebar UI relies on multiple sidebar-* color tokens. This PR only wires up 2 tokens in both CSS
variables and Tailwind theme, so the rest of the sidebar styling tokens have no backing theme
entries/vars and will render unstyled.

src/components/ui/sidebar.tsx[244-247]
src/components/ui/sidebar.tsx[281-296]
src/components/ui/sidebar.tsx[356-368]
src/components/ui/sidebar.tsx[395-429]
tailwind.config.ts[46-50]
src/app/globals.css[6-29]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The sidebar component uses Tailwind classes like `bg-sidebar-border`, `hover:bg-sidebar-accent`, and `ring-sidebar-ring`, but only `sidebar` and `sidebar-foreground` are defined in Tailwind config and CSS variables.
### Issue Context
This leads to missing CSS output for those classes and undefined CSS variables.
### Fix Focus Areas
- tailwind.config.ts[46-50]
- src/app/globals.css[6-29]
- src/components/ui/sidebar.tsx[244-247]
- src/components/ui/sidebar.tsx[356-368]
- src/components/ui/sidebar.tsx[395-429]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request primarily refines the application's authentication flow by deprecating the client-side 'firebase-auth-token' fallback cookie, ensuring that session management relies exclusively on the secure, server-side '__session' cookie. This change simplifies the authentication logic and enhances its robustness, particularly during the login process. Concurrently, the pull request introduces several user interface improvements across various dashboard sub-pages, such as adding "Back to Dashboard" navigation links and minor layout adjustments, to improve overall user experience. Note: The title "Fix/remove otel deadlock" does not align with the changes observed in the provided patch, which focus on authentication and UI enhancements.

Highlights

  • Streamlined Authentication: The client-side 'firebase-auth-token' fallback cookie has been entirely removed, making the '__session' server-side cookie the sole mechanism for session management. This simplifies both login and logout procedures.
  • Enhanced Login Robustness: The login process now directly awaits the server-side session cookie POST request without a timeout, ensuring the '__session' cookie is successfully established before redirection, with improved error handling for session failures.
  • Improved Dashboard Navigation: "Back to Dashboard" links with 'ArrowLeft' icons have been consistently added to Analytics, Athletes, Games, Profile, and Settings pages, enhancing user navigation.
  • UI Refinements: The sidebar header layout has been adjusted, including repositioning the collapse button, and new CSS variables ('--sidebar', '--sidebar-foreground') have been introduced for better styling control. The main header title was also updated from "Dashboard" to "Hustle".
Changelog
  • src/app/api/auth/logout/route.ts
    • Removed the 'firebase-auth-token' cookie from being cleared on logout.
  • src/app/dashboard/analytics/page.tsx
    • Added 'ArrowLeft' icon and 'Link' component imports.
    • Implemented a "Back to Dashboard" link at the top of the page.
  • src/app/dashboard/athletes/page.tsx
    • Added 'ArrowLeft' icon import.
    • Implemented a "Back to Dashboard" link at the top of the page.
  • src/app/dashboard/games/page.tsx
    • Replaced 'ChevronLeft' icon with 'ArrowLeft'.
    • Refactored the page header to move the "Back to Dashboard" link to the top of the content area.
  • src/app/dashboard/profile/page.tsx
    • Added 'Link' component and 'ArrowLeft' icon imports.
    • Implemented a "Back to Dashboard" link at the top of the page.
  • src/app/dashboard/settings/page.tsx
    • Added 'ArrowLeft' icon import.
    • Implemented a "Back to Dashboard" link at the top of the page.
  • src/app/globals.css
    • Defined new CSS custom properties '--sidebar' and '--sidebar-foreground'.
  • src/app/login/page.tsx
    • Removed client-side 'firebase-auth-token' cookie setting.
    • Removed timeout and 'AbortController' from server session cookie POST request.
    • Added more robust error handling for session cookie failure.
  • src/components/ProtectedRoute.tsx
    • Removed the import and usage of 'onIdTokenChange' and the associated 'useEffect' hook that refreshed the 'firebase-auth-token' cookie.
  • src/components/layout/app-sidebar-simple.tsx
    • Removed client-side 'firebase-auth-token' cookie clearing on logout.
    • Adjusted the layout of the sidebar header, specifically repositioning the collapse button.
  • src/components/layout/header.tsx
    • Changed the header title from "Dashboard" to "Hustle".
  • src/components/layout/user-nav.tsx
    • Removed client-side 'firebase-auth-token' cookie clearing on logout.
  • src/lib/firebase/auth.ts
    • Removed the 'onIdTokenChanged' import and the 'onIdTokenChange' export function.
  • src/middleware.ts
    • Removed the 'firebase-auth-token' fallback from 'getSessionCookie' function, relying solely on '__session'.
  • tailwind.config.ts
    • Extended Tailwind's theme colors to include 'sidebar' with 'DEFAULT' and 'foreground' variants.
Activity
  • The pull request description is a generic template and does not contain specific activity details like comments, reviews, or progress updates.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@github-actions
Copy link

github-actions bot commented Mar 6, 2026

Deployed to staging: https://hustle-app-staging-d4f2hb75nq-uc.a.run.app

@github-actions
Copy link

github-actions bot commented Mar 6, 2026

Smoke tests ✅ Passed

Target: https://hustle-app-staging-d4f2hb75nq-uc.a.run.app

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request refactors the authentication flow by removing the firebase-auth-token fallback cookie and relying solely on the __session cookie. This simplification is a positive change that likely resolves the deadlock issue mentioned in the title by creating a single source of truth for authentication state. The changes are applied consistently across login, logout, and middleware logic. My review includes one suggestion to improve maintainability by abstracting the duplicated 'Back to Dashboard' link into a reusable component.

… component

Address code review feedback:

1. Login session POST now has a 30s client-side timeout (AbortController)
   with one automatic retry on transient failures (504, 500, network error,
   timeout). Prevents indefinite loading state while tolerating cold starts.

2. Extract BackToDashboard into a reusable component used by athletes,
   analytics, games, profile, and settings pages — reduces duplication.

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

github-actions bot commented Mar 6, 2026

Deployed to staging: https://hustle-app-staging-d4f2hb75nq-uc.a.run.app

@github-actions
Copy link

github-actions bot commented Mar 6, 2026

Smoke tests ✅ Passed

Target: https://hustle-app-staging-d4f2hb75nq-uc.a.run.app

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
src/app/login/page.tsx (1)

78-83: Consider a more robust network error detection heuristic.

The condition err.message?.includes('fetch') is a weak heuristic that could match unrelated errors containing the word "fetch". Consider checking for TypeError (which fetch throws on network failures) or using a more specific pattern.

💡 Suggested improvement
          const isRetryable = attempt < 2 && (
            err.name === 'AbortError' ||
            err.status === 504 ||
            err.status === 500 ||
-           err.message?.includes('fetch')
+           err instanceof TypeError // fetch throws TypeError on network failures
          );
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/app/login/page.tsx` around lines 78 - 83, The retry heuristic in the
isRetryable calculation is too loose because err.message?.includes('fetch') can
match unrelated messages; update the condition used inside the isRetryable
expression (where attempt, err.name, and err.status are referenced) to detect
network/fetch failures more robustly by checking for TypeError (e.g., err
instanceof TypeError or err.name === 'TypeError') and optionally adding a
focused regex like /NetworkError|Failed to fetch/ on err.message, replacing the
current err.message?.includes('fetch') check.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/app/login/page.tsx`:
- Around line 78-83: The retry heuristic in the isRetryable calculation is too
loose because err.message?.includes('fetch') can match unrelated messages;
update the condition used inside the isRetryable expression (where attempt,
err.name, and err.status are referenced) to detect network/fetch failures more
robustly by checking for TypeError (e.g., err instanceof TypeError or err.name
=== 'TypeError') and optionally adding a focused regex like /NetworkError|Failed
to fetch/ on err.message, replacing the current err.message?.includes('fetch')
check.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e668e84b-aa98-4a8f-85ce-a673660016e2

📥 Commits

Reviewing files that changed from the base of the PR and between c7f07f3 and 3032c12.

📒 Files selected for processing (7)
  • src/app/dashboard/analytics/page.tsx
  • src/app/dashboard/athletes/page.tsx
  • src/app/dashboard/games/page.tsx
  • src/app/dashboard/profile/page.tsx
  • src/app/dashboard/settings/page.tsx
  • src/app/login/page.tsx
  • src/components/ui/back-to-dashboard.tsx
🚧 Files skipped from review as they are similar to previous changes (4)
  • src/app/dashboard/profile/page.tsx
  • src/app/dashboard/analytics/page.tsx
  • src/app/dashboard/athletes/page.tsx
  • src/app/dashboard/games/page.tsx

__session is now the sole auth mechanism (no fallback cookie). Server-side
verifyIdToken/createSessionCookie timeouts of 10s are too aggressive for
Firebase Admin cold starts (10-20s documented). Increased to 25s to stay
under the client's 30s AbortController timeout while accommodating cold starts.

Addresses Qodo review finding on PR #39.

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

github-actions bot commented Mar 6, 2026

Deployed to staging: https://hustle-app-staging-d4f2hb75nq-uc.a.run.app

@github-actions
Copy link

github-actions bot commented Mar 6, 2026

Smoke tests ✅ Passed

Target: https://hustle-app-staging-d4f2hb75nq-uc.a.run.app

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/app/api/auth/set-session/route.ts (1)

43-59: ⚠️ Potential issue | 🟠 Major

Use a single end-to-end timeout budget here.

Lines 43 and 59 now allow roughly 50s total because the 25s limits are applied sequentially. That exceeds the client's 30s abort window from the PR context, so slow cold starts can still fail login before the __session response makes it back.

⏱️ Proposed fix
+const SESSION_SETUP_TIMEOUT_MS = 25_000;
+
 export async function POST(request: NextRequest) {
   const t0 = Date.now();
+  const remainingTimeoutMs = () =>
+    Math.max(1, SESSION_SETUP_TIMEOUT_MS - (Date.now() - t0));
   console.log(`[set-session] POST handler entered at ${new Date().toISOString()}`);
   try {
@@
-      decodedToken = await withTimeout(adminAuth.verifyIdToken(idToken, true), 25000, 'verifyIdToken');
+      decodedToken = await withTimeout(
+        adminAuth.verifyIdToken(idToken, true),
+        remainingTimeoutMs(),
+        'verifyIdToken'
+      );
@@
-      sessionCookie = await withTimeout(adminAuth.createSessionCookie(idToken, { expiresIn: SESSION_EXPIRES_MS }), 25000, 'createSessionCookie');
+      sessionCookie = await withTimeout(
+        adminAuth.createSessionCookie(idToken, { expiresIn: SESSION_EXPIRES_MS }),
+        remainingTimeoutMs(),
+        'createSessionCookie'
+      );
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/app/api/auth/set-session/route.ts` around lines 43 - 59, The two
sequential withTimeout calls (adminAuth.verifyIdToken and
adminAuth.createSessionCookie) each use 25s, allowing ~50s total; change to a
single end-to-end timeout budget by recording t0 at request start and computing
remainingMs before each Firebase call, then pass that remainingMs into
withTimeout (or return a timeout error if remainingMs <= 0). Update the calls
that reference adminAuth.verifyIdToken and adminAuth.createSessionCookie (and
the surrounding t0/withTimeout logic) to use the computed remaining time (based
on a single constant TOTAL_SESSION_BUDGET_MS) so both calls share one timeout
budget and never exceed the client abort window.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@src/app/api/auth/set-session/route.ts`:
- Around line 43-59: The two sequential withTimeout calls
(adminAuth.verifyIdToken and adminAuth.createSessionCookie) each use 25s,
allowing ~50s total; change to a single end-to-end timeout budget by recording
t0 at request start and computing remainingMs before each Firebase call, then
pass that remainingMs into withTimeout (or return a timeout error if remainingMs
<= 0). Update the calls that reference adminAuth.verifyIdToken and
adminAuth.createSessionCookie (and the surrounding t0/withTimeout logic) to use
the computed remaining time (based on a single constant TOTAL_SESSION_BUDGET_MS)
so both calls share one timeout budget and never exceed the client abort window.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 8060cd3c-9509-4f90-809d-b18f248a7aba

📥 Commits

Reviewing files that changed from the base of the PR and between 3032c12 and f83dc72.

📒 Files selected for processing (1)
  • src/app/api/auth/set-session/route.ts

@jeremylongshore jeremylongshore merged commit 46d0e88 into main Mar 6, 2026
8 of 9 checks passed
@jeremylongshore jeremylongshore deleted the fix/remove-otel-deadlock branch March 6, 2026 23:00
jeremylongshore pushed a commit that referenced this pull request Mar 9, 2026
* fix(auth): remove broken fallback cookie and AbortController timeout

Remove the firebase-auth-token fallback cookie that was never read by
middleware or auth.ts, causing a false sense of resilience. Remove the
AbortController timeout on the session POST that was aborting before the
server could respond on cold starts. Login now awaits the session POST
fully and surfaces clear error messages on failure.

- Remove firebase-auth-token cookie from login, logout, sidebar, user-nav
- Remove AbortController from login page session POST
- Remove onIdTokenChanged listener from ProtectedRoute
- Remove onIdTokenChange export from client auth module
- Revert middleware to only check __session cookie

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

* fix(ui): mobile sidebar background, back buttons, header text, close btn

- Fix transparent mobile sidebar by adding --sidebar CSS variable and
  Tailwind color mapping so bg-sidebar resolves correctly
- Add "← Back to Dashboard" link to athletes, analytics, settings,
  profile, and games pages (matching dream-gym style)
- Change header text from "Dashboard" to "Hustle"
- Move sidebar close button to right of HUSTLE logo

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

* fix(auth,ui): add session POST timeout+retry, extract BackToDashboard component

Address code review feedback:

1. Login session POST now has a 30s client-side timeout (AbortController)
   with one automatic retry on transient failures (504, 500, network error,
   timeout). Prevents indefinite loading state while tolerating cold starts.

2. Extract BackToDashboard into a reusable component used by athletes,
   analytics, games, profile, and settings pages — reduces duplication.

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

* fix(auth): increase set-session timeouts from 10s to 25s for cold starts

__session is now the sole auth mechanism (no fallback cookie). Server-side
verifyIdToken/createSessionCookie timeouts of 10s are too aggressive for
Firebase Admin cold starts (10-20s documented). Increased to 25s to stay
under the client's 30s AbortController timeout while accommodating cold starts.

Addresses Qodo review finding on PR #39.

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: jeremylongshore <noreply@localhost.local>
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