Skip to content

Conversation

@huamanraj
Copy link
Collaborator

@huamanraj huamanraj commented Dec 15, 2025

in this revamp code @apsinghdev

works:
login signup

errors:
stuck at processing for payments

image

Summary by CodeRabbit

Release Notes

  • New Features

    • Implemented subscription system enabling premium paid user tiers with exclusive features
    • Added protected pro routes requiring active subscription for accessing premium dashboard and newsletters
  • Improvements

    • Enhanced automatic session refresh following successful payment completion
    • Optimized subscription data caching and retrieval for improved performance

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

@vercel
Copy link

vercel bot commented Dec 15, 2025

@huamanraj is attempting to deploy a commit to the AJEET PRATAP SINGH's projects Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 15, 2025

Walkthrough

This PR enriches user context with subscription information across the backend and frontend. It introduces subscription-aware authentication middleware, updates user type definitions to include active subscription details, enhances JWT/session handling to track paid status, and protects pro routes based on active subscription eligibility.

Changes

Cohort / File(s) Summary
Backend Auth Type & Context
apps/api/src/context.ts, apps/api/src/utils/auth.ts, apps/api/src/trpc.ts
Added new UserWithSubscription interface with subscription fields. Updated verifyToken to return enriched user payload including isPaidUser and subscription details. Imported UserWithSubscription in context and TRPC layers; added requiresSubscription middleware and new proProcedure export.
Backend Service & Router
apps/api/src/services/auth.service.ts, apps/api/src/routers/auth.ts
Expanded database queries to include active subscriptions (filtered by status, ordered by startDate, with plan details). Updated handleGoogleAuth and getSession to return enriched user payloads with isPaidUser and subscription objects. Enhanced getSession resolver to load user from DB with subscription data.
Backend Endpoint
apps/api/src/index.ts
Replaced explicit subscription DB lookup in /join-community with in-memory check using user.isPaidUser and user.subscription.
Frontend Session & Auth Config
apps/web/src/lib/auth/config.ts, apps/web/src/types/next-auth.d.ts
Extended NextAuth session callback to expose isPaidUser and subscription on session.user. Enhanced JWT callback to conditionally refresh token data via authenticated TRPC client. Added session strategy (JWT) and sessionToken cookie configuration. Extended Session and JWT types with subscription fields.
Frontend Route Protection
apps/web/src/lib/auth/protected-routes.ts, apps/web/src/middleware.ts
Added PROTECTED_PRO_ROUTES constant for pro-route gating. Updated middleware to check pro routes: redirect to login if no token, or to pricing if user is not paid.
Frontend Payment & Checkout Flow
apps/web/src/components/payment/PaymentFlow.tsx, apps/web/src/components/checkout/CheckoutWrapper.tsx
Updated payment flow to refresh session and redirect with ?payment=success parameter after verification. Added CheckoutWrapper side-effect to call update() and router.refresh() when payment succeeds.
Frontend Subscription Hook
apps/web/src/hooks/useSubscription.ts
Adjusted caching: refetchOnWindowFocus true, staleTime 30s, gcTime 5m (more aggressive refresh).

Sequence Diagram

sequenceDiagram
    participant User as User (Client)
    participant Middleware as Middleware
    participant Session as NextAuth Session
    participant API as TRPC API
    participant DB as Database

    rect rgb(220, 240, 255)
    Note over User,DB: Pro Route Access Attempt
    User->>Middleware: Request /dashboard/pro
    Middleware->>Session: Check token & isPaidUser
    alt No token
        Middleware-->>User: Redirect to login
    else Has token but not paid
        Middleware-->>User: Redirect to /pricing
    else Paid user
        Middleware-->>User: Allow access
    end
    end

    rect rgb(240, 255, 220)
    Note over User,DB: Payment Success & Session Refresh
    User->>API: Complete payment verification
    API->>DB: Validate & create subscription
    DB-->>API: Subscription created
    API-->>User: Success
    User->>Session: Call update() via PaymentFlow
    Session->>API: GET /trpc/auth.getSession
    API->>DB: Query user + active subscriptions + plan
    DB-->>API: User with subscription data
    API->>Session: Return enriched user (isPaidUser, subscription)
    Session->>Session: Update JWT token & session
    User->>User: router.refresh() & redirect to checkout
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

  • Subscription filtering logic (apps/api/src/services/auth.service.ts): Verify the active subscription query (status ACTIVE, endDate >= now, ordered by startDate desc, limited to 1) correctly identifies the most recent valid subscription.
  • Middleware ordering & security (apps/api/src/trpc.ts): Ensure requiresSubscription middleware correctly enforces subscription checks and doesn't bypass authentication.
  • JWT refresh & token cycling (apps/web/src/lib/auth/config.ts): Validate that the conditional JWT refresh in the callback (triggered after payment) correctly updates isPaidUser and subscription without introducing token stale-state issues.
  • Session/DB synchronization: Confirm that both backend (verifyToken, getSession) and frontend (NextAuth callbacks) consistently reflect subscription state and that updates propagate correctly.
  • Pro route protection edge cases (apps/web/src/middleware.ts): Check that paid-user redirects to /pricing (rather than login) and that route-gating logic handles session expiration gracefully.

Possibly related PRs

Poem

🐰 A rabbit hops through auth's new door,
With subscriptions rich and features galore!
Pro routes now guarded, payments aligned,
Sessions refreshed with user's mind.
The JWT dances, the DB rings true—
Paid users unlock what's waiting for you! 🎉

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% 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
Title check ✅ Passed The title accurately reflects the main change: updating user context from User to UserWithSubscription and refactoring the authentication flow across multiple files to support subscription data.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

@huamanraj huamanraj changed the title refactor: update user context and authentication flow refactor: update user context and authentication flow [auth revamp] Dec 15, 2025
Copy link
Contributor

@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: 4

🧹 Nitpick comments (10)
apps/web/src/hooks/useSubscription.ts (1)

28-28: Avoid using any type cast.

The any type cast on line 28 bypasses TypeScript's type checking. Consider properly typing the tRPC router or using type assertions with specific types to maintain type safety.

