diff --git a/apps/hooks/src/index.ts b/apps/hooks/src/index.ts
index 6d09c48..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"
});
}
});
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..44d7d18 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) => {
@@ -140,7 +143,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 +151,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 +186,6 @@ router.get(
if (credentials.length === 0) {
return res.status(200).json({
message: "No credentials found",
- data: [], // always array
- hasCredentials: false,
});
}
@@ -278,9 +280,9 @@ router.post(
error: e instanceof Error ? e.message : "Unknown error"
});
}
- }
+ }
+
-
);
// ------------------------------------ FETCHING WORKFLOWS -----------------------------------
@@ -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)
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,
},
});
@@ -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
+ 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
+ }
+ })
+ 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)
+
+ 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"
+ })
+ }
+
+})
router.get("/protected", userMiddleware, (req: AuthRequest, res) => {
return res.json({
ok: true,
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/api.ts b/apps/web/app/lib/api.ts
index ade5c0f..cfe242c 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/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/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..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",
@@ -46,11 +62,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 +79,7 @@ export default function WorkflowCanvas() {
}
return pos;
}
-
+ console.log("The Detaisl of Selected Node is ", selectedNode)
useEffect(() => {
const loadWorkflows = async () => {
try {
@@ -72,6 +89,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 +118,7 @@ export default function WorkflowCanvas() {
onConfigure: () =>
handleNodeConfigure({
id: Trigger.id,
+ name: Trigger.name
}),
},
};
@@ -119,7 +138,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 +268,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 +292,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 +469,7 @@ export default function WorkflowCanvas() {
);
}
};
+ console.log("THis log from page.tsx about the nodeConfig", selectedNode)
return (
@@ -505,13 +524,27 @@ export default function WorkflowCanvas() {
>
-
+
+
+
+
+
+
{
try {
const triggerNode = nodes.find(
@@ -560,6 +594,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/apps/web/store/slices/userSlice.ts b/apps/web/store/slices/userSlice.ts
index 9e5d51b..93162b3 100644
--- a/apps/web/store/slices/userSlice.ts
+++ b/apps/web/store/slices/userSlice.ts
@@ -19,7 +19,7 @@ const userSlice = createSlice({
name: 'user',
initialState,
reducers:{
- setUserId(state, action: PayloadAction){
+setUserId(state, action: PayloadAction){
state.userId = action.payload;
},
setUserStatus(state, action: PayloadAction){
diff --git a/packages/common/src/index.ts b/packages/common/src/index.ts
index 18231bd..f59ab28 100644
--- a/packages/common/src/index.ts
+++ b/packages/common/src/index.ts
@@ -2,7 +2,7 @@ import z from "zod";
import { number } from "zod/v4";
export const BACKEND_URL = "http://localhost:3002";
-export const HOOKS_URL = "http://localhost:3002";
+export const HOOKS_URL = "http://localhost:3003";
export const AvailableTriggers = z.object({
Name: z.string(),
AvailableTriggerID: z.string().optional(),
@@ -31,8 +31,15 @@ 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 ExecuteWorkflow = z.object({
+ workflowId : z.string(),
+})
export const NodeUpdateSchema = z.object({
NodeId: z.string(),
Config: z.any().optional(),
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"}`