Skip to content

fix incorrect state after sign in and reduce errors#142

Merged
InfinityBowman merged 3 commits into
mainfrom
141-incorrect-state-after-sign-out
Dec 24, 2025
Merged

fix incorrect state after sign in and reduce errors#142
InfinityBowman merged 3 commits into
mainfrom
141-incorrect-state-after-sign-out

Conversation

@InfinityBowman
Copy link
Copy Markdown
Owner

@InfinityBowman InfinityBowman commented Dec 24, 2025

Summary by CodeRabbit

  • Bug Fixes

    • Fixed session synchronization across browser tabs and ensured immediate session refresh on logout
    • Improved error screen navigation reliability with a safer global navigation fallback
    • Enhanced subscription retrieval with a safe fallback to avoid errors
    • Better handling of missing user information in notification connections
  • Changes

    • Post-logout redirect now routes to dashboard instead of sign-in
    • Subscription data fetch is gated by login state
  • Chores

    • Added monorepo tooling and ignore/config updates (dev tooling/configuration)

✏️ Tip: You can customize this high-level summary in your review settings.

@InfinityBowman InfinityBowman linked an issue Dec 24, 2025 that may be closed by this pull request
@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented Dec 24, 2025

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
corates ac85201 Commit Preview URL Dec 24 2025, 10:43 PM

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Dec 24, 2025

Important

Review skipped

Review was skipped as selected files did not have any reviewable changes.

💤 Files selected but had no reviewable changes (1)
  • docs/stripe/llms.txt

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

📝 Walkthrough

Walkthrough

Refactors auth/session flows and UI navigation: session is refetched on logout and inter-tab auth changes; navigation fallbacks added outside router context and post-logout redirect target changed; subscription fetching is gated by login state with a safe default and fetch error handling.

Changes

