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
12 changes: 7 additions & 5 deletions apps/hooks/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ app.use(express.json());

app.post("/hooks/catch/:userId/:workflowId", async (req, res) => {
try {

console.log("THIS LOG IS FROM HOOKS BACKEND THAT WE HAVE RECIEVED THE REQUEST")
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Fix typo in log message.

"RECIEVED" should be "RECEIVED".

📝 Suggested fix
-    console.log("THIS LOG IS FROM HOOKS BACKEND THAT WE HAVE RECIEVED THE REQUEST")
+    console.log("THIS LOG IS FROM HOOKS BACKEND THAT WE HAVE RECEIVED THE REQUEST")
📝 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
console.log("THIS LOG IS FROM HOOKS BACKEND THAT WE HAVE RECIEVED THE REQUEST")
console.log("THIS LOG IS FROM HOOKS BACKEND THAT WE HAVE RECEIVED THE REQUEST")
🤖 Prompt for AI Agents
In `@apps/hooks/src/index.ts` at line 11, Update the console.log statement in
index.ts that currently reads "THIS LOG IS FROM HOOKS BACKEND THAT WE HAVE
RECIEVED THE REQUEST" to correct the typo by changing "RECIEVED" to "RECEIVED"
(locate the console.log call in the module's top-level or exported handler and
update the string literal accordingly).

const { userId, workflowId } = req.params;
Comment on lines +10 to 12
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

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

Avoid unconditional console.log in the hooks handler; it will spam logs under load. Use a proper logger with levels (debug/info) or remove after debugging.

Copilot uses AI. Check for mistakes.
const { triggerData } = req.body;

Expand All @@ -24,7 +26,7 @@ app.post("/hooks/catch/:userId/:workflowId", async (req, res) => {
const workflowExecution = await tx.workflowExecution.create({
data: {
workflowId: workflow.id,
// next time you see this line validate the trigger data thinnnnnnnnnn
// next time you see this line validate the trigger data thinnnnnnnnnn
status: "Pending",
metadata: triggerData,
},
Expand All @@ -39,13 +41,13 @@ app.post("/hooks/catch/:userId/:workflowId", async (req, res) => {
});
return res.status(200).json({
success: true,
workflowExecutionId: result.workflowExecution.id,
workflowExecutionId: result.workflowExecution.id,
});
} catch (error: any) {
console.log(error);
res.status(500).json({
success: false,
error: "Failed to process webhook"
res.status(500).json({
success: false,
error: "Failed to process webhook"
});
Comment on lines +48 to 51
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Missing return before error response.

Without a return statement, the code could potentially continue execution after sending the error response, which may cause "headers already sent" errors if any code is added below.

🐛 Suggested fix
     console.log(error);
-    res.status(500).json({
+    return res.status(500).json({
       success: false,
       error: "Failed to process webhook"
     });
📝 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
res.status(500).json({
success: false,
error: "Failed to process webhook"
});
return res.status(500).json({
success: false,
error: "Failed to process webhook"
});
🤖 Prompt for AI Agents
In `@apps/hooks/src/index.ts` around lines 48 - 51, The error response currently
calls res.status(500).json({...}) without returning, which can allow execution
to continue and later attempt to modify headers; update the handler to stop
further execution by prefixing the response with a return (i.e., return
res.status(500).json(...)) wherever the res.status(500).json call appears (in
the webhook handler function around the res.status(500).json call) so the
function exits immediately after sending the error response.

}
});
Expand Down
1 change: 1 addition & 0 deletions apps/http-backend/src/routes/google_callback.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ googleAuth.get(
"/callback",
userMiddleware,
async (req: Request, res: Response) => {
console.log("Request recieved to the callback from fronted ")
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Fix typos in log message.

The log message contains spelling errors: "recieved" → "received" and "fronted" → "frontend".

📝 Suggested fix
-    console.log("Request recieved to the callback from fronted ")
+    console.log("Request received to the callback from frontend")
📝 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
console.log("Request recieved to the callback from fronted ")
console.log("Request received to the callback from frontend")
🤖 Prompt for AI Agents
In `@apps/http-backend/src/routes/google_callback.ts` at line 75, The console.log
string in the google_callback handler contains typos; update the message where
console.log("Request recieved to the callback from fronted ") is used to correct
the spelling to "received" and "frontend" (e.g., console.log("Request received
to the callback from frontend")) so the log is clear and accurate.

Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

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

This additional console.log in the OAuth callback adds noise to server logs. Prefer structured logging with levels (and avoid logging request details in auth flows) or remove it once verified.

Suggested change
console.log("Request recieved to the callback from fronted ")

Copilot uses AI. Check for mistakes.
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

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

Avoid automated semicolon insertion (94% of all statements in the enclosing function have an explicit semicolon).

Suggested change
console.log("Request recieved to the callback from fronted ")
console.log("Request recieved to the callback from fronted ");

Copilot uses AI. Check for mistakes.
const code = req.query.code;
const state = req.query.state;
const Oauth = new GoogleOAuthService();
Expand Down
88 changes: 81 additions & 7 deletions apps/http-backend/src/routes/userRoutes/userRoutes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,11 @@ import {
NodeUpdateSchema,
TriggerUpdateSchema,
workflowUpdateSchema,
ExecuteWorkflow,
HOOKS_URL,
} from "@repo/common/zod";
import { GoogleSheetsNodeExecutor } from "@repo/nodes";
import axios, { Axios } from "axios";
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

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

Remove the unused Axios import; it isn’t referenced and will trigger lint/no-unused-vars checks.

Suggested change
import axios, { Axios } from "axios";
import axios from "axios";

Copilot uses AI. Check for mistakes.
const router: Router = Router();

router.post("/createAvaliableNode", async (req: AuthRequest, res: Response) => {
Expand Down Expand Up @@ -140,15 +143,16 @@ router.get(
userMiddleware,
async (req: AuthRequest, res) => {
try {
console.log("user from getcredentials: ", req.user);
// console.log("user from getcredentials: ", req.user);
if (!req.user) {
return res.status(statusCodes.BAD_REQUEST).json({
message: "User is not Loggedin",
});
}
const userId = req.user.sub;
const type = req.params.type;
console.log(userId, " -userid");
console.log("The type of data comming to backed is ", type)
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

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

Avoid automated semicolon insertion (90% of all statements in the enclosing function have an explicit semicolon).

Suggested change
console.log("The type of data comming to backed is ", type)
console.log("The type of data comming to backed is ", type);

Copilot uses AI. Check for mistakes.
// console.log(userId, " -userid");

if (!type || !userId) {
return res.status(statusCodes.BAD_REQUEST).json({
Expand Down Expand Up @@ -182,8 +186,6 @@ router.get(
if (credentials.length === 0) {
return res.status(200).json({
message: "No credentials found",
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

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

/getCredentials/:type returns only { message } when no credentials exist, but returns { data, hasCredentials } when they do. This inconsistent response shape breaks clients that always read response.data.data. Return a consistent shape (e.g., data: [] and hasCredentials: false) for the empty case too.

Suggested change
message: "No credentials found",
message: "No credentials found",
data: [],
hasCredentials: false,

Copilot uses AI. Check for mistakes.
data: [], // always array
hasCredentials: false,
});
}

Expand Down Expand Up @@ -278,9 +280,9 @@ router.post(
error: e instanceof Error ? e.message : "Unknown error"
});
}
}
}



);

// ------------------------------------ FETCHING WORKFLOWS -----------------------------------
Expand Down Expand Up @@ -519,13 +521,17 @@ router.post(
// Use an empty array for credentials (if required) or don't pass it at all
// Config must be valid JSON (not an empty string)
// const stage = dataSafe.data.Position
console.log("This is from the backend log of positions", dataSafe.data.position)
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

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

Avoid automated semicolon insertion (90% of all statements in the enclosing function have an explicit semicolon).

Suggested change
console.log("This is from the backend log of positions", dataSafe.data.position)
console.log("This is from the backend log of positions", dataSafe.data.position);

Copilot uses AI. Check for mistakes.
const createdNode = await prismaClient.node.create({
data: {
name: dataSafe.data.Name,
workflowId: dataSafe.data.WorkflowId,
config: dataSafe.data.Config || {},
stage: Number(dataSafe.data.stage ?? 0),
position: {},
position: {
x: dataSafe.data.position.x,
y: dataSafe.data.position.y
},
AvailableNodeID: dataSafe.data.AvailableNodeId,
},
});
Expand Down Expand Up @@ -626,6 +632,74 @@ router.put(
}
);

router.post("/executeWorkflow", userMiddleware, async (req: AuthRequest, res) => {
console.log("REcieved REquest to the execute route ")
const Data = req.body
Comment on lines +635 to +637
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

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

This route-level log is noisy and not actionable in production. Prefer the app logger with a debug level, or remove it once the feature is verified.

Copilot uses AI. Check for mistakes.
if (!req.user) {
return res.status(statusCodes.UNAUTHORIZED).json({
message: "User Not Authorized"
})
}
const parsedData = ExecuteWorkflow.safeParse(Data);
console.log("This is the log data of execute work flow zod", parsedData.error)
if (!parsedData.success) {
return res.status(statusCodes.FORBIDDEN).json({
message: "Error in Zod Schma",
Data: parsedData.error
Comment on lines +646 to +648
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

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

Validation failures from ExecuteWorkflow.safeParse should return 400 (BAD_REQUEST), not 403 (FORBIDDEN). Also consider returning the Zod error under a consistent error key (not Data) and fix the typo in the message ("Schema").

Suggested change
return res.status(statusCodes.FORBIDDEN).json({
message: "Error in Zod Schma",
Data: parsedData.error
return res.status(statusCodes.BAD_REQUEST).json({
message: "Error in Zod Schema",
error: parsedData.error

Copilot uses AI. Check for mistakes.
})
}
Comment on lines +643 to +650
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Use BAD_REQUEST (400) instead of FORBIDDEN (403) for validation errors.

HTTP 403 Forbidden indicates authorization issues, not input validation failures. Zod schema validation errors should return 400 Bad Request.

Proposed fix
   if (!parsedData.success) {
-    return res.status(statusCodes.FORBIDDEN).json({
-      message: "Error in Zod Schma",
+    return res.status(statusCodes.BAD_REQUEST).json({
+      message: "Invalid input",
       Data: parsedData.error
     })
   }
📝 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 parsedData = ExecuteWorkflow.safeParse(Data);
console.log("This is the log data of execute work flow zod", parsedData.error)
if (!parsedData.success) {
return res.status(statusCodes.FORBIDDEN).json({
message: "Error in Zod Schma",
Data: parsedData.error
})
}
const parsedData = ExecuteWorkflow.safeParse(Data);
console.log("This is the log data of execute work flow zod", parsedData.error)
if (!parsedData.success) {
return res.status(statusCodes.BAD_REQUEST).json({
message: "Invalid input",
Data: parsedData.error
})
}
🤖 Prompt for AI Agents
In `@apps/http-backend/src/routes/userRoutes/userRoutes.ts` around lines 643 -
650, The route currently treats Zod validation failures from
ExecuteWorkflow.safeParse as a 403; change the response to use
statusCodes.BAD_REQUEST (400) instead of statusCodes.FORBIDDEN and return the
parsedData.error payload. Locate the block using ExecuteWorkflow.safeParse,
parsedData, and the res.status(...).json call and replace statusCodes.FORBIDDEN
with statusCodes.BAD_REQUEST and ensure the error message/field
(parsedData.error) is returned as before.

const workflowId = parsedData.data.workflowId;
const userId = req.user.id
try {
const trigger = await prismaClient.workflow.findFirst({
where: { id: workflowId, userId: userId },
include: {
Trigger: true
}
})
if (!trigger) {
return res.status(statusCodes.NOT_FOUND).json({
message: "Workflow not found or not authorized"
});
}
console.log("This is the Trigger Name of the workflow", trigger?.Trigger?.name)
console.log("This is the Trigger Data of the workflow", trigger)
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

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

Avoid logging full workflow/trigger objects during execution (trigger can include user/workflow metadata). Use structured logging with redaction and/or log only identifiers at debug level.

Suggested change
console.log("This is the Trigger Data of the workflow", trigger)
console.log("This is the Trigger metadata of the workflow", {
workflowId: trigger.id,
triggerId: trigger.Trigger?.id,
triggerName: trigger.Trigger?.name,
});

Copilot uses AI. Check for mistakes.

if (trigger?.Trigger?.name === "webhook") {
const data = await axios.post(`${HOOKS_URL}/hooks/catch/${userId}/${workflowId}`, {
triggerData: "",

},
{ timeout: 30000 },)
console.log("Workflow Execution for webhook started with Execution Id is ", data.data.workflowExecutionId)
const workflowExecutionId = data.data.workflowExecutionId;
if (!workflowExecutionId) {
return res.status(statusCodes.INTERNAL_SERVER_ERROR).json({
message: "Failed to start workflow execution"
}
)
}
return res.status(200).json({
success: true,
workflowExecutionId: data.data.workflowExecutionId
});
}
else {

return res.status(statusCodes.FORBIDDEN).json({
message: "Trigger is not webhook"
});
}


} catch (error: any) {
return res.status(statusCodes.INTERNAL_SERVER_ERROR).json({
message: "Internal Server Error ",
Error: error instanceof Error ? error.message : "Unknown Error"
})
}

})
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

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

Avoid automated semicolon insertion (90% of all statements in the enclosing script have an explicit semicolon).

Copilot uses AI. Check for mistakes.
router.get("/protected", userMiddleware, (req: AuthRequest, res) => {
return res.json({
ok: true,
Expand Down
8 changes: 7 additions & 1 deletion apps/web/app/components/ui/Design/WorkflowButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,13 @@ export default function ParentComponent() {

return (
<div className="flex flex-wrap items-center gap-2 md:flex-row">
<Button onClick={() => setIsOpen(true)} variant={"outline"}>Create WorkFlow</Button>
<Button
onClick={() => setIsOpen(true)}
variant={"outline"}
className="hover:cursor-pointer"
>
Create WorkFlow
</Button>

{/* The Modal is conditionally rendered here */}
{isOpen && <CardDemo onClose={() => setIsOpen(false)} />}
Expand Down
3 changes: 2 additions & 1 deletion apps/web/app/hooks/useCredential.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ export const useCredentials = (type: string, workflowId?: string): any => {
}

const response = await getCredentials(type);

const data = JSON.stringify(response)
console.log("This is the log from usecredentials" , data)
Comment on lines +21 to +22
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

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

Avoid logging credential responses in the browser console. These objects can contain sensitive OAuth tokens/refresh tokens depending on the backend response shape. Remove this log or ensure it only logs redacted metadata in non-production builds.

Suggested change
const data = JSON.stringify(response)
console.log("This is the log from usecredentials" , data)
if (process.env.NODE_ENV !== "production") {
console.log("useCredentials fetched credentials", {
type,
workflowId,
credentialCount: Array.isArray(response) ? response.length : undefined,
});
}

Copilot uses AI. Check for mistakes.
Comment on lines 20 to +22
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

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

After switching node configs to use the credential type google_oauth, this hook still treats Google OAuth as type === "google" (see the authUrl logic later in this hook). As a result, the Google OAuth redirect URL won’t be set for google_oauth. Update the type check(s) to use the new credential type (or standardize the type string across the app).

Copilot uses AI. Check for mistakes.
// Backend should ONLY return stored credentials
if (Array.isArray(response)) {
setCred(response);
Expand Down
14 changes: 10 additions & 4 deletions apps/web/app/lib/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ import { getCredentials } from "../workflow/lib/config";
export const api = {
user: {
get: async () => {
return await axios.get(`${BACKEND_URL}/user/workflows`,
return await axios.get(`${BACKEND_URL}/user/workflows`,
{
withCredentials: true,
headers: { "Content-Type": "application/json" },
})
withCredentials: true,
headers: { "Content-Type": "application/json" },
})
}
},
workflows: {
Expand All @@ -38,6 +38,12 @@ export const api = {
withCredentials: true,
headers: { "Content-Type": "application/json" },
})
},
execute: async (data: any) => {
return await axios.post(`${BACKEND_URL}/user/executeWorkflow`, data, {
withCredentials: true,
headers: { "Content-Type": "application/json" },
})
Comment on lines +42 to +46
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

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

execute currently accepts data: any, which bypasses the shared Zod contract you introduced (ExecuteWorkflow). Consider typing this parameter (e.g., with z.infer<typeof ExecuteWorkflow>) to catch payload shape issues at compile time.

Copilot uses AI. Check for mistakes.
}
},
triggers: {
Expand Down
2 changes: 1 addition & 1 deletion apps/web/app/lib/nodeConfigs/gmail.action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export const gmailActionConfig: NodeConfig = {
label: "Gmail", // ✅ Clean name
icon: "📧", // ✅ Email icon
description: "Send emails via Gmail",
credentials: "google",
credentials: "google_oauth",

fields: [
{
Expand Down
2 changes: 1 addition & 1 deletion apps/web/app/login/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ const Page = () => {
}
if(result?.ok){
toast.success("Login successful!")
router.push('/workflow')
router.push('/workflows')
}
} catch(e) {
setError({...newErrors, auth:"Login failed. Please try again"})
Expand Down
2 changes: 1 addition & 1 deletion apps/web/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export default async function Home() {
) : (
<>
<p>Status: Not authenticated</p>
<form action="/api/auth/signin" method="post">
<form action="/login" method="post">
Copy link

Copilot AI Jan 27, 2026

Choose a reason for hiding this comment

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

This form posts to /login, but /login is a page route and won’t handle POST requests in Next.js (likely results in 405). Use a normal link/navigation (e.g., anchor/Link) or change to a GET navigation instead of POST.

Copilot uses AI. Check for mistakes.
<button
type="submit"
className="px-4 py-2 mt-4 bg-green-500 text-white rounded"
Expand Down
3 changes: 3 additions & 0 deletions apps/web/app/workflows/[id]/components/ConfigModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,9 @@ export default function ConfigModal({
>
{loading ? "Saving..." : "Save"}
</button>



</div>
</div>
</div>
Expand Down
Loading