Replace the any cast with proper typing:

-  } = (trpc.user as any).subscriptionStatus.useQuery(undefined, {
+  } = trpc.user.subscriptionStatus.useQuery(undefined, {

If the tRPC router types are not properly exported, ensure your @/lib/trpc exports include the correct router type, or use a more specific type assertion.

apps/api/src/utils/auth.ts (1)

19-19: Avoid any type for completedSteps.

Per coding guidelines, avoid any type. Define a proper type or use unknown with type narrowing if the structure is truly dynamic.

-  completedSteps: any;
+  completedSteps: Record<string, boolean> | unknown;
apps/web/src/lib/auth/config.ts (3)

60-61: Avoid casting to any for type safety.

These casts bypass TypeScript's type checking. Consider extending the JWT type declarations in apps/web/src/types/next-auth.d.ts to properly type isPaidUser and subscription.

-      const isPaidUser = (token.isPaidUser as boolean) || false;
-      const subscription = (token.subscription as any) || null;
+      const isPaidUser = token.isPaidUser ?? false;
+      const subscription = token.subscription ?? null;

89-93: Refresh logic may cause excessive API calls for free users.

The condition !token.isPaidUser means every token refresh for non-paid users triggers a getSession API call. Consider caching the result or adding a timestamp-based check to reduce load.

         const shouldRefresh =
           trigger === "update" ||
           trigger === "signIn" ||
-          !token.isPaidUser ||
           token.isPaidUser === undefined;

97-103: Multiple any casts indicate missing type definitions.

The tempSession and trpc.auth casts suggest the tRPC client types don't match the expected session shape. Consider defining proper types for the authenticated client to maintain type safety throughout the auth flow.

apps/api/src/trpc.ts (2)

27-27: Redundant cast - verifyToken already returns UserWithSubscription.

Since verifyToken is typed to return Promise<UserWithSubscription>, this cast is unnecessary.

-        user: user as UserWithSubscription,
+        user,

46-53: Redundant subscription check.

isPaidUser is derived from !!activeSubscription in verifyToken, so checking both !user.isPaidUser || !user.subscription is redundant. One condition suffices.

-  if (!user.isPaidUser || !user.subscription) {
+  if (!user.isPaidUser) {
apps/api/src/services/auth.service.ts (3)

29-29: Avoid any type for prisma parameter.

Per coding guidelines, avoid any type. The PrismaClient type is already imported but not used for the parameter.

-  async handleGoogleAuth(prisma: any, input: GoogleAuthInput) {
+  async handleGoogleAuth(prisma: PrismaClient, input: GoogleAuthInput) {

43-59: Duplicated subscription query logic.

This subscription include block is nearly identical to the one in apps/api/src/utils/auth.ts (lines 49-64). Consider extracting a shared helper function to reduce duplication and ensure consistency.

// example: in a shared utility
const activeSubscriptionInclude = {
  subscriptions: {
    where: {
      status: SUBSCRIPTION_STATUS.ACTIVE,
      endDate: { gte: new Date() },
    },
    orderBy: { startDate: "desc" as const },
    take: 1,
    include: { plan: true },
  },
};

230-230: Type the user parameter properly.

Using any loses type safety. Import and use UserWithSubscription from ../utils/auth.js.

+import { type UserWithSubscription } from "../utils/auth.js";
+
-  getSession(user: any) {
+  getSession(user: UserWithSubscription) {
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fc0461a and 6847602.

📒 Files selected for processing (13)
  • apps/api/src/context.ts (2 hunks)
  • apps/api/src/index.ts (1 hunks)
  • apps/api/src/routers/auth.ts (1 hunks)
  • apps/api/src/services/auth.service.ts (3 hunks)
  • apps/api/src/trpc.ts (3 hunks)
  • apps/api/src/utils/auth.ts (1 hunks)
  • apps/web/src/components/checkout/CheckoutWrapper.tsx (1 hunks)
  • apps/web/src/components/payment/PaymentFlow.tsx (2 hunks)
  • apps/web/src/hooks/useSubscription.ts (1 hunks)
  • apps/web/src/lib/auth/config.ts (4 hunks)
  • apps/web/src/lib/auth/protected-routes.ts (1 hunks)
  • apps/web/src/middleware.ts (2 hunks)
  • apps/web/src/types/next-auth.d.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (27)
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{ts,tsx,js,jsx}: Always use lowercase when writing comments
Avoid unnecessary comments; code should be self-documenting when possible
Use comments to explain 'why', not 'what'
Remove unused imports
Use UPPER_SNAKE_CASE for constants
Use camelCase for functions and variables

Files:

  • apps/api/src/index.ts
  • apps/web/src/components/checkout/CheckoutWrapper.tsx
  • apps/web/src/lib/auth/protected-routes.ts
  • apps/web/src/components/payment/PaymentFlow.tsx
  • apps/api/src/utils/auth.ts
  • apps/api/src/routers/auth.ts
  • apps/web/src/middleware.ts
  • apps/api/src/trpc.ts
  • apps/api/src/services/auth.service.ts
  • apps/web/src/hooks/useSubscription.ts
  • apps/web/src/lib/auth/config.ts
  • apps/web/src/types/next-auth.d.ts
  • apps/api/src/context.ts
**/*.{tsx,ts}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{tsx,ts}: Prefer functional components with TypeScript and use proper TypeScript types, avoid any
Extract reusable logic into custom hooks
Use descriptive prop names and define prop types using TypeScript interfaces or types
Prefer controlled components over uncontrolled
Use zustand for global state (located in src/store/)
Use absolute imports from @/ prefix when available
Include proper aria labels for accessibility
Ensure keyboard navigation works
Maintain proper heading hierarchy
Provide alt text for images
Avoid unnecessary re-renders

Files:

  • apps/api/src/index.ts
  • apps/web/src/components/checkout/CheckoutWrapper.tsx
  • apps/web/src/lib/auth/protected-routes.ts
  • apps/web/src/components/payment/PaymentFlow.tsx
  • apps/api/src/utils/auth.ts
  • apps/api/src/routers/auth.ts
  • apps/web/src/middleware.ts
  • apps/api/src/trpc.ts
  • apps/api/src/services/auth.service.ts
  • apps/web/src/hooks/useSubscription.ts
  • apps/web/src/lib/auth/config.ts
  • apps/web/src/types/next-auth.d.ts
  • apps/api/src/context.ts
**/*.{tsx,ts,jsx,js}

📄 CodeRabbit inference engine (.cursorrules)

Organize imports: react → third-party → local components → utils → types

Files:

  • apps/api/src/index.ts
  • apps/web/src/components/checkout/CheckoutWrapper.tsx
  • apps/web/src/lib/auth/protected-routes.ts
  • apps/web/src/components/payment/PaymentFlow.tsx
  • apps/api/src/utils/auth.ts
  • apps/api/src/routers/auth.ts
  • apps/web/src/middleware.ts
  • apps/api/src/trpc.ts
  • apps/api/src/services/auth.service.ts
  • apps/web/src/hooks/useSubscription.ts
  • apps/web/src/lib/auth/config.ts
  • apps/web/src/types/next-auth.d.ts
  • apps/api/src/context.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{ts,tsx}: Use PascalCase for types and interfaces with descriptive names
Use dynamic imports for code splitting when appropriate
Memoize expensive computations

Files:

  • apps/api/src/index.ts
  • apps/web/src/components/checkout/CheckoutWrapper.tsx
  • apps/web/src/lib/auth/protected-routes.ts
  • apps/web/src/components/payment/PaymentFlow.tsx
  • apps/api/src/utils/auth.ts
  • apps/api/src/routers/auth.ts
  • apps/web/src/middleware.ts
  • apps/api/src/trpc.ts
  • apps/api/src/services/auth.service.ts
  • apps/web/src/hooks/useSubscription.ts
  • apps/web/src/lib/auth/config.ts
  • apps/web/src/types/next-auth.d.ts
  • apps/api/src/context.ts
**/*.{js,jsx,ts,tsx,py,java,go,rb,php}

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

**/*.{js,jsx,ts,tsx,py,java,go,rb,php}: Always use lowercase when writing comments
Avoid unnecessary comments; code should be self-documenting when possible
Use comments to explain 'why', not 'what'

Files:

  • apps/api/src/index.ts
  • apps/web/src/components/checkout/CheckoutWrapper.tsx
  • apps/web/src/lib/auth/protected-routes.ts
  • apps/web/src/components/payment/PaymentFlow.tsx
  • apps/api/src/utils/auth.ts
  • apps/api/src/routers/auth.ts
  • apps/web/src/middleware.ts
  • apps/api/src/trpc.ts
  • apps/api/src/services/auth.service.ts
  • apps/web/src/hooks/useSubscription.ts
  • apps/web/src/lib/auth/config.ts
  • apps/web/src/types/next-auth.d.ts
  • apps/api/src/context.ts
apps/api/src/**/*.{js,ts}

📄 CodeRabbit inference engine (apps/api/.cursor/rules/backend_rules.mdc)

apps/api/src/**/*.{js,ts}: Log errors with context (userId, endpoint, timestamp) for debugging
Always await async operations; never forget to handle promise rejections
Never log sensitive information (passwords, tokens, credit card numbers)

Files:

  • apps/api/src/index.ts
  • apps/api/src/utils/auth.ts
  • apps/api/src/routers/auth.ts
  • apps/api/src/trpc.ts
  • apps/api/src/services/auth.service.ts
  • apps/api/src/context.ts
apps/api/src/**/*.ts

📄 CodeRabbit inference engine (apps/api/.cursor/rules/backend_rules.mdc)

Avoid any type; use unknown for truly dynamic data and narrow with type guards

Files:

  • apps/api/src/index.ts
  • apps/api/src/utils/auth.ts
  • apps/api/src/routers/auth.ts
  • apps/api/src/trpc.ts
  • apps/api/src/services/auth.service.ts
  • apps/api/src/context.ts
apps/api/src/{index,main,app,server}.{js,ts}

📄 CodeRabbit inference engine (apps/api/.cursor/rules/backend_rules.mdc)

Validate required environment variables on startup; fail fast if missing

Files:

  • apps/api/src/index.ts
apps/web/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

apps/web/src/**/*.{ts,tsx}: Always follow the design system defined in apps/web/src/lib/design-tokens.ts and apps/web/tailwind.config.ts
NEVER use hardcoded hex values (e.g., #5519f7) directly in components; ALWAYS reference colors from the design token system using Tailwind classes
Use semantic color names that describe purpose, not appearance
Use font-sans for standard UI text (Geist Sans) and font-mono for code, technical content, or monospace needs (DM Mono)
Follow Tailwind's spacing scale (0.25rem increments); for section padding use mobile p-4 (1rem) and desktop p-[60px]
Use appropriate border radius: small elements rounded-lg, medium rounded-xl, large rounded-2xl, buttons rounded-[16px]
Use animation durations: fast duration-100 (0.1s), normal duration-300 (0.3s), slow duration-600 (0.6s)

Files:

  • apps/web/src/components/checkout/CheckoutWrapper.tsx
  • apps/web/src/lib/auth/protected-routes.ts
  • apps/web/src/components/payment/PaymentFlow.tsx
  • apps/web/src/middleware.ts
  • apps/web/src/hooks/useSubscription.ts
  • apps/web/src/lib/auth/config.ts
  • apps/web/src/types/next-auth.d.ts
**/*[A-Z]*.{tsx,ts}

📄 CodeRabbit inference engine (.cursorrules)

Use PascalCase for component file names (e.g., UserProfile.tsx)

Files:

  • apps/web/src/components/checkout/CheckoutWrapper.tsx
  • apps/web/src/components/payment/PaymentFlow.tsx
  • apps/web/src/hooks/useSubscription.ts
apps/web/src/**/*.{tsx,ts}

📄 CodeRabbit inference engine (.cursorrules)

Optimize images using next/image

apps/web/src/**/*.{tsx,ts}: Use Zustand for global state, located in src/store/
Use PascalCase for types and interfaces with descriptive names
Use dynamic imports for code splitting when appropriate
Optimize images using next/image
Memoize expensive computations
Define a type when defining const functions

Files:

  • apps/web/src/components/checkout/CheckoutWrapper.tsx
  • apps/web/src/lib/auth/protected-routes.ts
  • apps/web/src/components/payment/PaymentFlow.tsx
  • apps/web/src/middleware.ts
  • apps/web/src/hooks/useSubscription.ts
  • apps/web/src/lib/auth/config.ts
  • apps/web/src/types/next-auth.d.ts
apps/web/src/components/**/*.{tsx,ts,jsx,js}

📄 CodeRabbit inference engine (apps/web/.cursor/rules/frontend_rules.mdc)

apps/web/src/components/**/*.{tsx,ts,jsx,js}: Never use hardcoded hex values directly in components; always reference colors from the design token system using Tailwind classes
Use semantic color names from the design token system that describe purpose, not appearance (e.g., bg-brand-purple, bg-surface-primary, text-text-primary)
Use font-sans for standard UI text (Geist Sans) and font-mono for code, technical content, or monospace needs (DM Mono)
Follow Tailwind's spacing scale for section padding: p-4 (1rem) on mobile, p-[60px] on desktop
Use rounded-lg (0.5rem) for small elements, rounded-xl (1rem) for medium elements, rounded-2xl (1.5rem) for large elements, and rounded-[16px] for buttons
Use duration-100 (0.1s) for fast transitions, duration-300 (0.3s) for normal transitions, and duration-600 (0.6s) for slow transitions
Use available custom animations: animate-accordion-down, animate-accordion-up, animate-scrollRight, animate-scrollLeft, animate-customspin, animate-spin-slow, animate-spin-slow-reverse, animate-marquee, animate-marquee-vertical, animate-shine
Prefer functional components with TypeScript
Extract reusable logic into custom hooks
Prefer controlled components over uncontrolled
Include proper aria labels for accessibility
Ensure keyboard navigation works in interactive components
Maintain proper heading hierarchy in page components
Provide alt text for images
Use 'class:' instead of the ternary operator in class tags whenever possible
Implement accessibility features on interactive elements (e.g., tabindex='0', aria-label, onClick, onKeyDown)
Always follow the design system defined in apps/web/src/lib/design-tokens.ts and apps/web/tailwind.config.ts

Files:

  • apps/web/src/components/checkout/CheckoutWrapper.tsx
  • apps/web/src/components/payment/PaymentFlow.tsx
apps/web/src/components/**/*.{tsx,ts}

📄 CodeRabbit inference engine (apps/web/.cursor/rules/frontend_rules.mdc)

apps/web/src/components/**/*.{tsx,ts}: Use proper TypeScript types and avoid using any type
Use descriptive prop names and define prop types using TypeScript interfaces or types
Name components using PascalCase (e.g., UserProfile.tsx)

Files:

  • apps/web/src/components/checkout/CheckoutWrapper.tsx
  • apps/web/src/components/payment/PaymentFlow.tsx
apps/web/src/**/*.{tsx,ts,jsx,js}

📄 CodeRabbit inference engine (apps/web/.cursor/rules/frontend_rules.mdc)

apps/web/src/**/*.{tsx,ts,jsx,js}: Organize imports in order: React → third-party → local components → utils → types
Use absolute imports from @/ prefix when available
Remove unused imports
Use UPPER_SNAKE_CASE for constants
Use camelCase for functions and variables
Always use Tailwind classes for styling HTML elements; avoid using CSS or style tags
Use descriptive variable and function names; name event functions with a 'handle' prefix (e.g., handleClick, handleKeyDown)
Use const with arrow functions instead of function declarations (e.g., 'const toggle = () =>')

Files:

  • apps/web/src/components/checkout/CheckoutWrapper.tsx
  • apps/web/src/lib/auth/protected-routes.ts
  • apps/web/src/components/payment/PaymentFlow.tsx
  • apps/web/src/middleware.ts
  • apps/web/src/hooks/useSubscription.ts
  • apps/web/src/lib/auth/config.ts
  • apps/web/src/types/next-auth.d.ts
**/src/{lib,utils}/**

📄 CodeRabbit inference engine (.cursorrules)

Use kebab-case or camelCase for utility file names

Files:

  • apps/web/src/lib/auth/protected-routes.ts
  • apps/api/src/utils/auth.ts
  • apps/web/src/lib/auth/config.ts
apps/web/src/{lib,utils}/**/*.{tsx,ts,jsx,js}

📄 CodeRabbit inference engine (apps/web/.cursor/rules/frontend_rules.mdc)

Name files and folders using kebab-case or camelCase for utilities

Files:

  • apps/web/src/lib/auth/protected-routes.ts
  • apps/web/src/lib/auth/config.ts
apps/api/src/**/{middleware,logging,utils}/*.{js,ts}

📄 CodeRabbit inference engine (apps/api/.cursor/rules/backend_rules.mdc)

Include correlation IDs in logs for request tracing across services

Files:

  • apps/api/src/utils/auth.ts
apps/api/src/**/{logging,middleware,utils}/*.{js,ts}

📄 CodeRabbit inference engine (apps/api/.cursor/rules/backend_rules.mdc)

Use structured logging (JSON format) for easier parsing and analysis

Files:

  • apps/api/src/utils/auth.ts
apps/api/src/**/{services,models,database}/*.{js,ts}

📄 CodeRabbit inference engine (apps/api/.cursor/rules/backend_rules.mdc)

Encrypt sensitive data (passwords, tokens, API keys) before storing in database

Files:

  • apps/api/src/services/auth.service.ts
apps/api/src/**/{database,services}/*.{js,ts}

📄 CodeRabbit inference engine (apps/api/.cursor/rules/backend_rules.mdc)

Handle database connection failures gracefully with retry logic

Files:

  • apps/api/src/services/auth.service.ts
apps/api/src/**/{database,models,services}/*.{js,ts}

📄 CodeRabbit inference engine (apps/api/.cursor/rules/backend_rules.mdc)

Always use parameterized queries or ORM methods to prevent SQL injection

Files:

  • apps/api/src/services/auth.service.ts
apps/api/src/**/{services,database}/*.{js,ts}

📄 CodeRabbit inference engine (apps/api/.cursor/rules/backend_rules.mdc)

Wrap database transactions in try-catch blocks with proper rollback on failure

Files:

  • apps/api/src/services/auth.service.ts
apps/api/src/**/{services,repositories}/*.{js,ts}

📄 CodeRabbit inference engine (apps/api/.cursor/rules/backend_rules.mdc)

Avoid N+1 queries; use eager loading or batch queries when fetching related data

Files:

  • apps/api/src/services/auth.service.ts
apps/api/src/**/{services,models}/*.{js,ts}

📄 CodeRabbit inference engine (apps/api/.cursor/rules/backend_rules.mdc)

Validate data against schema before database operations

Files:

  • apps/api/src/services/auth.service.ts
apps/api/src/**/{database,clients,services}/*.{js,ts}

📄 CodeRabbit inference engine (apps/api/.cursor/rules/backend_rules.mdc)

Use connection pooling for database and external service clients

Files:

  • apps/api/src/services/auth.service.ts
apps/api/src/**/{services,clients,handlers}/*.{js,ts}

📄 CodeRabbit inference engine (apps/api/.cursor/rules/backend_rules.mdc)

Implement timeouts for external API calls to prevent hanging requests

Files:

  • apps/api/src/services/auth.service.ts
apps/api/src/**/{middleware,services,routes,controllers}/*.{js,ts}

📄 CodeRabbit inference engine (apps/api/.cursor/rules/backend_rules.mdc)

Log all critical operations (auth attempts, payment processing, data mutations)

Files:

  • apps/api/src/services/auth.service.ts
🧠 Learnings (3)
📚 Learning: 2025-11-25T07:34:58.984Z
Learnt from: CR
Repo: apsinghdev/opensox PR: 0
File: apps/api/.cursor/rules/backend_rules.mdc:0-0
Timestamp: 2025-11-25T07:34:58.984Z
Learning: Applies to apps/api/src/**/{routes,controllers,handlers,middleware}/*.{js,ts} : Always validate user authentication before processing protected routes

Applied to files:

  • apps/web/src/lib/auth/protected-routes.ts
  • apps/api/src/routers/auth.ts
  • apps/web/src/middleware.ts
  • apps/api/src/trpc.ts
📚 Learning: 2025-11-25T07:34:58.984Z
Learnt from: CR
Repo: apsinghdev/opensox PR: 0
File: apps/api/.cursor/rules/backend_rules.mdc:0-0
Timestamp: 2025-11-25T07:34:58.984Z
Learning: Applies to apps/api/src/**/{routes,middleware}/*.{js,ts} : Use middleware for auth checks; never duplicate auth logic in route handlers

Applied to files:

  • apps/web/src/lib/auth/protected-routes.ts
  • apps/web/src/middleware.ts
  • apps/api/src/trpc.ts
📚 Learning: 2025-11-25T07:34:58.984Z
Learnt from: CR
Repo: apsinghdev/opensox PR: 0
File: apps/api/.cursor/rules/backend_rules.mdc:0-0
Timestamp: 2025-11-25T07:34:58.984Z
Learning: Applies to apps/api/src/**/{routes,middleware}/*.{js,ts} : Implement rate limiting on all public endpoints to prevent abuse

Applied to files:

  • apps/web/src/lib/auth/protected-routes.ts
  • apps/web/src/middleware.ts
🧬 Code graph analysis (10)
apps/api/src/index.ts (2)
apps/web/src/components/checkout/checkout-confirmation.tsx (1)
  • isJoining (20-62)
apps/web/src/app/(main)/dashboard/pro/dashboard/page.tsx (1)
  • ProDashboardPage (8-126)
apps/web/src/components/checkout/CheckoutWrapper.tsx (3)
apps/web/src/hooks/useSubscription.ts (1)
  • useSubscription (11-77)
apps/web/src/lib/auth/config.ts (1)
  • session (59-73)
apps/web/src/app/(main)/dashboard/account/page.tsx (2)
  • AccountPage (58-72)
  • AccountPageContent (9-56)
apps/web/src/components/payment/PaymentFlow.tsx (1)
apps/web/src/lib/auth/config.ts (1)
  • session (59-73)
apps/api/src/utils/auth.ts (2)
apps/web/src/lib/auth/config.ts (1)
  • jwt (75-116)
apps/api/src/constants/subscription.ts (1)
  • SUBSCRIPTION_STATUS (5-14)
apps/api/src/routers/auth.ts (1)
apps/api/src/services/auth.service.ts (1)
  • authService (24-245)
apps/web/src/middleware.ts (1)
apps/web/src/lib/auth/protected-routes.ts (1)
  • PROTECTED_PRO_ROUTES (6-9)
apps/api/src/trpc.ts (1)
apps/api/src/utils/auth.ts (1)
  • UserWithSubscription (12-28)
apps/api/src/services/auth.service.ts (2)
apps/api/src/constants/subscription.ts (1)
  • SUBSCRIPTION_STATUS (5-14)
apps/api/src/utils/auth.ts (1)
  • generateToken (30-32)
apps/web/src/lib/auth/config.ts (2)
apps/web/src/lib/trpc.ts (1)
  • trpc (4-4)
apps/web/src/lib/trpc-server.ts (1)
  • createAuthenticatedClient (24-42)
apps/api/src/context.ts (1)
apps/api/src/utils/auth.ts (1)
  • UserWithSubscription (12-28)
🔇 Additional comments (14)
apps/web/src/hooks/useSubscription.ts (1)

30-33: Verify aggressive refetch settings are intentional; also address pre-existing any type cast.

The combination of refetchOnWindowFocus: true with a 30-second staleTime will trigger a refetch every time the user switches back to the tab (if more than 30 seconds have passed). While subscription status is critical for access control, this configuration is notably more aggressive than other queries in the codebase (e.g., the default 60-second staleTime in trpc-provider, or the getCompletedStepsProcedure query which uses refetchOnWindowFocus: false with 5-minute staleTime).

Confirm whether:

  • This aggressive refetching is necessary for real-time subscription enforcement
  • A longer staleTime (e.g., 5 minutes) would be sufficient
  • refetchOnWindowFocus should be false or conditional based on the subscription state

Additionally, line 28 uses any type cast on (trpc.user as any), which violates the guideline to avoid any. Replace with proper TypeScript typing.

apps/web/src/lib/auth/protected-routes.ts (1)

6-9: LGTM!

The new PROTECTED_PRO_ROUTES constant follows the same pattern as PROTECTED_DASHBOARD_ROUTES and properly uses const assertion for type safety.

apps/web/src/middleware.ts (1)

20-22: LGTM!

The isProRoute check follows the same pattern as the existing isProtectedRoute check and correctly identifies pro routes.

apps/api/src/index.ts (1)

121-125: LGTM! Efficiency improvement by using enriched user data.

The change from a database subscription lookup to an in-memory check using user.isPaidUser and user.subscription (provided by the enriched UserWithSubscription type from verifyToken) improves performance while maintaining security. This aligns with the PR's goal of enriching user context with subscription information.

Based on learnings, the authentication is properly validated before processing this protected route.

apps/web/src/components/payment/PaymentFlow.tsx (1)

76-79: LGTM! Proper post-payment flow with session refresh.

The updated flow correctly:

  1. Refreshes the session with await update() to fetch the latest paid status
  2. Navigates to the success page
  3. Triggers a router refresh to revalidate server components

This ensures the user's subscription status is immediately reflected across the application.

apps/web/src/components/checkout/CheckoutWrapper.tsx (1)

17-24: LGTM! Proper session refresh after payment success.

The useEffect correctly:

  • Detects payment success via URL parameter
  • Refreshes the session to fetch updated subscription data
  • Uses hasRefreshed flag to prevent multiple refreshes
  • Triggers router refresh to revalidate server-side data

The dependency array is complete, and the hasRefreshed guard prevents infinite loops.

apps/api/src/context.ts (2)

3-3: LGTM! Proper type alignment with enriched user payload.

The import change from Prisma's User to the custom UserWithSubscription type correctly aligns the context type with the enriched user data that includes subscription information.


13-13: LGTM! Context type updated to support enriched user data.

The context's user field now properly types to UserWithSubscription | null, supporting the subscription-aware authentication flow throughout the application.

apps/web/src/types/next-auth.d.ts (2)

6-19: LGTM! Properly extends Session interface with subscription data.

The Session interface extension correctly adds:

  • isPaidUser boolean flag for quick access checks
  • Detailed subscription object with all necessary fields

This aligns with the enriched authentication payload from the backend.


26-34: LGTM! JWT interface properly extended.

The JWT interface extension mirrors the Session user fields, ensuring consistency across the authentication flow. This enables the JWT callback to pass subscription data from the token to the session.

apps/api/src/utils/auth.ts (1)

47-66: LGTM on subscription query logic.

The Prisma query correctly filters for active subscriptions with valid end dates, orders by most recent, and limits to one result. The include for plan data is appropriate.

apps/web/src/lib/auth/config.ts (1)

21-35: LGTM on session and cookie configuration.

JWT strategy with 7-day expiry aligns with the backend token expiry. Cookie configuration properly handles production security with __Secure- prefix and secure flag.

apps/api/src/trpc.ts (1)

38-61: Middleware approach for subscription checks is correct.

Based on learnings, using middleware for auth checks avoids duplicating auth logic in route handlers. The requiresSubscription middleware properly chains after authentication and provides clear error messages.

apps/api/src/services/auth.service.ts (1)

65-87: LGTM on enriched user response structure.

The response includes all necessary user fields plus subscription details with proper null handling. The planName inclusion from the related plan is a good addition for display purposes.

Comment on lines 69 to 116
getSession: protectedProcedure.query(
async ({ ctx }: { ctx: { user: any } }) => {
return authService.getSession(ctx.user);
const userId = ctx.user.id;
const user = await ctx.db.prisma.user.findUnique({
where: { id: userId },
include: {
subscriptions: {
where: {
status: "active",
endDate: {
gte: new Date(),
},
},
orderBy: {
startDate: "desc",
},
take: 1,
include: {
plan: true,
},
},
},
});

if (!user) {
throw new TRPCError({
code: "NOT_FOUND",
message: "User not found",
});
}

const activeSubscription = user.subscriptions[0] || null;

return authService.getSession({
...user,
isPaidUser: !!activeSubscription,
subscription: activeSubscription
? {
id: activeSubscription.id,
status: activeSubscription.status,
startDate: activeSubscription.startDate,
endDate: activeSubscription.endDate,
planId: activeSubscription.planId,
planName: activeSubscription.plan?.name,
}
: null,
});
}
Copy link
Contributor

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:

rg -nP '\bSUBSCRIPTION_STATUS\b' --type=ts -A2

Repository: apsinghdev/opensox

Length of output: 2348


🏁 Script executed:

# Check the full auth.ts file to see type definitions and context
fd auth.ts --type f | head -5

Repository: apsinghdev/opensox

Length of output: 117


🏁 Script executed:

# Search for subscription status constants or enums
rg -n 'status.*active' apps/api/src --type=ts -B2 -A2 | head -50

Repository: apsinghdev/opensox

Length of output: 1508


🏁 Script executed:

# Get the full context of the auth.ts file to see type definitions
head -70 apps/api/src/routers/auth.ts

Repository: apsinghdev/opensox

Length of output: 2453


🏁 Script executed:

# Check the SUBSCRIPTION_STATUS constant definition
cat -n apps/api/src/constants/subscription.ts

Repository: apsinghdev/opensox

Length of output: 1275


🏁 Script executed:

# Check if there's a ProtectedProcedure type or context type definition
rg -n 'protectedProcedure\|type.*Context' apps/api/src/routers/auth.ts -B2 -A2

Repository: apsinghdev/opensox

Length of output: 44


🏁 Script executed:

# Check how protectedProcedure is defined and what context type it has
cat -n apps/api/src/trpc.ts | head -100

Repository: apsinghdev/opensox

Length of output: 2138


🏁 Script executed:

# Check if there are type definitions for the user object anywhere
rg -n 'type.*User\|interface.*User' apps/api/src/routers/auth.ts -B2 -A5

Repository: apsinghdev/opensox

Length of output: 44


🏁 Script executed:

# Check if SUBSCRIPTION_STATUS is imported in auth.ts
head -20 apps/api/src/routers/auth.ts | grep -n import

Repository: apsinghdev/opensox

Length of output: 321


Use the SUBSCRIPTION_STATUS constant instead of hardcoded string and replace any type with proper typing.

The code should use the SUBSCRIPTION_STATUS.ACTIVE constant (defined in constants/subscription.ts) instead of the hardcoded string "active" at line 77, consistent with the rest of the codebase (utils/auth.ts, services/auth.service.ts, services/user.service.ts, services/payment.service.ts).

Also, replace ctx: { user: any } with the proper UserWithSubscription type available from utils/auth.js and already imported in trpc.ts. The any type violates the API coding guideline that requires avoiding any type.

Required changes:

  • Import SUBSCRIPTION_STATUS from constants/subscription.js
  • Import UserWithSubscription type from utils/auth.js
  • Change line 77 from status: "active" to status: SUBSCRIPTION_STATUS.ACTIVE
  • Change line 70 from { ctx: { user: any } } to { ctx: { user: UserWithSubscription } }
🤖 Prompt for AI Agents
In apps/api/src/routers/auth.ts around lines 69 to 116, replace the inline any
type and hardcoded subscription string: change the function signature param from
"{ ctx: { user: any } }" to "{ ctx: { user: UserWithSubscription } }", import
the UserWithSubscription type from utils/auth.js (or .ts), import
SUBSCRIPTION_STATUS from constants/subscription.js (or .ts), and replace the
subscription where clause status: "active" with status:
SUBSCRIPTION_STATUS.ACTIVE; ensure imports are added at the top of the file and
that TypeScript resolves the type import correctly.

Comment on lines +65 to +66
export const protectedProcedure = t.procedure.use(isAuthed) as any;
export const proProcedure = protectedProcedure.use(requiresSubscription) as any;
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

cat -n apps/api/src/trpc.ts | head -80

Repository: apsinghdev/opensox

Length of output: 2138


🏁 Script executed:

# Check the Context type definition
rg -A 10 "type Context" apps/api/src/context.ts

# Check how these procedures are used
rg "protectedProcedure|proProcedure" apps/api/src --type ts

Repository: apsinghdev/opensox

Length of output: 1253


🏁 Script executed:

cat -n apps/api/src/context.ts

Repository: apsinghdev/opensox

Length of output: 886


🏁 Script executed:

# Check if there are any type-related imports from @trpc/server
rg "@trpc/server" apps/api/src/trpc.ts -A 5

# Search for ProcedureBuilder or similar type patterns
rg "ProcedureBuilder|Procedure<" apps/api/src --type ts

# Check TRPC version in package.json
cat apps/api/package.json | grep -A 2 "@trpc"

Repository: apsinghdev/opensox

Length of output: 393


🏁 Script executed:

# Get full package.json @trpc section
cat apps/api/package.json | grep -A 20 '"@trpc'

Repository: apsinghdev/opensox

Length of output: 361


🏁 Script executed:

# Search for any TRPC type utilities or middleware patterns in the codebase
rg "middleware|context" apps/api/src --type ts -B 2 -A 2 | head -60

# Check if there are any other procedureBuilders or typed procedures
rg "procedure.*use|Procedure" apps/api/src --type ts | head -20

Repository: apsinghdev/opensox

Length of output: 3926


🏁 Script executed:

# Check how procedures are actually used in one of the routers to see the type impact
cat -n apps/api/src/routers/user.ts | head -50

Repository: apsinghdev/opensox

Length of output: 1517


🏁 Script executed:

# Check if there's any type documentation or comments about this in the codebase
rg "TRPC|middleware|context" apps/api/src --type ts -B 1 | grep -i "type\|TODO\|FIXME" | head -20

# Look for any utility files that might help with typing
fd "type\|util" apps/api/src --type ts

Repository: apsinghdev/opensox

Length of output: 314


🏁 Script executed:

# Search for utils directory
fd -t f "\.ts$" apps/api/src/utils/ | head -20

# Check if there are any typing utilities or helpers
rg "type.*Procedure|Builder" apps/api/src --type-add "ts:*.ts" -t ts

Repository: apsinghdev/opensox

Length of output: 121


🏁 Script executed:

# Let me check the exact TypeScript error by looking for any tsconfig and running a type check
cat apps/api/tsconfig.json

# Also check if there's a build or type check script
cat apps/api/package.json | grep -A 10 '"scripts"'

Repository: apsinghdev/opensox

Length of output: 1514


🏁 Script executed:

# Let me check what specific type issue arises by examining the TRPC types more closely
# First, check if there are any other type-related patterns in the codebase
rg "as.*ProcedureBuilder|as.*Procedure" apps/api/src

# Check the full routers to understand how the context is actually used
cat -n apps/api/src/routers/auth.ts | head -40

Repository: apsinghdev/opensox

Length of output: 1697


🏁 Script executed:

# Let me search for any patterns in the codebase that might show a better way to handle this
rg "ProcedureBuilder|BuildProcedure" apps/api

# Also check if there are any type annotations or helpers defined elsewhere
fd -type f -name "*.ts" -path "*/api/src/*" | xargs grep -l "type.*Procedure" 2>/dev/null

# Check auth.ts to see the UserWithSubscription type definition
cat -n apps/api/src/utils/auth.ts | head -30

Repository: apsinghdev/opensox

Length of output: 1192


🌐 Web query:

TRPC middleware context narrowing type safety @trpc/server

💡 Result:

Short answer

  • Define a broad base context with initTRPC.context().
  • In a middleware, return opts.next({ ctx: { ... } }) with the narrowed properties added/overridden; downstream middlewares/procedures will see the refined type. Use middleware chaining (.use / .pipe / unstable_pipe or .concat for reusable plugins) to compose further narrowing. See tRPC docs for examples. [1][2]

Minimal example (v10/v11 style)

import { initTRPC, TRPCError } from '@trpc/server';
const t = initTRPC.context<{ user?: { id: string } }>().create();

const isAuthed = t.middleware(async (opts) => {
  const { ctx } = opts;
  if (!ctx.user) throw new TRPCError({ code: 'UNAUTHORIZED' });
  // return next with a narrowed ctx (user is now non-nullable)
  return opts.next({ ctx: { user: ctx.user } });
});

const protectedProcedure = t.procedure.use(isAuthed).query(({ ctx }) => {
  // ctx.user is typed as { id: string } (non-nullable) here
  return ctx.user.id;
});

References

  • tRPC middlewares / context extension and middleware chaining. [1]
  • tRPC context typing via initTRPC.context(). [2]

🏁 Script executed:

# Let me check if there's a way to properly type these procedures using TRPC's type system
# Look for any type parameter usage with procedure or middleware
rg "\.use<\|Procedure<" apps/api/src

# Check if there's an initTRPC pattern that allows for proper typing
rg "initTRPC\." apps/api/src -A 3

Repository: apsinghdev/opensox

Length of output: 223


🏁 Script executed:

# Let me check if there's a way to create a custom typed procedure builder
# Look for any advanced patterns or if there's a typesafe alternative
rg "createCallerFactory|createServerSideHelpers" apps/api/src

# Check if there's any documentation or commented code about this
rg "TODO|FIXME|NOTE" apps/api/src/trpc.ts

Repository: apsinghdev/opensox

Length of output: 44


Remove as any casts and properly type context narrowing through middleware.

The as any casts on lines 65-66 violate the type safety guidelines and prevent TypeScript from catching errors in consumers. TRPC v11.7.2 supports proper context narrowing through middleware chaining—refactor to define the narrowed context types explicitly (consider creating a custom typed procedure builder or using TRPC's middleware context propagation without type assertions).

🤖 Prompt for AI Agents
In apps/api/src/trpc.ts around lines 65-66, remove the `as any` casts and
instead surface the narrowed context types from the middlewares: update the
middleware signatures to return a typed context (e.g., isAuthed should return
ctx + { user: User } and requiresSubscription should return ctx + {
subscription: Subscription }), then build typed procedures by using
t.procedure.use(isAuthed) and
t.procedure.use(isAuthed).use(requiresSubscription) while preserving TypeScript
generics so the resulting protectedProcedure and proProcedure inherit the
narrowed ctx types; if helpful create a small typedProcedure builder (or
explicit Procedure type aliases) that supplies the middleware-returned Context
type to avoid assertions and ensure callers get correct compile-time types.

Comment on lines 93 to 95
} catch (error) {
throw new Error("Token verification failed");
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Error context is lost when re-throwing.

The catch block swallows the original error, making debugging difficult. Per coding guidelines, log errors with context for debugging.

   } catch (error) {
+    console.error("Token verification failed:", { error, tokenPrefix: token.substring(0, 10) });
     throw new Error("Token verification failed");
   }

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In apps/api/src/utils/auth.ts around lines 93 to 95, the catch block currently
throws a new Error("Token verification failed") and discards the original error;
change it to preserve and surface the original error by logging it with context
(e.g., auth token verification failed) using the project's logger and either
rethrow the original error or throw a new Error that includes the original error
message/stack so debugging information is retained.

Comment on lines +30 to +43
if (isProRoute) {
if (!token) {
const signInUrl = new URL("/login", req.url);
signInUrl.searchParams.set("callbackUrl", pathname);
return NextResponse.redirect(signInUrl);
}

const isPaidUser = (token as any).isPaidUser || false;

if (!isPaidUser) {
const pricingUrl = new URL("/pricing", req.url);
return NextResponse.redirect(pricingUrl);
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Avoid using any type; use proper TypeScript typing.

Line 37 uses (token as any).isPaidUser, which violates the coding guideline to avoid any types. Since apps/web/src/types/next-auth.d.ts extends the JWT interface with isPaidUser, you should properly type the token.

Apply this diff to use proper typing:

-    const isPaidUser = (token as any).isPaidUser || false;
+    const isPaidUser = token?.isPaidUser || false;

Alternatively, if more explicit typing is needed:

+import type { JWT } from "next-auth/jwt";
+
 export async function middleware(req: NextRequest) {
-  const token = await getToken({
+  const token = await getToken({
     req,
     secret: process.env.NEXTAUTH_SECRET,
-  });
+  }) as JWT | null;
   
   // ... later ...
-  const isPaidUser = (token as any).isPaidUser || false;
+  const isPaidUser = token?.isPaidUser || false;

As per coding guidelines: apps/web/src/**/*.ts should use proper TypeScript types and avoid any.

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

Suggested change
if (isProRoute) {
if (!token) {
const signInUrl = new URL("/login", req.url);
signInUrl.searchParams.set("callbackUrl", pathname);
return NextResponse.redirect(signInUrl);
}
const isPaidUser = (token as any).isPaidUser || false;
if (!isPaidUser) {
const pricingUrl = new URL("/pricing", req.url);
return NextResponse.redirect(pricingUrl);
}
}
if (isProRoute) {
if (!token) {
const signInUrl = new URL("/login", req.url);
signInUrl.searchParams.set("callbackUrl", pathname);
return NextResponse.redirect(signInUrl);
}
const isPaidUser = token?.isPaidUser || false;
if (!isPaidUser) {
const pricingUrl = new URL("/pricing", req.url);
return NextResponse.redirect(pricingUrl);
}
}
🤖 Prompt for AI Agents
In apps/web/src/middleware.ts around lines 30–43, replace the unsafe (token as
any).isPaidUser usage with a properly typed token: import the JWT type (or the
project's extended JWT interface) and cast token to that type (e.g., JWT & {
isPaidUser?: boolean } or the declared interface from
apps/web/src/types/next-auth.d.ts), then read isPaidUser from that typed object;
update imports if needed and ensure TypeScript no longer uses any.

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.

1 participant