Cohort / File(s) Summary
Session & Cross-tab Sync
packages/web/src/api/better-auth-store.js
After logout and on receiving auth-change from other tabs, session is refetched (uses optional chaining and await) to force immediate session().data to update to null.
Error UI & Safe Navigation
packages/web/src/components/ErrorBoundary.jsx
Adds SafeNavigateButton that navigates via window.location.href and replaces the previous in-route navigate usage in the error UI.
Navbar sign-out flow
packages/web/src/components/Navbar.jsx
Changes post-signout redirect from /signin to /dashboard and uses replace: true to alter back-button behavior.
Project notifications guard
packages/web/src/components/project-ui/ProjectDashboard.jsx
Handles missing userId by disconnecting and returning early instead of only connecting conditionally; keeps existing connect logic when userId is present.
Sidebar fetch guard (control-flow change)
packages/web/src/components/sidebar/Sidebar.jsx
Replaces positive guard with an early-return `if (!isLoggedIn()
Subscription fetching & safety
packages/web/src/primitives/useSubscription.js
Introduces DEFAULT_SUBSCRIPTION, getSubscriptionSafe wrapper, API_BASE/error handling helpers, and gates subscription fetches behind useBetterAuth (isLoggedIn()); returns safe defaults on error and initializes lazily.
Monorepo tooling / ignore
.gitignore, package.json, turbo.json, packages/workers/turbo.json
Adds .turbo to .gitignore, adds turbo devDependency and packageManager to package.json, and introduces Turbo config files for repo task orchestration.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

I hop through tabs to keep sessions tight,
I nudge the window when routes lose sight,
Guards in the burrow catch fetches that fall,
Dashboard ahead — steady steps for all! 🐇

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'fix incorrect state after sign in and reduce errors' is partially related to the changeset. It addresses state management issues and error reduction, which align with several key changes (session refetch logic, error boundary improvements, navigation fixes). However, the title doesn't capture the scope of the changes, which also include significant Turbo build system integration, API call wrapping, and subscription handling improvements that are not mentioned.

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

Copy link
Copy Markdown

@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.

Actionable comments posted: 1

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fdffecd and 7d87241.

📒 Files selected for processing (6)
  • packages/web/src/api/better-auth-store.js
  • packages/web/src/components/ErrorBoundary.jsx
  • packages/web/src/components/Navbar.jsx
  • packages/web/src/components/project-ui/ProjectDashboard.jsx
  • packages/web/src/components/sidebar/Sidebar.jsx
  • packages/web/src/primitives/useSubscription.js
🧰 Additional context used
📓 Path-based instructions (16)
**/*

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Do not use emojis in code, comments, documentation, or commit messages

NEVER use emojis anywhere in code, comments, documentation, plan files, or commit messages. This includes unicode symbols. For UI icons, use solid-icons library or SVGs only.

Files:

  • packages/web/src/components/Navbar.jsx
  • packages/web/src/components/project-ui/ProjectDashboard.jsx
  • packages/web/src/primitives/useSubscription.js
  • packages/web/src/components/ErrorBoundary.jsx
  • packages/web/src/api/better-auth-store.js
  • packages/web/src/components/sidebar/Sidebar.jsx
packages/web/src/**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

packages/web/src/**/*.{js,jsx,ts,tsx}: For UI icons, use the solid-icons library or SVGs only. Do not use emojis
Ensure browser compatibility for all frontend code (Safari is usually problematic)
Keep files small, focused, and modular. If a file exceeds a high number of lines, consider refactoring by extracting sub-modules into a folder with index.jsx and helper components, moving complex logic into separate utility files or primitives, or splitting large forms into section components
Do NOT prop-drill application state. Shared or cross-feature state must live in external stores under packages/web/src/stores/ or relative to the component file
Use createMemo for derived values to ensure they update reactively

Use import aliases from jsconfig.json instead of relative paths

Files:

  • packages/web/src/components/Navbar.jsx
  • packages/web/src/components/project-ui/ProjectDashboard.jsx
  • packages/web/src/primitives/useSubscription.js
  • packages/web/src/components/ErrorBoundary.jsx
  • packages/web/src/api/better-auth-store.js
  • packages/web/src/components/sidebar/Sidebar.jsx
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{js,jsx,ts,tsx}: Prefer modern ES6+ syntax and features
Use aliases for imports when appropriate to improve readability

**/*.{js,jsx,ts,tsx}: Prefer modern ES6+ syntax and features in JavaScript/TypeScript code
Comments should explain why something is being done, not narrate what the code does. Avoid comments that repeat variable names or describe obvious code behavior.

Files:

  • packages/web/src/components/Navbar.jsx
  • packages/web/src/components/project-ui/ProjectDashboard.jsx
  • packages/web/src/primitives/useSubscription.js
  • packages/web/src/components/ErrorBoundary.jsx
  • packages/web/src/api/better-auth-store.js
  • packages/web/src/components/sidebar/Sidebar.jsx
packages/web/src/components/**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

packages/web/src/components/**/*.{js,jsx,ts,tsx}: Use responsive design principles for UI components
Group related components in subdirectories with an index.js barrel export
Use Zag.js for UI components and design system
Zag component exist in packages/web/src/components/zag/* and should be reused. Check the README.md in that folder for a list of existing components before adding new components and when debugging
Components should receive at most 1–5 props, and only for local configuration, not shared state. If a component would need more than 5 props, move the shared data into an external store, a primitive, or Solid context
Do not destructure props in SolidJS components as it breaks reactivity. Instead, access props directly from the props object or wrap them in a function to ensure they are always up-to-date
Components should be lean and focused. They should not implement business logic; move that into stores, utilities, or primitives
Never have a component act as a God component coordinating multiple large concerns

Files:

  • packages/web/src/components/Navbar.jsx
  • packages/web/src/components/project-ui/ProjectDashboard.jsx
  • packages/web/src/components/ErrorBoundary.jsx
  • packages/web/src/components/sidebar/Sidebar.jsx
packages/{web,ui}/src/**/*.{jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/corates.mdc)

Group related components in subdirectories with barrel exports

Files:

  • packages/web/src/components/Navbar.jsx
  • packages/web/src/components/project-ui/ProjectDashboard.jsx
  • packages/web/src/components/ErrorBoundary.jsx
  • packages/web/src/components/sidebar/Sidebar.jsx
packages/{web,landing}/src/**/*.{jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/corates.mdc)

packages/{web,landing}/src/**/*.{jsx,tsx}: Use Ark UI components from @corates/ui package, not local component implementations
Use solid-icons library (e.g., solid-icons/bi, solid-icons/fi) for icon imports

Files:

  • packages/web/src/components/Navbar.jsx
  • packages/web/src/components/project-ui/ProjectDashboard.jsx
  • packages/web/src/components/ErrorBoundary.jsx
  • packages/web/src/components/sidebar/Sidebar.jsx
packages/web/src/**/*.{jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/corates.mdc)

packages/web/src/**/*.{jsx,tsx}: In SolidJS, do NOT prop-drill application state. Import stores directly where needed instead.
In SolidJS, do NOT destructure props. Access props.field directly or wrap in a function: () => props.field
In SolidJS components, components should receive at most 1-5 props (local config only, not shared state)

Files:

  • packages/web/src/components/Navbar.jsx
  • packages/web/src/components/project-ui/ProjectDashboard.jsx
  • packages/web/src/components/ErrorBoundary.jsx
  • packages/web/src/components/sidebar/Sidebar.jsx
packages/web/src/**/*.{jsx,tsx,js,ts}

📄 CodeRabbit inference engine (.cursor/rules/corates.mdc)

In SolidJS, use createMemo for derived values

Files:

  • packages/web/src/components/Navbar.jsx
  • packages/web/src/components/project-ui/ProjectDashboard.jsx
  • packages/web/src/primitives/useSubscription.js
  • packages/web/src/components/ErrorBoundary.jsx
  • packages/web/src/api/better-auth-store.js
  • packages/web/src/components/sidebar/Sidebar.jsx
packages/web/src/**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/error-handling.mdc)

packages/web/src/**/*.{js,ts,jsx,tsx}: Always use handleFetchError from @/lib/error-utils.js for fetch calls in frontend code with options like { showToast: true } for error handling
Use createFormErrorSignals from @/lib/form-errors.js for form validation error handling with field-level and global error management

Files:

  • packages/web/src/components/Navbar.jsx
  • packages/web/src/components/project-ui/ProjectDashboard.jsx
  • packages/web/src/primitives/useSubscription.js
  • packages/web/src/components/ErrorBoundary.jsx
  • packages/web/src/api/better-auth-store.js
  • packages/web/src/components/sidebar/Sidebar.jsx
packages/{web,workers}/src/**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/error-handling.mdc)

packages/{web,workers}/src/**/*.{js,ts,jsx,tsx}: Never throw string literals; always throw Error objects or return domain errors from API routes
Use error utility functions like isErrorCode from @corates/shared or @/lib/error-utils.js to check specific error types instead of manual string comparisons

Files:

  • packages/web/src/components/Navbar.jsx
  • packages/web/src/components/project-ui/ProjectDashboard.jsx
  • packages/web/src/primitives/useSubscription.js
  • packages/web/src/components/ErrorBoundary.jsx
  • packages/web/src/api/better-auth-store.js
  • packages/web/src/components/sidebar/Sidebar.jsx
{packages/web/**,packages/landing/**}/**/*.{jsx,tsx,js,ts}

📄 CodeRabbit inference engine (.cursor/rules/solidjs.mdc)

{packages/web/**,packages/landing/**}/**/*.{jsx,tsx,js,ts}: Never destructure props in SolidJS components - destructuring breaks reactivity. Access props directly (e.g., props.name) or wrap in a function (e.g., const name = () => props.name) to maintain reactivity.
Import stores directly in components rather than prop-drilling store data through component hierarchies.
Use separate read and write patterns for stores: import the store directly for reading data (e.g., projectStore.getProjectList()) and import action stores separately for writing (e.g., projectActionsStore.createProject()).
Use createSignal from solid-js for managing simple reactive values. Prefer derived state with signals or memo over effects when possible.
Use createStore from solid-js/store for managing complex objects and arrays that require granular reactivity, enabling fine-grained updates where only affected parts re-render.
Use createMemo from solid-js for derived values that depend on reactive state, ensuring computed values update only when their dependencies change.
Always clean up effects that create subscriptions or timers using the onCleanup function from solid-js. Use effects sparingly, only when derived values won't work well.
Keep components lean and focused on rendering. Move business logic to stores (for shared state and operations), primitives (for reusable hooks/logic), or utilities (for pure functions).
Use the Show component from solid-js for conditional rendering instead of JavaScript ternary operators or logical AND operators.
Use the For component from solid-js for rendering lists. It provides better performance and keying compared to JavaScript's map function in JSX.
When manipulating children in wrapper components, use the children helper from solid-js to ensure proper reactivity and handling of child elements.

Files:

  • packages/web/src/components/Navbar.jsx
  • packages/web/src/components/project-ui/ProjectDashboard.jsx
  • packages/web/src/primitives/useSubscription.js
  • packages/web/src/components/ErrorBoundary.jsx
  • packages/web/src/api/better-auth-store.js
  • packages/web/src/components/sidebar/Sidebar.jsx
packages/{web,ui}/**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/ui-components.mdc)

packages/{web,ui}/**/*.{js,jsx,ts,tsx}: Import UI components from '@corates/ui' package instead of local component files. Do not import Ark UI components from local paths like '@/components/zag/' or 'packages/web/src/components/zag/'
Always use 'solid-icons' library for icons. Never use emoji characters or text as icon replacements. Import from specific icon sets like 'solid-icons/bi', 'solid-icons/fi', 'solid-icons/ai', etc.

Files:

  • packages/web/src/components/Navbar.jsx
  • packages/web/src/components/project-ui/ProjectDashboard.jsx
  • packages/web/src/primitives/useSubscription.js
  • packages/web/src/components/ErrorBoundary.jsx
  • packages/web/src/api/better-auth-store.js
  • packages/web/src/components/sidebar/Sidebar.jsx
packages/web/**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/ui-components.mdc)

Use import aliases from 'packages/web/jsconfig.json' instead of relative paths. Aliases include: '@/' (src/), '@components/' (src/components/), '@auth-ui/' (src/components/auth-ui/), '@checklist-ui/' (src/components/checklist-ui/), '@project-ui/' (src/components/project-ui/), '@routes/' (src/routes/), '@primitives/' (src/primitives/), '@api/' (src/api/), '@config/' (src/config/), and '@lib/' (src/lib/)

Files:

  • packages/web/src/components/Navbar.jsx
  • packages/web/src/components/project-ui/ProjectDashboard.jsx
  • packages/web/src/primitives/useSubscription.js
  • packages/web/src/components/ErrorBoundary.jsx
  • packages/web/src/api/better-auth-store.js
  • packages/web/src/components/sidebar/Sidebar.jsx
packages/{web,ui}/**/*.{jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/ui-components.mdc)

Use Tailwind CSS classes for styling components

Files:

  • packages/web/src/components/Navbar.jsx
  • packages/web/src/components/project-ui/ProjectDashboard.jsx
  • packages/web/src/components/ErrorBoundary.jsx
  • packages/web/src/components/sidebar/Sidebar.jsx
packages/web/src/primitives/**/*.{js,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Create reusable logic in primitives (hooks) that can be shared across components to keep components clean and focused on rendering

Files:

  • packages/web/src/primitives/useSubscription.js
{packages/web/**,packages/landing/**}/src/primitives/**/*.{jsx,tsx,js,ts}

📄 CodeRabbit inference engine (.cursor/rules/solidjs.mdc)

Create reusable component logic in primitives (custom hooks) rather than embedding business logic directly in components. Primitives should encapsulate store access and complex logic patterns.

Files:

  • packages/web/src/primitives/useSubscription.js
🧠 Learnings (4)
📚 Learning: 2025-12-24T17:23:10.082Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/solidjs.mdc:0-0
Timestamp: 2025-12-24T17:23:10.082Z
Learning: Applies to {packages/web/**,packages/landing/**}/**/*.{jsx,tsx,js,ts} : Always clean up effects that create subscriptions or timers using the `onCleanup` function from solid-js. Use effects sparingly, only when derived values won't work well.

Applied to files:

  • packages/web/src/components/project-ui/ProjectDashboard.jsx
📚 Learning: 2025-12-24T17:23:10.082Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/solidjs.mdc:0-0
Timestamp: 2025-12-24T17:23:10.082Z
Learning: Applies to {packages/web/**,packages/landing/**}/**/*.{jsx,tsx,js,ts} : Use the `Show` component from solid-js for conditional rendering instead of JavaScript ternary operators or logical AND operators.

Applied to files:

  • packages/web/src/components/ErrorBoundary.jsx
📚 Learning: 2025-12-24T17:23:10.082Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/solidjs.mdc:0-0
Timestamp: 2025-12-24T17:23:10.082Z
Learning: Applies to {packages/web/**,packages/landing/**}/**/*.{jsx,tsx,js,ts} : Use `createSignal` from solid-js for managing simple reactive values. Prefer derived state with signals or memo over effects when possible.

Applied to files:

  • packages/web/src/components/ErrorBoundary.jsx
📚 Learning: 2025-12-19T14:49:49.730Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-19T14:49:49.730Z
Learning: Applies to packages/workers/src/**/*.{js,ts} : Use Better-Auth for authentication and user management

Applied to files:

  • packages/web/src/api/better-auth-store.js
🧬 Code graph analysis (4)
packages/web/src/components/project-ui/ProjectDashboard.jsx (3)
packages/web/src/components/sidebar/Sidebar.jsx (1)
  • currentUserId (23-23)
packages/web/src/components/project-ui/overview-tab/OverviewTab.jsx (1)
  • currentUserId (31-31)
packages/web/src/components/project-ui/todo-tab/ToDoTab.jsx (1)
  • currentUserId (29-29)
packages/web/src/primitives/useSubscription.js (2)
packages/web/src/api/billing.js (5)
  • getSubscription (22-34)
  • error (29-29)
  • error (47-47)
  • error (68-70)
  • error (88-88)
packages/web/src/api/better-auth-store.js (2)
  • useBetterAuth (734-736)
  • isLoggedIn (131-137)
packages/web/src/api/better-auth-store.js (3)
packages/workers/src/index.js (1)
  • session (341-341)
packages/workers/src/auth/config.js (1)
  • session (320-322)
packages/workers/src/auth/routes.js (1)
  • session (35-37)
packages/web/src/components/sidebar/Sidebar.jsx (2)
packages/web/src/api/better-auth-store.js (1)
  • isLoggedIn (131-137)
packages/web/src/components/checklist-ui/ChecklistsDashboard.jsx (1)
  • isLoggedIn (12-12)
⏰ 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). (1)
  • GitHub Check: Workers Builds: corates
🔇 Additional comments (9)
packages/web/src/components/project-ui/ProjectDashboard.jsx (1)

80-86: LGTM! Clean guard prevents connection errors during signout.

The early return when userId becomes null appropriately disconnects notifications and prevents connection attempts with invalid state.

packages/web/src/components/Navbar.jsx (1)

47-48: LGTM! Navigation target aligned with dashboard-first UX.

Redirecting to /dashboard after sign-out is appropriate since the dashboard can handle unauthenticated state and provides clear navigation to sign in.

packages/web/src/api/better-auth-store.js (2)

180-184: LGTM! Cross-tab session synchronization working correctly.

Refetching the session when auth changes arrive from other tabs ensures state consistency across tabs.


380-383: LGTM! Immediate session clear prevents stale state issues.

Awaiting the session refetch ensures session().data becomes null right away, preventing components from trying to fetch data with stale user state.

packages/web/src/components/sidebar/Sidebar.jsx (1)

40-44: LGTM! Early return guard is clear and idiomatic.

The refactored guard prevents project list fetching when the user is not logged in or userId is unavailable, aligning with the PR's goal of safer session-aware fetching.

packages/web/src/components/ErrorBoundary.jsx (2)

11-29: LGTM! Fallback navigation appropriate for error recovery.

Using window.location.href ensures navigation works outside Route context (e.g., when the router itself has failed). The full page reload is acceptable for error recovery scenarios and provides a clean slate.


80-80: LGTM! Clean integration of SafeNavigateButton.

packages/web/src/primitives/useSubscription.js (2)

17-24: LGTM! Sensible default subscription object.

The default free tier subscription provides a safe fallback that allows components to function normally during signout or errors.


46-55: LGTM! Login-aware lazy fetch prevents signout errors.

The conditional source function ensures subscription data is only fetched when authenticated, and the initialValue provides immediate fallback data. The resource should automatically refetch when isLoggedIn() becomes true after sign-in.

Comment thread packages/web/src/primitives/useSubscription.js
Copy link
Copy Markdown

@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.

Actionable comments posted: 3

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7d87241 and 23ddde2.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (5)
  • .gitignore
  • package.json
  • packages/web/src/primitives/useSubscription.js
  • packages/workers/turbo.json
  • turbo.json
🧰 Additional context used
📓 Path-based instructions (11)
**/*

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Do not use emojis in code, comments, documentation, or commit messages

NEVER use emojis anywhere in code, comments, documentation, plan files, or commit messages. This includes unicode symbols. For UI icons, use solid-icons library or SVGs only.

Files:

  • package.json
  • packages/web/src/primitives/useSubscription.js
  • turbo.json
  • packages/workers/turbo.json
packages/web/src/**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

packages/web/src/**/*.{js,jsx,ts,tsx}: For UI icons, use the solid-icons library or SVGs only. Do not use emojis
Ensure browser compatibility for all frontend code (Safari is usually problematic)
Keep files small, focused, and modular. If a file exceeds a high number of lines, consider refactoring by extracting sub-modules into a folder with index.jsx and helper components, moving complex logic into separate utility files or primitives, or splitting large forms into section components
Do NOT prop-drill application state. Shared or cross-feature state must live in external stores under packages/web/src/stores/ or relative to the component file
Use createMemo for derived values to ensure they update reactively

Use import aliases from jsconfig.json instead of relative paths

Files:

  • packages/web/src/primitives/useSubscription.js
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{js,jsx,ts,tsx}: Prefer modern ES6+ syntax and features
Use aliases for imports when appropriate to improve readability

**/*.{js,jsx,ts,tsx}: Prefer modern ES6+ syntax and features in JavaScript/TypeScript code
Comments should explain why something is being done, not narrate what the code does. Avoid comments that repeat variable names or describe obvious code behavior.

Files:

  • packages/web/src/primitives/useSubscription.js
packages/web/src/primitives/**/*.{js,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Create reusable logic in primitives (hooks) that can be shared across components to keep components clean and focused on rendering

Files:

  • packages/web/src/primitives/useSubscription.js
packages/web/src/**/*.{jsx,tsx,js,ts}

📄 CodeRabbit inference engine (.cursor/rules/corates.mdc)

In SolidJS, use createMemo for derived values

Files:

  • packages/web/src/primitives/useSubscription.js
packages/web/src/**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/error-handling.mdc)

packages/web/src/**/*.{js,ts,jsx,tsx}: Always use handleFetchError from @/lib/error-utils.js for fetch calls in frontend code with options like { showToast: true } for error handling
Use createFormErrorSignals from @/lib/form-errors.js for form validation error handling with field-level and global error management

Files:

  • packages/web/src/primitives/useSubscription.js
packages/{web,workers}/src/**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/error-handling.mdc)

packages/{web,workers}/src/**/*.{js,ts,jsx,tsx}: Never throw string literals; always throw Error objects or return domain errors from API routes
Use error utility functions like isErrorCode from @corates/shared or @/lib/error-utils.js to check specific error types instead of manual string comparisons

Files:

  • packages/web/src/primitives/useSubscription.js
{packages/web/**,packages/landing/**}/**/*.{jsx,tsx,js,ts}

📄 CodeRabbit inference engine (.cursor/rules/solidjs.mdc)

{packages/web/**,packages/landing/**}/**/*.{jsx,tsx,js,ts}: Never destructure props in SolidJS components - destructuring breaks reactivity. Access props directly (e.g., props.name) or wrap in a function (e.g., const name = () => props.name) to maintain reactivity.
Import stores directly in components rather than prop-drilling store data through component hierarchies.
Use separate read and write patterns for stores: import the store directly for reading data (e.g., projectStore.getProjectList()) and import action stores separately for writing (e.g., projectActionsStore.createProject()).
Use createSignal from solid-js for managing simple reactive values. Prefer derived state with signals or memo over effects when possible.
Use createStore from solid-js/store for managing complex objects and arrays that require granular reactivity, enabling fine-grained updates where only affected parts re-render.
Use createMemo from solid-js for derived values that depend on reactive state, ensuring computed values update only when their dependencies change.
Always clean up effects that create subscriptions or timers using the onCleanup function from solid-js. Use effects sparingly, only when derived values won't work well.
Keep components lean and focused on rendering. Move business logic to stores (for shared state and operations), primitives (for reusable hooks/logic), or utilities (for pure functions).
Use the Show component from solid-js for conditional rendering instead of JavaScript ternary operators or logical AND operators.
Use the For component from solid-js for rendering lists. It provides better performance and keying compared to JavaScript's map function in JSX.
When manipulating children in wrapper components, use the children helper from solid-js to ensure proper reactivity and handling of child elements.

Files:

  • packages/web/src/primitives/useSubscription.js
{packages/web/**,packages/landing/**}/src/primitives/**/*.{jsx,tsx,js,ts}

📄 CodeRabbit inference engine (.cursor/rules/solidjs.mdc)

Create reusable component logic in primitives (custom hooks) rather than embedding business logic directly in components. Primitives should encapsulate store access and complex logic patterns.

Files:

  • packages/web/src/primitives/useSubscription.js
packages/{web,ui}/**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/ui-components.mdc)

packages/{web,ui}/**/*.{js,jsx,ts,tsx}: Import UI components from '@corates/ui' package instead of local component files. Do not import Ark UI components from local paths like '@/components/zag/' or 'packages/web/src/components/zag/'
Always use 'solid-icons' library for icons. Never use emoji characters or text as icon replacements. Import from specific icon sets like 'solid-icons/bi', 'solid-icons/fi', 'solid-icons/ai', etc.

Files:

  • packages/web/src/primitives/useSubscription.js
packages/web/**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/ui-components.mdc)

Use import aliases from 'packages/web/jsconfig.json' instead of relative paths. Aliases include: '@/' (src/), '@components/' (src/components/), '@auth-ui/' (src/components/auth-ui/), '@checklist-ui/' (src/components/checklist-ui/), '@project-ui/' (src/components/project-ui/), '@routes/' (src/routes/), '@primitives/' (src/primitives/), '@api/' (src/api/), '@config/' (src/config/), and '@lib/' (src/lib/)

Files:

  • packages/web/src/primitives/useSubscription.js
🧠 Learnings (3)
📚 Learning: 2025-12-24T17:23:10.082Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/solidjs.mdc:0-0
Timestamp: 2025-12-24T17:23:10.082Z
Learning: Applies to {packages/web/**,packages/landing/**}/**/*.{jsx,tsx,js,ts} : Always clean up effects that create subscriptions or timers using the `onCleanup` function from solid-js. Use effects sparingly, only when derived values won't work well.

Applied to files:

  • packages/web/src/primitives/useSubscription.js
📚 Learning: 2025-12-24T17:22:56.372Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/error-handling.mdc:0-0
Timestamp: 2025-12-24T17:22:56.372Z
Learning: Applies to packages/web/src/**/*.{js,ts,jsx,tsx} : Always use `handleFetchError` from `@/lib/error-utils.js` for fetch calls in frontend code with options like `{ showToast: true }` for error handling

Applied to files:

  • packages/web/src/primitives/useSubscription.js
📚 Learning: 2025-12-24T17:22:56.372Z
Learnt from: CR
Repo: InfinityBowman/corates PR: 0
File: .cursor/rules/error-handling.mdc:0-0
Timestamp: 2025-12-24T17:22:56.372Z
Learning: Applies to packages/{web,workers}/src/**/*.{js,ts,jsx,tsx} : Use error utility functions like `isErrorCode` from `corates/shared` or `@/lib/error-utils.js` to check specific error types instead of manual string comparisons

Applied to files:

  • packages/web/src/primitives/useSubscription.js
⏰ 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). (2)
  • GitHub Check: Workers Builds: corates-workers-prod
  • GitHub Check: Workers Builds: corates
🔇 Additional comments (7)
.gitignore (1)

12-12: LGTM!

The addition of .turbo to the ignore list is standard practice for TurboRepo cache files and aligns with the new Turbo configuration.

package.json (1)

64-64: LGTM!

The packageManager field is a Corepack standard that pins the exact package manager version, ensuring consistent behavior across environments. This aligns well with the engines requirement for pnpm >= 10.0.0.

packages/workers/turbo.json (1)

1-9: Configuration is correct as-is.

The empty outputs array is intentional and appropriate for this Wrangler-based Cloudflare Workers package. Unlike traditional Node.js packages that produce cacheable build artifacts (dist, build output), Wrangler projects are deployed directly to Cloudflare from source. The build script only ensures the shared dependency is built; the workers package itself has no local build artifacts to cache.

packages/web/src/primitives/useSubscription.js (4)

7-8: LGTM! Imports follow coding guidelines.

The new imports for API_BASE, handleFetchError, and useBetterAuth properly use import aliases and are necessary for the login-gated subscription fetching.

Also applies to: 16-16


18-25: LGTM! Well-designed default subscription object.

The DEFAULT_SUBSCRIPTION constant provides a sensible fallback for unauthenticated users and error states, preventing undefined/null issues downstream.


31-49: LGTM! Proper error handling with handleFetchError.

The getSubscriptionSafe function correctly uses handleFetchError with { showToast: false } as required by coding guidelines. The silent error handling and default fallback prevent error boundaries from catching auth/network errors during sign-out flows.

As per coding guidelines and past review feedback, the use of handleFetchError is now properly implemented.


67-161: LGTM! Derived values and helpers follow SolidJS best practices.

The rest of the implementation correctly uses createMemo for derived values and properly accesses the reactive subscription() signal. No concerns with this section.

Comment thread package.json
"eslint-plugin-unicorn": "^62.0.0",
"prettier": "^3.7.4",
"prettier-plugin-tailwindcss": "^0.7.2",
"turbo": "^2.7.2",
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

latest stable version of turbo package npm 2024 2025

💡 Result:

The latest stable version of the npm package "turbo" is 2.5.6. [1][2]

Sources:
[1] npm package page showing version 2.5.6.
[2] npm version listing (canary releases vs stable).


Use the latest stable version of turbo instead of a pre-release.

Turbo 2.7.2 appears to be a canary/pre-release version, as the latest stable version is 2.5.6. Using pre-release versions in devDependencies introduces unnecessary stability risks. Update to "turbo": "^2.5.6" or the latest stable release available.

🤖 Prompt for AI Agents
In package.json around line 57, the turbo dependency is pinned to a pre-release
version ("^2.7.2"); change that entry to the latest stable release (e.g.
"^2.5.6") in devDependencies, save the file, and run your package manager
(npm/yarn/pnpm install) to update the lockfile so the project uses the stable
turbo release.

Comment on lines +56 to +65
const { isLoggedIn } = useBetterAuth();

// Only fetch subscription when user is logged in
// This prevents errors during signout when component is still mounted
const [subscription, { refetch, mutate }] = createResource(
() => (isLoggedIn() ? getSubscriptionSafe() : null),
{
initialValue: DEFAULT_SUBSCRIPTION,
},
});
);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

cat -n packages/web/src/primitives/useSubscription.js

Repository: InfinityBowman/corates

Length of output: 5887


🏁 Script executed:

rg -n "refetch" packages/web/src --type=js --type=ts -B2 -A2

Repository: InfinityBowman/corates

Length of output: 10393


🏁 Script executed:

find packages/web/src -name "*auth*" -type f | head -20

Repository: InfinityBowman/corates

Length of output: 200


🏁 Script executed:

rg -n "useSubscription" packages/web/src --type=js --type=jsx --type=ts --type=tsx -B2 -A5

Repository: InfinityBowman/corates

Length of output: 93


🏁 Script executed:

rg -n -C5 "subscription.*refetch|isLoggedIn" packages/web/src --type=js --type=jsx --type=ts --type=tsx | grep -C3 "effect\|createEffect\|onMount"

Repository: InfinityBowman/corates

Length of output: 93


🏁 Script executed:

rg -n "useSubscription" packages/web/src -B2 -A5

Repository: InfinityBowman/corates

Length of output: 4615


🏁 Script executed:

rg -n "createEffect" packages/web/src -A3 | grep -B3 -A3 "subscription\|isLoggedIn"

Repository: InfinityBowman/corates

Length of output: 1520


🏁 Script executed:

rg -n "onMount" packages/web/src/primitives/useSubscription.js -A5

Repository: InfinityBowman/corates

Length of output: 48


🏁 Script executed:

rg -n "createResource" packages/web/src -B1 -A3 | head -80

Repository: InfinityBowman/corates

Length of output: 4279


🏁 Script executed:

rg -n "createEffect\|onMount" packages/web/src/components -B2 -A8 | grep -B5 -A5 "isLoggedIn\|subscription"

Repository: InfinityBowman/corates

Length of output: 48


🏁 Script executed:

cat -n packages/web/src/api/better-auth-store.js | head -100

Repository: InfinityBowman/corates

Length of output: 4228


🏁 Script executed:

find packages/web/src -name "Layout.jsx" -o -name "Root.jsx" -o -name "App.jsx" | xargs cat -n

Repository: InfinityBowman/corates

Length of output: 1734


Fix reactivity: createResource won't react to login state changes.

The single-function form of createResource only executes once on mount. Calling isLoggedIn() inside the fetcher doesn't create a reactive dependency, so the subscription won't automatically refetch when the user logs in or out. This contradicts the PR objective to fix incorrect state after sign-in.

Use the source/fetcher form to make it reactive:

-  const [subscription, { refetch, mutate }] = createResource(
-    () => (isLoggedIn() ? getSubscriptionSafe() : null),
-    {
-      initialValue: DEFAULT_SUBSCRIPTION,
-    },
-  );
+  const [subscription, { refetch, mutate }] = createResource(
+    isLoggedIn,
+    async (loggedIn) => {
+      if (!loggedIn) {
+        return DEFAULT_SUBSCRIPTION;
+      }
+      return await getSubscriptionSafe();
+    },
+    {
+      initialValue: DEFAULT_SUBSCRIPTION,
+    },
+  );

This ensures whenever isLoggedIn() changes, the fetcher is automatically called with the new value, keeping subscription state synchronized with auth state.

🤖 Prompt for AI Agents
In packages/web/src/primitives/useSubscription.js around lines 56 to 65, the
createResource fetcher calls isLoggedIn() directly so it only runs once on mount
and does not react to auth state changes; change to the source/fetcher form by
providing a source function that returns isLoggedIn() and a separate fetcher
that receives the boolean and returns loggedIn ? getSubscriptionSafe() : null
(preserve the initialValue and destructured refetch/mutate usage) so the
resource automatically re-runs whenever isLoggedIn() changes.

Comment thread turbo.json
Comment on lines +1 to +15
{
"$schema": "./node_modules/turbo/schema.json",
"tasks": {
"build": {
"outputs": ["dist/**"]
},
"check-types": {
"dependsOn": ["^check-types"]
},
"dev": {
"persistent": true,
"cache": false
}
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

# Check if turbo.json exists and verify its content
find . -name "turbo.json" -type f | head -20

Repository: InfinityBowman/corates

Length of output: 108


🏁 Script executed:

# List the root-level turbo.json if it exists
if [ -f "turbo.json" ]; then
  echo "=== turbo.json content ===" 
  cat -n turbo.json
else
  echo "turbo.json not found in root"
fi

Repository: InfinityBowman/corates

Length of output: 448


🏁 Script executed:

# Find all package.json files and check their build scripts and output configurations
echo "=== Checking package.json build scripts and output dirs ==="
fd -t f "package\.json$" -x sh -c '
  dir=$(dirname {})
  if [ "$dir" = "." ]; then 
    dir="root"
  fi
  echo "--- $dir/package.json ---"
  cat {} | jq -r ".scripts.build // .scripts.dev // empty" 2>/dev/null || echo "Cannot parse"
'

Repository: InfinityBowman/corates

Length of output: 568


🏁 Script executed:

# Search for output/dist directory patterns in common config files
echo "=== Checking for output/build directory configs ==="
rg -t json -t js -t ts "dist|outDir|output" --glob "!node_modules" --glob "!.turbo" -A 2 -B 2 | head -100

Repository: InfinityBowman/corates

Length of output: 6455


🏁 Script executed:

# Verify landing package build output location
cat -n packages/landing/jsconfig.json | grep -A 2 -B 2 "dist\|output"

Repository: InfinityBowman/corates

Length of output: 144


🏁 Script executed:

# Check landing build script and output location
grep -r "\.output" packages/landing/package.json packages/landing/scripts/ packages/landing/jsconfig.json

Repository: InfinityBowman/corates

Length of output: 239


Fix turbo.json build task outputs to match actual package build directories.

The build task declares "outputs": ["dist/**"], but packages/landing outputs to .output/public. Update the build task configuration:

"build": {
  "outputs": ["dist/**", ".output/**"]
}

Alternatively, use per-package turbo.json files to specify outputs if they differ across the monorepo.

🤖 Prompt for AI Agents
In turbo.json around lines 1 to 15, the build task only lists "dist/**" as
outputs but the landing package emits to ".output/public"; update the build task
outputs to include ".output/**" (or add per-package turbo.json overrides) so
Turbo correctly tracks and caches the actual build artifacts.

@InfinityBowman InfinityBowman merged commit 74105db into main Dec 24, 2025
2 of 3 checks passed
@InfinityBowman InfinityBowman deleted the 141-incorrect-state-after-sign-out branch December 24, 2025 23:20
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.

incorrect state after sign out

1 participant