Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions app/api/user/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { db } from "@/config/db";
import { usersTable } from "@/config/schema";
import { currentUser } from "@clerk/nextjs/server";
import { eq } from "drizzle-orm";
import { point } from "drizzle-orm/pg-core";
import { NextRequest, NextResponse } from "next/server";

export async function POST(req:NextRequest) {

const user = await currentUser();

const users = await db.select().from(usersTable)
//@ts-ignore
.where(eq(usersTable.email,user?.primaryEmailAddress?.emailAddress))
Comment on lines +10 to +14
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

Add authentication check and fix type safety issues.

Several critical issues:

  1. Missing authentication check: If the user is not authenticated, currentUser() returns null, but the code proceeds without checking, potentially causing runtime errors or querying with undefined email.

  2. Type suppression with @ts-ignore: This indicates a type mismatch that should be properly resolved rather than suppressed.

  3. Unsafe email access: user?.primaryEmailAddress?.emailAddress could be undefined, making the query condition unreliable.

Apply this diff to add proper authentication and type handling:

 export async function POST(req:NextRequest) {

     const user = await currentUser();
+    
+    if (!user || !user.primaryEmailAddress?.emailAddress) {
+        return NextResponse.json(
+            { error: 'Unauthorized' },
+            { status: 401 }
+        );
+    }
+    
+    const userEmail = user.primaryEmailAddress.emailAddress;

     const users = await db.select().from(usersTable)
-    //@ts-ignore
-    .where(eq(usersTable.email,user?.primaryEmailAddress?.emailAddress))
+    .where(eq(usersTable.email, userEmail))
📝 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
const user = await currentUser();
const users = await db.select().from(usersTable)
//@ts-ignore
.where(eq(usersTable.email,user?.primaryEmailAddress?.emailAddress))
const user = await currentUser();
if (!user || !user.primaryEmailAddress?.emailAddress) {
return NextResponse.json(
{ error: 'Unauthorized' },
{ status: 401 }
);
}
const userEmail = user.primaryEmailAddress.emailAddress;
const users = await db.select().from(usersTable)
.where(eq(usersTable.email, userEmail))
🤖 Prompt for AI Agents
In app/api/user/route.ts around lines 10 to 14, the code calls currentUser()
then queries by its email without checking authentication, uses @ts-ignore and
accesses a possibly undefined email; fix by first verifying currentUser()
returned a user and return an HTTP 401 (or appropriate response) if null,
extract and validate the primary email into a typed string (return 400 or handle
missing email if not present), remove the @ts-ignore and use the validated email
in the where clause (e.g., eq(usersTable.email, email)) so TypeScript types
match and the query never runs with undefined.


if(users?.length <=0){
const newUser = {
name: user?.fullName ?? '',
email : user?.primaryEmailAddress?.emailAddress ?? '' ,
points: 0
}
const result = await db.insert(usersTable)
.values(newUser).returning()

return NextResponse.json(result[0])

}

return NextResponse.json(users[0])
}
Comment on lines +8 to +30
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

Add error handling for database operations.

The database operations (select, insert) can fail due to network issues, constraint violations, or other database errors, but there's no try-catch block to handle these failures gracefully.

Wrap the handler logic in a try-catch block:

 export async function POST(req:NextRequest) {
+    try {
+        const user = await currentUser();
+        
+        if (!user || !user.primaryEmailAddress?.emailAddress) {
+            return NextResponse.json(
+                { error: 'Unauthorized' },
+                { status: 401 }
+            );
+        }
+        
+        const userEmail = user.primaryEmailAddress.emailAddress;

-    const user = await currentUser();
-
-    const users = await db.select().from(usersTable)
-    //@ts-ignore
-    .where(eq(usersTable.email,user?.primaryEmailAddress?.emailAddress))
+        const users = await db.select().from(usersTable)
+            .where(eq(usersTable.email, userEmail))

-    if(users?.length <=0){
-        const newUser = {
-            name: user?.fullName ?? '',
-            email : user?.primaryEmailAddress?.emailAddress ?? '' ,
-            points: 0
-        }
-        const result = await db.insert(usersTable)
-            .values(newUser).returning()
+        if(users?.length === 0){
+            const newUser = {
+                name: user.fullName ?? '',
+                email: userEmail,
+                points: 0
+            }
+            const result = await db.insert(usersTable)
+                .values(newUser).returning()

-        return NextResponse.json(result[0])
+            return NextResponse.json(result[0])
+        }

-    }
-
-    return NextResponse.json(users[0])
+        return NextResponse.json(users[0])
+    } catch (error) {
+        console.error('Error in user route:', error);
+        return NextResponse.json(
+            { error: 'Internal server error' },
+            { status: 500 }
+        );
+    }
 }
🤖 Prompt for AI Agents
In app/api/user/route.ts around lines 8 to 30, the DB calls are unprotected and
can throw; wrap the handler logic in a try-catch so any db errors are caught,
log the error, and return a 500 NextResponse with a safe error message; before
querying, validate currentUser() exists and has an email to avoid querying with
undefined (replace the //@ts-ignore by using a properly typed email variable or
guard), and ensure insert/select results are checked before accessing result[0]
so you return a consistent response or error when operations fail.

7 changes: 7 additions & 0 deletions app/context/UserDetailsContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { createContext } from "react";

export const UserDetailContext = createContext<any>({
userDetails : undefined,
setUserDetail : () => { }

})
24 changes: 22 additions & 2 deletions app/provider.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,32 @@
import React from 'react';
import React, { useEffect, useState } from 'react';
import { ThemeProvider as NextThemesProvider } from "next-themes"

import { useUser } from '@clerk/nextjs';
import axios from 'axios'
import { UserDetailContext } from './context/UserDetailsContext';
import { set } from 'date-fns';
function Provider( {
children,
...props
}: React.ComponentProps<typeof NextThemesProvider>) {

const {user} = useUser();
const[userDetails,setUserDetail]= useState();

useEffect(()=>{
user && CreateNewUser()
},[user])

const CreateNewUser = async() =>{
const result = await axios.post('/api/user',{})
console.log(result)
setUserDetail(result?.data)
}



return (
<NextThemesProvider {...props}>
<UserDetailContext.Provider value={{userDetails,setUserDetail}}/>
{children}
</NextThemesProvider>
Comment on lines +29 to 31
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

Context Provider is self-closing, so children don’t receive context.

Right now the Provider is rendered as a self-closing tag, and {children} are outside it, so nothing in the tree can actually consume UserDetailContext.

<NextThemesProvider {...props}>
-  <UserDetailContext.Provider value={{userDetails,setUserDetail}}/>
-    {children}
+  <UserDetailContext.Provider value={{ userDetails, setUserDetail }}>
+    {children}
+  </UserDetailContext.Provider>
</NextThemesProvider>

Please wrap the children as above and verify any consumers of UserDetailContext now receive the expected value.


🏁 Script executed:

#!/bin/bash
# Find and display the provider file
find . -type f -name "provider.tsx" | head -5

Length of output: 18


🏁 Script executed:

#!/bin/bash
# Display the full app/provider.tsx file
cat app/provider.tsx

Length of output: 895


🏁 Script executed:

#!/bin/bash
# Search for UserDetailContext usage and imports
rg -n "UserDetailContext" --type=tsx --type=ts -C3

Length of output: 27


🏁 Script executed:

#!/bin/bash
# Search for UserDetailContext usage without type flags
rg -n "UserDetailContext" -C3

Length of output: 1089


🏁 Script executed:

#!/bin/bash
# Search for useContext calls that might reference UserDetailContext
rg -n "useContext" -C2

Length of output: 1860


🏁 Script executed:

#!/bin/bash
# Find all files that import from context/UserDetailsContext
rg -n "from.*context/UserDetailsContext" -C2

Length of output: 280


Context Provider is self-closing, so children don't receive context.

Right now the Provider is rendered as a self-closing tag on line 29, and {children} are outside it on line 30, so nothing in the tree can access UserDetailContext.

<NextThemesProvider {...props}>
-  <UserDetailContext.Provider value={{userDetails,setUserDetail}}/>
-    {children}
+  <UserDetailContext.Provider value={{ userDetails, setUserDetail }}>
+    {children}
+  </UserDetailContext.Provider>
</NextThemesProvider>

Wrap children inside the Provider to fix the context propagation. While no current consumers of UserDetailContext exist in the codebase, the structural bug breaks the intended pattern and must be corrected.

🤖 Prompt for AI Agents
In app/provider.tsx around lines 29 to 31, the UserDetailContext.Provider is
self-closing so {children} are placed outside the provider and receive no
context; change the provider to wrap the children (open tag before children,
close tag after children) and pass the same value={{ userDetails, setUserDetail
}} so the context is actually provided to the component tree.

)
Expand Down
3 changes: 3 additions & 0 deletions config/db.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { drizzle } from 'drizzle-orm/neon-http';

export const db = drizzle(process.env.DATABASE_URL!);
9 changes: 9 additions & 0 deletions config/schema.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { integer, pgTable, varchar } from "drizzle-orm/pg-core";

export const usersTable = pgTable("users", {
id: integer().primaryKey().generatedAlwaysAsIdentity(),
name: varchar({ length: 255 }).notNull(),
email: varchar({ length: 255 }).notNull().unique(),
points: integer().default(0),
subscription: varchar()
});
10 changes: 10 additions & 0 deletions drizzle.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import 'dotenv/config';
import { defineConfig } from 'drizzle-kit';

export default defineConfig({
schema: './config/schema.tsx',
dialect: 'postgresql',
dbCredentials: {
url: process.env.DATABASE_URL!,
},
});
Loading