From bf47ffe5b692b6bb4e327dc34fdae3866d7cbaa9 Mon Sep 17 00:00:00 2001 From: Vamsi_0 Date: Tue, 27 Jan 2026 17:00:08 +0530 Subject: [PATCH 1/3] fix: improve logging and update form actions for better clarity - Added console logs in various components to enhance debugging and traceability. - Updated form action in the login page to redirect to '/workflows' for consistency. - Refactored position handling in workflow nodes to ensure proper data structure. - Changed credential references in node configurations to 'google_oauth' for clarity. - Cleaned up commented-out code and improved error handling in user routes. --- apps/hooks/src/index.ts | 1 + .../src/routes/google_callback.ts | 1 + .../src/routes/userRoutes/userRoutes.ts | 17 ++++--- .../components/ui/Design/WorkflowButton.tsx | 8 +++- apps/web/app/hooks/useCredential.ts | 3 +- apps/web/app/lib/nodeConfigs/gmail.action.ts | 2 +- .../app/lib/nodeConfigs/googleSheet.action.ts | 2 +- apps/web/app/login/page.tsx | 2 +- apps/web/app/page.tsx | 2 +- apps/web/app/workflow/lib/config.ts | 5 ++- .../workflows/[id]/components/ConfigModal.tsx | 18 ++++++++ apps/web/app/workflows/[id]/page.tsx | 45 +++++++++++++------ apps/web/app/workflows/page.tsx | 25 ++++++++++- packages/common/src/index.ts | 4 ++ .../nodes/src/common/google-oauth-service.ts | 3 +- 15 files changed, 107 insertions(+), 31 deletions(-) diff --git a/apps/hooks/src/index.ts b/apps/hooks/src/index.ts index 6d09c48..31ccc2c 100644 --- a/apps/hooks/src/index.ts +++ b/apps/hooks/src/index.ts @@ -53,3 +53,4 @@ app.post("/hooks/catch/:userId/:workflowId", async (req, res) => { app.listen(3003, () => { console.log("Server running on 3003"); }); + \ No newline at end of file diff --git a/apps/http-backend/src/routes/google_callback.ts b/apps/http-backend/src/routes/google_callback.ts index 82d06d6..2b1e9ba 100644 --- a/apps/http-backend/src/routes/google_callback.ts +++ b/apps/http-backend/src/routes/google_callback.ts @@ -72,6 +72,7 @@ googleAuth.get( "/callback", userMiddleware, async (req: Request, res: Response) => { + console.log("Request recieved to the callback from fronted ") const code = req.query.code; const state = req.query.state; const Oauth = new GoogleOAuthService(); diff --git a/apps/http-backend/src/routes/userRoutes/userRoutes.ts b/apps/http-backend/src/routes/userRoutes/userRoutes.ts index 490bf4d..96af688 100644 --- a/apps/http-backend/src/routes/userRoutes/userRoutes.ts +++ b/apps/http-backend/src/routes/userRoutes/userRoutes.ts @@ -140,7 +140,7 @@ 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", @@ -148,7 +148,8 @@ router.get( } 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) + // console.log(userId, " -userid"); if (!type || !userId) { return res.status(statusCodes.BAD_REQUEST).json({ @@ -182,8 +183,6 @@ router.get( if (credentials.length === 0) { return res.status(200).json({ message: "No credentials found", - data: [], // always array - hasCredentials: false, }); } @@ -278,9 +277,9 @@ router.post( error: e instanceof Error ? e.message : "Unknown error" }); } - } + } + - ); // ------------------------------------ FETCHING WORKFLOWS ----------------------------------- @@ -519,13 +518,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) 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, }, }); diff --git a/apps/web/app/components/ui/Design/WorkflowButton.tsx b/apps/web/app/components/ui/Design/WorkflowButton.tsx index d431ff9..e03c008 100644 --- a/apps/web/app/components/ui/Design/WorkflowButton.tsx +++ b/apps/web/app/components/ui/Design/WorkflowButton.tsx @@ -9,7 +9,13 @@ export default function ParentComponent() { return (
- + {/* The Modal is conditionally rendered here */} {isOpen && setIsOpen(false)} />} diff --git a/apps/web/app/hooks/useCredential.ts b/apps/web/app/hooks/useCredential.ts index 2abea42..4faddc2 100644 --- a/apps/web/app/hooks/useCredential.ts +++ b/apps/web/app/hooks/useCredential.ts @@ -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) // Backend should ONLY return stored credentials if (Array.isArray(response)) { setCred(response); diff --git a/apps/web/app/lib/nodeConfigs/gmail.action.ts b/apps/web/app/lib/nodeConfigs/gmail.action.ts index bb6df74..57c37a2 100644 --- a/apps/web/app/lib/nodeConfigs/gmail.action.ts +++ b/apps/web/app/lib/nodeConfigs/gmail.action.ts @@ -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: [ { diff --git a/apps/web/app/lib/nodeConfigs/googleSheet.action.ts b/apps/web/app/lib/nodeConfigs/googleSheet.action.ts index b950ca9..a6cb0da 100644 --- a/apps/web/app/lib/nodeConfigs/googleSheet.action.ts +++ b/apps/web/app/lib/nodeConfigs/googleSheet.action.ts @@ -6,7 +6,7 @@ export const googleSheetActionConfig: NodeConfig = { label: "Google Sheet", icon: "📊", description: "Read or write data to Google Sheets", - credentials: "google", // Requires Google OAuth + credentials: "google_oauth", // Requires Google OAuth fields: [ { diff --git a/apps/web/app/login/page.tsx b/apps/web/app/login/page.tsx index 2379ed7..5ebc250 100644 --- a/apps/web/app/login/page.tsx +++ b/apps/web/app/login/page.tsx @@ -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"}) diff --git a/apps/web/app/page.tsx b/apps/web/app/page.tsx index fd1b77a..ad4b7d6 100644 --- a/apps/web/app/page.tsx +++ b/apps/web/app/page.tsx @@ -31,7 +31,7 @@ export default async function Home() { ) : ( <>

Status: Not authenticated

-
+ + + +
diff --git a/apps/web/app/workflows/[id]/page.tsx b/apps/web/app/workflows/[id]/page.tsx index 683be30..d7e31a7 100644 --- a/apps/web/app/workflows/[id]/page.tsx +++ b/apps/web/app/workflows/[id]/page.tsx @@ -46,11 +46,12 @@ export default function WorkflowCanvas() { const [configOpen, setConfigOpen] = useState(false); const [selectedNode, setSelectedNode] = useState(null); const [error, setError] = useState(null); - + const [loading, setLoading] = useState("") const nodeTypes = { customNode: BaseNode, }; + // Safe default position - reused everywhere below const DEFAULT_TRIGGER_POSITION = { x: 250, y: 50 }; const DEFAULT_ACTION_POSITION = { x: 500, y: 200 }; @@ -62,7 +63,7 @@ export default function WorkflowCanvas() { } return pos; } - + console.log("The Detaisl of Selected Node is ", selectedNode) useEffect(() => { const loadWorkflows = async () => { try { @@ -72,6 +73,7 @@ export default function WorkflowCanvas() { const dbNodes = Array.isArray(workflows?.data?.Data?.nodes) ? workflows.data.Data.nodes : []; + console.log("the node data is", dbNodes) const dbEdges = Array.isArray(workflows?.data?.Data?.Edges) ? workflows.data.Data.Edges : []; @@ -100,6 +102,7 @@ export default function WorkflowCanvas() { onConfigure: () => handleNodeConfigure({ id: Trigger.id, + name: Trigger.name }), }, }; @@ -119,7 +122,7 @@ export default function WorkflowCanvas() { onConfigure: () => handleNodeConfigure({ id: node.id, - name: node.data?.label || node.Name, + name: node.data?.label || node.name, type: "action", actionType: node.AvailableNodeId, }), @@ -249,7 +252,6 @@ export default function WorkflowCanvas() { return; } - let cuont = 0; // Calculate next available action node index (excluding placeholders) const currentActionNodes = nodes.filter( (n) => n.data.nodeType === "action" && !n.data.isPlaceholder @@ -274,9 +276,9 @@ export default function WorkflowCanvas() { }, WorkflowId: workflowId, position: newNodePosition, - stage: cuont, + stage: nextIndex, }); - + console.log("The data of Node Positions from 201", newNodePosition) const actionId = result.data.data.id; const newNode = { @@ -451,6 +453,7 @@ export default function WorkflowCanvas() { ); } }; + console.log("THis log from page.tsx about the nodeConfig", selectedNode) return (
@@ -505,13 +508,27 @@ export default function WorkflowCanvas() { > - + + +
+ + +
{ try { const triggerNode = nodes.find( @@ -560,6 +578,7 @@ export default function WorkflowCanvas() { } }} /> + setTriggerOpen(false)} diff --git a/apps/web/app/workflows/page.tsx b/apps/web/app/workflows/page.tsx index fcae037..ed99f14 100644 --- a/apps/web/app/workflows/page.tsx +++ b/apps/web/app/workflows/page.tsx @@ -13,6 +13,7 @@ import { } from "@workspace/ui/components/card" import { Button } from "@workspace/ui/components/button" import { useRouter } from "next/navigation"; +import ParentComponent from "../components/ui/Design/WorkflowButton"; // Removed: import { Router } from "next/router"; export const UserWorkflows = () => { @@ -76,8 +77,21 @@ export const UserWorkflows = () => { )} -
-                                    {JSON.stringify(workflow.config || workflow.Config, null, 2)}
+                                
+                                    {(() => {
+                                        const config = workflow.config ?? workflow.Config;
+                                        if (
+                                            config == null ||
+                                            (typeof config === 'object' &&
+                                                !Array.isArray(config) &&
+                                                Object.keys(config).length === 0
+                                            ) ||
+                                            (Array.isArray(config) && config.length === 0)
+                                        ) {
+                                            return "Not Configured";
+                                        }
+                                        return JSON.stringify(config, null, 2);
+                                    })()}
                                 
@@ -95,6 +109,13 @@ export const UserWorkflows = () => { ))}
)} + +
+
+ +
+
+ ); }; diff --git a/packages/common/src/index.ts b/packages/common/src/index.ts index 18231bd..c8f5977 100644 --- a/packages/common/src/index.ts +++ b/packages/common/src/index.ts @@ -31,6 +31,10 @@ export const NodeSchema = z.object({ Config: z.any().optional(), stage: z.number().optional(), WorkflowId: z.string(), + position : z.object({ + x : z.number() , + y : z.number() + }) }); export const NodeUpdateSchema = z.object({ diff --git a/packages/nodes/src/common/google-oauth-service.ts b/packages/nodes/src/common/google-oauth-service.ts index 6eeffd1..dec8e01 100644 --- a/packages/nodes/src/common/google-oauth-service.ts +++ b/packages/nodes/src/common/google-oauth-service.ts @@ -66,7 +66,7 @@ class GoogleOAuthService { try { // const credentialId = `cred_google_${userId}_${Date.now()}` - await this.prisma.credential.create({ + const Data = await this.prisma.credential.create({ data: { // id:credentialId, userId: userId, @@ -75,6 +75,7 @@ class GoogleOAuthService { nodeId: nodeId || null, }, }); + console.log("THis log is writing to see if google auth tokens is storing to db or not ",Data) } catch (error) { throw new Error( `failed to store data in Credentials: ${error instanceof Error ? error.message : "Unknown Error"}` From ff14ee40863bf573a99842b9638e5a0eb2535501 Mon Sep 17 00:00:00 2001 From: Vamsi_0 Date: Tue, 27 Jan 2026 18:47:35 +0530 Subject: [PATCH 2/3] feat: implement executeWorkflow endpoint and enhance logging - Added a new endpoint for executing workflows, which validates user authorization and trigger data. - Improved logging for better traceability in the hooks backend and user routes. - Updated API integration in the frontend to support workflow execution. - Cleaned up code and ensured consistent formatting across various files. --- apps/hooks/src/index.ts | 13 ++-- .../src/routes/userRoutes/userRoutes.ts | 59 ++++++++++++++++++- apps/web/app/lib/api.ts | 14 +++-- .../workflows/[id]/components/ConfigModal.tsx | 13 ---- apps/web/app/workflows/[id]/page.tsx | 18 +++++- apps/web/store/slices/userSlice.ts | 2 +- packages/common/src/index.ts | 5 +- 7 files changed, 97 insertions(+), 27 deletions(-) diff --git a/apps/hooks/src/index.ts b/apps/hooks/src/index.ts index 31ccc2c..b020e9f 100644 --- a/apps/hooks/src/index.ts +++ b/apps/hooks/src/index.ts @@ -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") const { userId, workflowId } = req.params; const { triggerData } = req.body; @@ -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, }, @@ -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" }); } }); @@ -53,4 +55,3 @@ app.post("/hooks/catch/:userId/:workflowId", async (req, res) => { app.listen(3003, () => { console.log("Server running on 3003"); }); - \ No newline at end of file diff --git a/apps/http-backend/src/routes/userRoutes/userRoutes.ts b/apps/http-backend/src/routes/userRoutes/userRoutes.ts index 96af688..f6a1adc 100644 --- a/apps/http-backend/src/routes/userRoutes/userRoutes.ts +++ b/apps/http-backend/src/routes/userRoutes/userRoutes.ts @@ -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"; const router: Router = Router(); router.post("/createAvaliableNode", async (req: AuthRequest, res: Response) => { @@ -148,7 +151,7 @@ router.get( } const userId = req.user.sub; const type = req.params.type; - console.log("The type of data comming to backed is ",type) + console.log("The type of data comming to backed is ", type) // console.log(userId, " -userid"); if (!type || !userId) { @@ -629,6 +632,60 @@ router.put( } ); +router.post("/executeWorkflow", userMiddleware, async (req: AuthRequest, res) => { + console.log("REcieved REquest to the execute route ") + const Data = req.body + 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 + }) + } + 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 + } + }) + console.log("This is the Trigger Name of the workflow", trigger?.Trigger?.name) + console.log("This is the Trigger Data of the workflow", trigger) + + if (trigger?.Trigger?.name === "webhook") { + const data = await axios.post(`${HOOKS_URL}/hooks/catch/${userId}/${workflowId}`, { + triggerData: "" + }) + console.log("Workflow Execution for webhook started with Execution Id is ", data.data.workflowExecutionId) + 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 + }) + } + +}) router.get("/protected", userMiddleware, (req: AuthRequest, res) => { return res.json({ ok: true, diff --git a/apps/web/app/lib/api.ts b/apps/web/app/lib/api.ts index 0953af7..dc7f9ba 100644 --- a/apps/web/app/lib/api.ts +++ b/apps/web/app/lib/api.ts @@ -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: { @@ -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" }, + }) } }, triggers: { diff --git a/apps/web/app/workflows/[id]/components/ConfigModal.tsx b/apps/web/app/workflows/[id]/components/ConfigModal.tsx index 8f1fec2..ac71c88 100644 --- a/apps/web/app/workflows/[id]/components/ConfigModal.tsx +++ b/apps/web/app/workflows/[id]/components/ConfigModal.tsx @@ -53,20 +53,7 @@ export default function ConfigModal({ onClose(); } }; - const handleExecute = async () => { - setLoading(true); - try { - // await api.workflows.po - } - catch (error: any) { - toast.error("Failed to save config"); - } - finally { - setLoading(false); - onClose(); - } - } const renderField = (field: any) => { const fieldValue = config[field.name] || ""; diff --git a/apps/web/app/workflows/[id]/page.tsx b/apps/web/app/workflows/[id]/page.tsx index d7e31a7..c2c2327 100644 --- a/apps/web/app/workflows/[id]/page.tsx +++ b/apps/web/app/workflows/[id]/page.tsx @@ -19,12 +19,28 @@ import { TriggerSideBar } from "@/app/components/nodes/TriggerSidebar"; import ActionSideBar from "@/app/components/Actions/ActionSidebar"; import { api } from "@/app/lib/api"; import ConfigModal from "./components/ConfigModal"; +import { toast } from "sonner"; export default function WorkflowCanvas() { const params = useParams(); const workflowId = params.id as string; // State + const handleExecute = async () => { + setLoading(true); + try { + const data = await api.workflows.execute({workflowId}) + console.log("This is from the Execute Button", data) + toast.success("Execution Started") + } + catch (error: any) { + toast.error("Failed to save config"); + + } + finally { + setLoading(false); + } + } const [nodes, setNodes, onNodesChange] = useNodesState([ { id: "trigger-placeholder", @@ -519,7 +535,7 @@ export default function WorkflowCanvas() {