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
146 changes: 67 additions & 79 deletions apps/http-backend/src/routes/userRoutes/userRoutes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
NodeSchema,
NodeUpdateSchema,
TriggerUpdateSchema,
workflowUpdateSchema,
} from "@repo/common/zod";
import { GoogleSheetsNodeExecutor } from "@repo/nodes";
const router: Router = Router();
Expand Down Expand Up @@ -133,56 +134,6 @@ router.get(
}
);

// //------------------------------ GET CREDENTIALS -----------------------------

// router.get('/getCredentials/:type',
// userMiddleware,
// async (req: AuthRequest, res) =>{
// try{
// 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")
// if(!type || !userId){
// return res.status(statusCodes.BAD_REQUEST).json({
// message: "Incorrect type Input",
// });
// }
// const executor = new GoogleSheetsNodeExecutor()
// const response = await executor.getAllCredentials(userId,type)
// // console.log( typeof(response));
// // console.log("response: ",response)
// const authUrl = typeof response === 'string' ? response : null
// // console.log(authUrl);

// const credentials = response instanceof Object ? response : null
// // console.log(credentials)
// if(authUrl){
// return res.status(statusCodes.OK).json({
// message: "Credentials not found create credentials using this auth url",
// Data: authUrl,
// });
// }
// else return res.status(statusCodes.OK).json({
// message: "Credentials Fetched succesfully",
// Data: credentials,
// });
// }
// catch(e){
// console.log("Error Fetching the credentials ", e instanceof Error ? e.message : "Unkown reason");
// return res
// .status(statusCodes.INTERNAL_SERVER_ERROR)
// .json({ message: "Internal server from fetching the credentials" });
// }
// }
// );

//------------------------------ GET CREDENTIALS -----------------------------

router.get(
"/getCredentials/:type",
Expand Down Expand Up @@ -290,31 +241,23 @@ router.post(
"/create/workflow",
userMiddleware,
async (req: AuthRequest, res) => {
try {
if (!req.user) {
return res.status(statusCodes.BAD_REQUEST).json({
message: "User is not logged in ",
});
}
const Data = req.body;
const ParsedData = WorkflowSchema.safeParse(Data);
const UserID = req.user.id;
// const UserID = "343c9a0a-9c3f-40d0-81de-9a5969e03f92";
// Ensure that the required fields are present in the parsed data and create the workflow properly.
if (!ParsedData.success) {
return res.status(statusCodes.BAD_REQUEST).json({
message: "Incorrect Workflow Inputs",
});
}

if (!req.user) {
return res.status(statusCodes.BAD_REQUEST).json({
message: "User is not logged in ",
});
}
const Data = req.body;
const ParsedData = WorkflowSchema.safeParse(Data);
const UserID = req.user.id;
// const UserID = "343c9a0a-9c3f-40d0-81de-9a5969e03f92";
// Ensure that the required fields are present in the parsed data and create the workflow properly.
if (!ParsedData.success) {
return res.status(statusCodes.BAD_REQUEST).json({
message: "Incorrect Workflow Inputs",
});
} try {
Comment on lines +244 to +259
Copy link

Copilot AI Jan 19, 2026

Choose a reason for hiding this comment

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

The try block wraps only a portion of the code, leaving the validation logic (lines 244-259) outside error handling. This creates inconsistent error handling behavior. Either move the entire function logic inside the try block or handle errors for the validation section separately.

Copilot uses AI. Check for mistakes.
const createWorkflow = await prismaClient.workflow.create({
// Example JSON body to test this route:
/*
{
"Name":"workflow-1",
"UserId": "",
"Config":[{}]
}
*/
data: {
user: {
connect: { id: UserID },
Expand All @@ -328,13 +271,16 @@ router.post(
message: "Workflow Created Successfully",
Data: createWorkflow,
});
} catch (e) {
} catch (e: any) {
console.log("Internal server error from creating aworkflow", e);
Copy link

Copilot AI Jan 19, 2026

Choose a reason for hiding this comment

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

The error message contains a spelling error: "aworkflow" should be "a workflow" (missing space).

Suggested change
console.log("Internal server error from creating aworkflow", e);
console.log("Internal server error from creating a workflow", e);

Copilot uses AI. Check for mistakes.
return res.status(statusCodes.INTERNAL_SERVER_ERROR).json({
message: "Internal Server Error from CCreating Workflow",
Copy link

Copilot AI Jan 19, 2026

Choose a reason for hiding this comment

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

The error message contains a spelling error: "CCreating" should be "Creating" (duplicate C).

Suggested change
message: "Internal Server Error from CCreating Workflow",
message: "Internal Server Error from Creating Workflow",

Copilot uses AI. Check for mistakes.
error: e instanceof Error ? e.message : "Unknown error"
});
}
}
}


);

// ------------------------------------ FETCHING WORKFLOWS -----------------------------------
Expand Down Expand Up @@ -444,10 +390,52 @@ router.get(
}
);

// router.put("/workflow/update" , userMiddleware , (req : AuthRequest , res : Response) => {
router.put("/workflow/update", userMiddleware, async (req: AuthRequest, res: Response) => {

// })
// ---------------------------------------- INSERTING DATA INTO NODES/ TRIGGER TABLE-----------------------------
const data = req.body;
const parsedData = workflowUpdateSchema.safeParse(data);

if (!parsedData.success) {
return res.status(statusCodes.BAD_REQUEST).json({
message: "Incorrect Input",
error: parsedData.error
})
}
const workflowId = parsedData.data.workflowId;
if (!req.user) {
return res.status(statusCodes.UNAUTHORIZED).json({
message: "User Not Authenticated"
})
}
const userId = req.user.id
try {
const workflowValid = await prismaClient.workflow.findFirst({
where: { id: workflowId, userId: userId }
})
if (!workflowValid) {
return res.status(statusCodes.BAD_REQUEST).json({
message: "Didn't find the workflow"
})
}
const update = await prismaClient.workflow.update({
where: { id: workflowId, userId: userId },
data: {
// Nodes: parsedData.data.nodes,
Copy link

Copilot AI Jan 19, 2026

Choose a reason for hiding this comment

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

The commented-out code line 423 should be either uncommented if needed or removed. Since this is inside a working update endpoint that only updates Edges, leaving this commented suggests incomplete functionality - the nodes data being sent from the frontend is not being persisted to the database.

Suggested change
// Nodes: parsedData.data.nodes,
Nodes: parsedData.data.nodes,

Copilot uses AI. Check for mistakes.
Edges: parsedData.data.edges
}
})
Comment on lines +420 to +426
Copy link

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:

# Find workflowUpdateSchema definition
fd -t f -e ts -e js | xargs grep -l "workflowUpdateSchema" | head -20

Repository: Dev-Pross/BuildFlow

Length of output: 145


🏁 Script executed:

# Check the imports and full context of userRoutes.ts around line 420
cat -n apps/http-backend/src/routes/userRoutes/userRoutes.ts | sed -n '1,30p'

Repository: Dev-Pross/BuildFlow

Length of output: 1245


🏁 Script executed:

# Look for Prisma schema to understand Workflow model structure
fd schema.prisma

Repository: Dev-Pross/BuildFlow

Length of output: 95


🏁 Script executed:

# Check frontend code reference
test -f apps/web/app/workflows/[id]/page.tsx && cat -n apps/web/app/workflows/[id]/page.tsx | sed -n '610,630p' || echo "File not found at expected path"

Repository: Dev-Pross/BuildFlow

Length of output: 767


🏁 Script executed:

# Find workflowUpdateSchema definition in common package
fd -t f -e ts -e js packages/common | xargs grep -A 10 "workflowUpdateSchema" | head -50

Repository: Dev-Pross/BuildFlow

Length of output: 428


🏁 Script executed:

# Read the Prisma schema to understand Workflow model
cat -n packages/db/prisma/schema.prisma | grep -A 30 "model Workflow"

Repository: Dev-Pross/BuildFlow

Length of output: 2532


🏁 Script executed:

# Get more context on workflowUpdateSchema - check full definition
rg "workflowUpdateSchema.*=" packages/common -A 15

Repository: Dev-Pross/BuildFlow

Length of output: 869


🏁 Script executed:

# Get the full context of the workflow update route (lines 393-438)
cat -n apps/http-backend/src/routes/userRoutes/userRoutes.ts | sed -n '393,440p'

Repository: Dev-Pross/BuildFlow

Length of output: 1844


🏁 Script executed:

# Check if there's a separate node update endpoint or how nodes are meant to be updated
rg "prismaClient.node" apps/http-backend/src/routes/userRoutes/userRoutes.ts -A 5 -B 2

Repository: Dev-Pross/BuildFlow

Length of output: 647


🏁 Script executed:

# Look at the Node model in Prisma schema
cat -n packages/db/prisma/schema.prisma | grep -A 20 "^model Node"

Repository: Dev-Pross/BuildFlow

Length of output: 45


🏁 Script executed:

# Find the Node model definition in the Prisma schema
rg "^model Node" packages/db/prisma/schema.prisma -A 20

Repository: Dev-Pross/BuildFlow

Length of output: 2174


🏁 Script executed:

# Check if there's a separate endpoint for updating nodes
rg "router.put.*node\|router.patch.*node" apps/http-backend/src/routes/userRoutes/userRoutes.ts -i

Repository: Dev-Pross/BuildFlow

Length of output: 45


🏁 Script executed:

# Look for how nodes are persisted - check for any node update logic in the workflow update or elsewhere
rg "updateMany.*node\|createMany.*node" apps/http-backend/src/routes/userRoutes/ -i

Repository: Dev-Pross/BuildFlow

Length of output: 45


🏁 Script executed:

# Look at the workflow create endpoint to see how nodes are handled there
cat -n apps/http-backend/src/routes/userRoutes/userRoutes.ts | sed -n '244,290p'

Repository: Dev-Pross/BuildFlow

Length of output: 1892


🏁 Script executed:

# Check if there's a workflow creation logic that handles nodes
rg "prismaClient.node.create\|prismaClient.node.updateMany" apps/http-backend/src/routes/userRoutes/userRoutes.ts -B 5 -A 10

Repository: Dev-Pross/BuildFlow

Length of output: 45


🏁 Script executed:

# Look for any workflow-related route that might handle node updates
rg "router\.(post|put|patch)" apps/http-backend/src/routes/userRoutes/userRoutes.ts | grep -i "node\|workflow"

Repository: Dev-Pross/BuildFlow

Length of output: 235


🏁 Script executed:

# Check how nodes are actually created - look for the node creation logic when a workflow is created
rg "prismaClient.node.create" apps/http-backend/src/routes/userRoutes/userRoutes.ts -B 10 -A 5

Repository: Dev-Pross/BuildFlow

Length of output: 796


🏁 Script executed:

# Look for any endpoint that handles node creation in bulk
rg "createMany\|updateMany" apps/http-backend/src/routes/userRoutes/userRoutes.ts -B 5 -A 5

Repository: Dev-Pross/BuildFlow

Length of output: 45


🏁 Script executed:

# Check all endpoints in userRoutes to see if there's a separate node update mechanism
rg "^router\.(post|put|patch|delete)" apps/http-backend/src/routes/userRoutes/userRoutes.ts | head -30

Repository: Dev-Pross/BuildFlow

Length of output: 311


🏁 Script executed:

# Let me check what the complete workflow update route does and if there's any node handling elsewhere
cat -n apps/http-backend/src/routes/userRoutes/userRoutes.ts | sed -n '393,450p'

Repository: Dev-Pross/BuildFlow

Length of output: 2185


🏁 Script executed:

# Check if there's any documentation or comments about the intended behavior
rg "workflow.*update\|update.*workflow" apps/http-backend/src/routes/userRoutes/userRoutes.ts -i -B 3 -A 3

Repository: Dev-Pross/BuildFlow

Length of output: 45


🏁 Script executed:

# Look at the workspace - see if there's another file handling node updates
fd -t f -e ts "routes" apps/http-backend/src | head -20

Repository: Dev-Pross/BuildFlow

Length of output: 161


🏁 Script executed:

# Check the nodes.routes.ts file to understand node update logic
cat -n apps/http-backend/src/routes/nodes.routes.ts

Repository: Dev-Pross/BuildFlow

Length of output: 4017


🏁 Script executed:

# Also check how the frontend handles node updates - are they sent separately?
rg "api.nodes\|api.workflows" apps/web/app/workflows/[id]/page.tsx -B 2 -A 5

Repository: Dev-Pross/BuildFlow

Length of output: 45


🏁 Script executed:

# Search for API endpoints in the web app - check the api client implementation
fd -t f -e ts -e js "api" apps/web | grep -E "(client|api)" | head -20

Repository: Dev-Pross/BuildFlow

Length of output: 86


🏁 Script executed:

# Look for workflow update API calls in the web app
rg "workflows.put\|api.put.*workflow" apps/web -B 3 -A 5

Repository: Dev-Pross/BuildFlow

Length of output: 45


🏁 Script executed:

# Check if nodes are being updated separately through a different endpoint
rg "nodes.put\|nodes.update\|api.put.*node" apps/web -B 3 -A 5

Repository: Dev-Pross/BuildFlow

Length of output: 45


🏁 Script executed:

# Check the API client implementation
cat -n apps/web/app/lib/api.ts

Repository: Dev-Pross/BuildFlow

Length of output: 3532


🏁 Script executed:

# Look at the entire handleSave function to understand the full flow
cat -n apps/web/app/workflows/[id]/page.tsx | sed -n '615,650p'

Repository: Dev-Pross/BuildFlow

Length of output: 1356


Nodes in the update payload are being ignored and not persisted.

The workflowUpdateSchema accepts nodes, and the frontend sends them (lines 618-627 in the page component), but the workflow update route only saves Edges while the Nodes field remains commented out (line 423).

The current Prisma schema stores nodes as separate Node records with a workflowId relation, not as a JSON field on Workflow. If nodes are sent in this update request, they should either be:

  1. Persisted by updating individual Node records in the database, or
  2. Removed from the payload if nodes are managed through a separate endpoint (/update/node)

Without handling the nodes data, any node updates from the UI are lost.

🤖 Prompt for AI Agents
In `@apps/http-backend/src/routes/userRoutes/userRoutes.ts` around lines 420 -
426, The update handler currently calls prismaClient.workflow.update and only
saves Edges while Nodes are ignored; either persist incoming nodes or remove
them from the payload. To fix, inspect parsedData.data.nodes in the same route
handling the workflow update (or validate via workflowUpdateSchema) and choose
one: (A) Persist nodes by using the Node model with the workflowId—e.g., delete
or upsert existing Node records for the given workflowId and bulk create/update
from parsedData.data.nodes after prismaClient.workflow.update, referencing
prismaClient.node and workflowId/Nodes; or (B) strip nodes from the update
payload and route node changes to the existing /update/node endpoint instead,
returning a clear response indicating nodes must be updated via that endpoint.
Ensure you reference prismaClient.workflow.update, parsedData.data.nodes,
prismaClient.node, and the /update/node route when implementing the chosen
approach.

return res.status(statusCodes.ACCEPTED).json({
message: "Workflow Updated Succesfuly",
Copy link

Copilot AI Jan 19, 2026

Choose a reason for hiding this comment

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

The success message contains a spelling error: "Succesfuly" should be "Successfully".

Suggested change
message: "Workflow Updated Succesfuly",
message: "Workflow Updated Successfully",

Copilot uses AI. Check for mistakes.
Data: update
})
} catch (error: any) {
console.log("Error updating workflow:", error);
return res.status(statusCodes.INTERNAL_SERVER_ERROR).json({
message: "Internal Server Error from Updating workflow",
error: error instanceof Error ? error.message : "Unknown error"
})
}
})
Comment on lines +401 to +438
Copy link

Copilot AI Jan 19, 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 script have an explicit semicolon).

Suggested change
error: parsedData.error
})
}
const workflowId = parsedData.data.workflowId;
if (!req.user) {
return res.status(statusCodes.UNAUTHORIZED).json({
message: "User Not Authenticated"
})
}
const userId = req.user.id
try {
const workflowValid = await prismaClient.workflow.findFirst({
where: { id: workflowId, userId: userId }
})
if (!workflowValid) {
return res.status(statusCodes.BAD_REQUEST).json({
message: "Didn't find the workflow"
})
}
const update = await prismaClient.workflow.update({
where: { id: workflowId, userId: userId },
data: {
// Nodes: parsedData.data.nodes,
Edges: parsedData.data.edges
}
})
return res.status(statusCodes.ACCEPTED).json({
message: "Workflow Updated Succesfuly",
Data: update
})
} catch (error: any) {
console.log("Error updating workflow:", error);
return res.status(statusCodes.INTERNAL_SERVER_ERROR).json({
message: "Internal Server Error from Updating workflow",
error: error instanceof Error ? error.message : "Unknown error"
})
}
})
error: parsedData.error,
});
}
const workflowId = parsedData.data.workflowId;
if (!req.user) {
return res.status(statusCodes.UNAUTHORIZED).json({
message: "User Not Authenticated",
});
}
const userId = req.user.id;
try {
const workflowValid = await prismaClient.workflow.findFirst({
where: { id: workflowId, userId: userId },
});
if (!workflowValid) {
return res.status(statusCodes.BAD_REQUEST).json({
message: "Didn't find the workflow",
});
}
const update = await prismaClient.workflow.update({
where: { id: workflowId, userId: userId },
data: {
// Nodes: parsedData.data.nodes,
Edges: parsedData.data.edges,
},
});
return res.status(statusCodes.ACCEPTED).json({
message: "Workflow Updated Succesfuly",
Data: update,
});
} catch (error: any) {
console.log("Error updating workflow:", error);
return res.status(statusCodes.INTERNAL_SERVER_ERROR).json({
message: "Internal Server Error from Updating workflow",
error: error instanceof Error ? error.message : "Unknown error",
});
}
});

Copilot uses AI. Check for mistakes.

router.post(
"/create/trigger",
Expand Down
17 changes: 13 additions & 4 deletions apps/web/app/lib/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,20 @@ export const api = {
headers: { "Content-Type": "application/json" },
}
),
get: async (id: string) =>
await axios.get(`${BACKEND_URL}/user/workflow/${id}`, {
get: async (id: string) => {
return await axios.get(`${BACKEND_URL}/user/workflow/${id}`, {
withCredentials: true,
headers: { "Content-Type": "application/json" },
}),
});
},
put: async (data: any) => {
return await axios.put(`${BACKEND_URL}/user/workflow/update`,
data,
{
withCredentials: true,
headers: { "Content-Type": "application/json" },
})
}
},
triggers: {
getAvailable: async () =>
Expand Down Expand Up @@ -59,7 +68,7 @@ export const api = {
},
Credentials: {
getCredentials: async (type: string) => {
const res = await axios.get(`${BACKEND_URL}/user/getCredentials/${type}`, {
const res = await axios.get(`${BACKEND_URL}/user/getCredentials/${type}`, {
withCredentials: true,
headers: { "Content-Type": "application/json" },
});
Expand Down
Loading
Loading