Conversation
- 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.
- 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.
…w endpoint - Added validation to check if the workflow trigger exists and is authorized, returning a 404 status if not. - Improved error handling for workflow execution failures, returning a 500 status with a clear message. - Updated logging to provide more informative output regarding workflow execution status.
📝 WalkthroughWalkthroughIntroduces workflow execution via webhook-based triggers with endpoint validation and authorization checks. Updates node positioning schemas, enhances credential handling for Google OAuth, refines UI components for workflow management, and adds diagnostic logging across multiple services. Changes
Sequence DiagramsequenceDiagram
participant Client as Frontend Client
participant Backend as HTTP Backend
participant HooksService as Hooks Service
participant DB as Database
Client->>Backend: POST /user/executeWorkflow (workflowId, auth)
Backend->>DB: Query workflow by ID
DB-->>Backend: Workflow data
Backend->>Backend: Validate user authorization
alt Authorized
Backend->>HooksService: POST to HOOKS_URL (trigger webhook)
HooksService-->>Backend: Webhook received
Backend-->>Client: Success response (200)
Client->>Client: Show success toast
else Not Authorized
Backend-->>Client: Error 403/404
Client->>Client: Show error toast
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~75 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 1 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 7
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
packages/nodes/src/common/google-oauth-service.ts (1)
69-78: Remove debug logging and fix variable naming.Two issues here:
Naming convention:
Datashould bedata(camelCase) per JavaScript/TypeScript conventions.Security concern: Logging the full credential object exposes sensitive OAuth tokens (access_token, refresh_token) in logs. This debug statement should be removed before merging, or at minimum sanitized to avoid leaking secrets.
🔒 Suggested fix
- const Data = await this.prisma.credential.create({ + const data = await this.prisma.credential.create({ data: { // id:credentialId, userId: userId, type: "google_oauth", config: JSON.parse(JSON.stringify(tokens)), nodeId: nodeId || null, }, }); - console.log("THis log is writing to see if google auth tokens is storing to db or not ",Data) + console.log(`✅ Google OAuth credentials stored for user ${userId}`);apps/http-backend/src/routes/google_callback.ts (1)
132-148: Hardcoded localhost URLs will break in deployed environments.The redirect URLs are hardcoded to
http://localhost:3000, which won't work when the application is deployed. Consider using environment variables for the frontend URL.♻️ Suggested fix
+const FRONTEND_URL = process.env.FRONTEND_URL || "http://localhost:3000"; + // Redirect to workflow page if workflowId is provided, otherwise to general workflow page const redirectUrl = workflowId - ? `http://localhost:3000/workflows/${workflowId}` - : "http://localhost:3000/workflow"; + ? `${FRONTEND_URL}/workflows/${workflowId}` + : `${FRONTEND_URL}/workflow`; console.log(' Redirecting to:', redirectUrl); return res.redirect(redirectUrl); } catch (err: any) { // ... error handling const errorUrl = workflowId - ? `http://localhost:3000/workflows/${workflowId}?google=error&msg=${encodeURIComponent(err?.message ?? "Token exchange failed")}` - : `http://localhost:3000/workflow?google=error&msg=${encodeURIComponent(err?.message ?? "Token exchange failed")}`; + ? `${FRONTEND_URL}/workflows/${workflowId}?google=error&msg=${encodeURIComponent(err?.message ?? "Token exchange failed")}` + : `${FRONTEND_URL}/workflow?google=error&msg=${encodeURIComponent(err?.message ?? "Token exchange failed")}`;apps/web/app/page.tsx (1)
34-41: Form POST to/loginwill not work as expected.The
/loginroute is a client-side React page component, not an API endpoint that handles POST requests. Submitting a form withmethod="post"to this route will likely result in a 405 error or unexpected behavior.The previous
/api/auth/signinwas NextAuth's built-in sign-in handler. If you want to redirect users to the login page, use a link or client-side navigation instead of a form POST.🐛 Suggested fix - Use a link for navigation
<p>Status: Not authenticated</p> - <form action="/login" method="post"> - <button - type="submit" - className="px-4 py-2 mt-4 bg-green-500 text-white rounded" - > - Sign in - </button> - </form> + <a href="/login"> + <button + type="button" + className="px-4 py-2 mt-4 bg-green-500 text-white rounded" + > + Sign in + </button> + </a>Or use Next.js
Linkcomponent for client-side navigation:import Link from 'next/link'; // ... <Link href="/login"> <button className="px-4 py-2 mt-4 bg-green-500 text-white rounded"> Sign in </button> </Link>
🤖 Fix all issues with AI agents
In `@apps/hooks/src/index.ts`:
- 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).
- Around line 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.
In `@apps/http-backend/src/routes/google_callback.ts`:
- 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.
In `@apps/http-backend/src/routes/userRoutes/userRoutes.ts`:
- Around line 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.
In `@apps/web/app/workflows/`[id]/page.tsx:
- Line 65: The loading state is incorrectly initialized as a string and typed as
any; change the useState call for loading to use a boolean type and initialize
to false (e.g., useState<boolean>(false) or allow type inference) so usages like
disabled={loading} and {loading ? "Executing..." : "Execute"} are type-safe;
update references to loading and setLoading accordingly but no other logic
changes.
- Around line 29-43: The catch block in handleExecute currently shows the wrong
toast text ("Failed to save config"); update the error handling for
handleExecute so the toast.error reflects workflow execution failure (e.g.,
"Failed to start execution" or "Failed to execute workflow") and optionally log
the caught error (from the catch parameter) using console.error or include it in
the toast for easier debugging; make this change around the handleExecute
function and the api.workflows.execute call.
In `@packages/common/src/index.ts`:
- Around line 34-37: NodeSchema.position currently expects an object but
frontend sometimes sends a numeric Position or uses capitalized "Position";
update the schema in packages/common/src/index.ts to accept both shapes and be
tolerant: change NodeSchema.position to a union like z.union([z.object({x:
z.number(), y: z.number()}), z.number()]) (or z.any() temporarily) and ensure
validation accepts either key by normalizing incoming payload keys (map
"Position" -> "position") in the request parsing code that handles node creation
(refer to apps/web/app/workflow/lib/config.ts where Position is sent); this
makes the API backward-compatible while you standardize callers to send the
object-shaped position used elsewhere (e.g.,
apps/web/app/workflows/[id]/page.tsx and seed data).
🧹 Nitpick comments (11)
apps/web/app/login/page.tsx (1)
54-54: Consider removing debug log before production.The
console.log('res', result)statement appears to be a debug artifact that could leak authentication result details in the browser console.🧹 Suggested cleanup
- console.log('res',result); - if(result?.error){apps/hooks/src/index.ts (1)
29-31: Address TODO: Validate trigger data.The comment indicates that
triggerDatashould be validated before being stored in the database. Storing unvalidated external input could lead to data integrity issues or potential security vulnerabilities.Would you like me to help implement validation for
triggerDatausing a schema validator like Zod, or open an issue to track this task?apps/web/app/hooks/useCredential.ts (1)
21-22: Consider removing debug logging before production.Logging credential response data to the console could expose sensitive information in browser developer tools. This appears to be a debug artifact.
🧹 Suggested cleanup
const response = await getCredentials(type); - const data = JSON.stringify(response) - console.log("This is the log from usecredentials" , data) // Backend should ONLY return stored credentialspackages/common/src/index.ts (1)
5-5: Consider env-based hooks URL instead of hardcoded localhost.Since this shared constant is used to render user-facing webhook URLs, hardcoding
localhostrisks incorrect URLs outside local dev. Consider sourcing it from environment config (e.g., a NEXT_PUBLIC_* variable in web and a server env in backend) and wiring it through the app layer.apps/web/app/lib/api.ts (1)
42-46: Type the execute payload against the shared schema.The
executemethod'sdataparameter should be typed withz.infer<typeof ExecuteWorkflow>and validated before sending to prevent contract drift. TheExecuteWorkflowschema exists in the shared schema and matches the payload shape ({workflowId}) being sent from call sites. This pattern is already applied elsewhere in this file withTriggerUpdateSchema.♻️ Suggested update
-import { BACKEND_URL, NodeUpdateSchema } from "@repo/common/zod"; +import { BACKEND_URL, NodeUpdateSchema, ExecuteWorkflow } from "@repo/common/zod"; ... - execute: async (data: any) => { - return await axios.post(`${BACKEND_URL}/user/executeWorkflow`, data, { + execute: async (data: z.infer<typeof ExecuteWorkflow>) => { + ExecuteWorkflow.parse(data); + return await axios.post(`${BACKEND_URL}/user/executeWorkflow`, data, { withCredentials: true, headers: { "Content-Type": "application/json" }, }) }apps/web/app/workflows/[id]/page.tsx (2)
33-33: Remove debug console.log statements before merging.Multiple
console.logstatements are present throughout the file (lines 33, 82, 92, 297, 472). These should be removed or replaced with proper logging for production code.Also applies to: 82-82, 92-92, 297-297, 472-472
536-539: Simplify onClick handler—async wrapper is unnecessary.The async IIFE wrapper around
handleExecute()is redundant sincehandleExecuteis already an async function and React's onClick can handle promises directly.Proposed fix
<button - onClick={async () => { - await handleExecute(); - }} + onClick={handleExecute} disabled={loading}apps/http-backend/src/routes/userRoutes/userRoutes.ts (4)
20-20: Remove unused importAxios.Only
axios(lowercase) is used in the code; theAxiostype import is unused.Proposed fix
-import axios, { Axios } from "axios"; +import axios from "axios";
668-686: Add error handling for axios call to prevent unhandled rejections.If the axios POST to HOOKS_URL fails (e.g., network error, service unavailable, non-2xx response), it will throw and be caught by the outer catch block returning a generic 500 error. Consider handling specific axios errors to provide better feedback.
Proposed fix
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" - } - ) + try { + const hookResponse = await axios.post( + `${HOOKS_URL}/hooks/catch/${userId}/${workflowId}`, + { triggerData: "" }, + { timeout: 30000 } + ); + const workflowExecutionId = hookResponse.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 + }); + } catch (hookError: any) { + console.error("Hook service error:", hookError.message); + return res.status(statusCodes.BAD_GATEWAY).json({ + message: "Failed to trigger workflow execution", + error: hookError.response?.data?.message || hookError.message + }); } - return res.status(200).json({ - success: true, - workflowExecutionId: data.data.workflowExecutionId - }); }
687-692: Consider supporting non-webhook triggers or providing clearer UX guidance.Returning 403 Forbidden when the trigger is not a webhook may confuse users who attempt to execute workflows with other trigger types. Consider either:
- Supporting other trigger types for manual execution
- Returning a more descriptive error (e.g., 400 with a clear message)
Proposed fix for clearer messaging
else { - - return res.status(statusCodes.FORBIDDEN).json({ - message: "Trigger is not webhook" + return res.status(statusCodes.BAD_REQUEST).json({ + message: "Manual execution is only supported for webhook-triggered workflows" }); }
636-637: Remove debug console.log statements before merging.Multiple
console.logstatements are scattered throughout the new and modified code (lines 154, 524, 636, 644, 665-667, 674). These should be removed or replaced with a proper logging framework for production.Also applies to: 644-644, 665-667, 674-674, 524-524, 154-154
| app.post("/hooks/catch/:userId/:workflowId", async (req, res) => { | ||
| try { | ||
|
|
||
| console.log("THIS LOG IS FROM HOOKS BACKEND THAT WE HAVE RECIEVED THE REQUEST") |
There was a problem hiding this comment.
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.
| 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).
| res.status(500).json({ | ||
| success: false, | ||
| error: "Failed to process webhook" | ||
| }); |
There was a problem hiding this comment.
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.
| 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.
| "/callback", | ||
| userMiddleware, | ||
| async (req: Request, res: Response) => { | ||
| console.log("Request recieved to the callback from fronted ") |
There was a problem hiding this comment.
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.
| 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.
| 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 | ||
| }) | ||
| } |
There was a problem hiding this comment.
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.
| 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 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); | ||
| } | ||
| } |
There was a problem hiding this comment.
Incorrect error message in catch block.
The toast message says "Failed to save config" but this handler is for workflow execution, not saving configuration.
Proposed fix
catch (error: any) {
- toast.error("Failed to save config");
+ toast.error("Failed to execute workflow");
}📝 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.
| 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 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 execute workflow"); | |
| } | |
| finally { | |
| setLoading(false); | |
| } | |
| } |
🤖 Prompt for AI Agents
In `@apps/web/app/workflows/`[id]/page.tsx around lines 29 - 43, The catch block
in handleExecute currently shows the wrong toast text ("Failed to save config");
update the error handling for handleExecute so the toast.error reflects workflow
execution failure (e.g., "Failed to start execution" or "Failed to execute
workflow") and optionally log the caught error (from the catch parameter) using
console.error or include it in the toast for easier debugging; make this change
around the handleExecute function and the api.workflows.execute call.
| const [selectedNode, setSelectedNode] = useState<any>(null); | ||
| const [error, setError] = useState<string | null>(null); | ||
|
|
||
| const [loading, setLoading] = useState<any>("") |
There was a problem hiding this comment.
Type mismatch: loading state initialized as string but used as boolean.
The state is initialized with an empty string "" but used as a boolean throughout the component (e.g., disabled={loading}, {loading ? "Executing..." : "Execute"}). Additionally, using any type defeats TypeScript's type safety.
Proposed fix
- const [loading, setLoading] = useState<any>("")
+ const [loading, setLoading] = useState<boolean>(false)📝 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.
| const [loading, setLoading] = useState<any>("") | |
| const [loading, setLoading] = useState<boolean>(false) |
🤖 Prompt for AI Agents
In `@apps/web/app/workflows/`[id]/page.tsx at line 65, The loading state is
incorrectly initialized as a string and typed as any; change the useState call
for loading to use a boolean type and initialize to false (e.g.,
useState<boolean>(false) or allow type inference) so usages like
disabled={loading} and {loading ? "Executing..." : "Execute"} are type-safe;
update references to loading and setLoading accordingly but no other logic
changes.
| position : z.object({ | ||
| x : z.number() , | ||
| y : z.number() | ||
| }) |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
cat -n packages/common/src/index.ts | head -50Repository: Dev-Pross/BuildFlow
Length of output: 1598
🏁 Script executed:
# Find the specific files mentioned
find . -name "workflowSlice.ts" -o -name "config.ts" | grep -E "(workflowSlice|config\.ts)"Repository: Dev-Pross/BuildFlow
Length of output: 141
🏁 Script executed:
# Search for position field usage patterns across the codebase
rg -n "position\s*[:=]" --type=ts --type=tsx -A 2 -B 2 | head -100Repository: Dev-Pross/BuildFlow
Length of output: 90
🏁 Script executed:
cat -n apps/web/store/slices/workflowSlice.ts | sed -n '1,30p'Repository: Dev-Pross/BuildFlow
Length of output: 847
🏁 Script executed:
cat -n apps/web/app/workflow/lib/config.ts | sed -n '200,230p'Repository: Dev-Pross/BuildFlow
Length of output: 976
🏁 Script executed:
# Broader search for position usage without type restriction
rg -n "position\s*[:=]" -A 2 -B 2 | head -150Repository: Dev-Pross/BuildFlow
Length of output: 9379
Fix position payload type mismatch between frontend and backend schema.
The NodeSchema.position field is defined as a required object ({x: number, y: number}), but apps/web/app/workflow/lib/config.ts (line 234) sends Position as a number (0) when creating nodes, causing a schema validation mismatch. Additionally, the API field is inconsistently named: the schema expects lowercase position but the frontend sends capitalized Position. Other parts of the codebase correctly use object-shaped positions (e.g., apps/web/app/workflows/[id]/page.tsx, seed data), so either standardize payloads across all creation/update endpoints or make the schema more lenient for backward compatibility.
🤖 Prompt for AI Agents
In `@packages/common/src/index.ts` around lines 34 - 37, NodeSchema.position
currently expects an object but frontend sometimes sends a numeric Position or
uses capitalized "Position"; update the schema in packages/common/src/index.ts
to accept both shapes and be tolerant: change NodeSchema.position to a union
like z.union([z.object({x: z.number(), y: z.number()}), z.number()]) (or z.any()
temporarily) and ensure validation accepts either key by normalizing incoming
payload keys (map "Position" -> "position") in the request parsing code that
handles node creation (refer to apps/web/app/workflow/lib/config.ts where
Position is sent); this makes the API backward-compatible while you standardize
callers to send the object-shaped position used elsewhere (e.g.,
apps/web/app/workflows/[id]/page.tsx and seed data).
There was a problem hiding this comment.
Pull request overview
This PR applies a set of config and feature tweaks across the web app, backend, hooks service, and shared schemas—primarily around webhook execution, node positioning, and Google OAuth credential handling.
Changes:
- Adds workflow execution support via a new backend
/executeWorkflowroute and corresponding frontend API + UI button. - Updates shared Zod schemas (node
position,ExecuteWorkflow) and persists node positions on creation. - Adjusts Google OAuth credential type usage and hooks service URL/port, plus assorted UI tweaks.
Reviewed changes
Copilot reviewed 14 out of 15 changed files in this pull request and generated 23 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/nodes/src/common/google-oauth-service.ts | Captures credential create result and adds debug logging during OAuth credential persistence. |
| packages/common/src/index.ts | Updates HOOKS_URL port and extends Zod schemas (node position, ExecuteWorkflow). |
| apps/web/store/slices/userSlice.ts | Minor formatting change in reducer definition. |
| apps/web/app/workflows/page.tsx | Improves workflow config display and adds a fixed “Create Workflow” button. |
| apps/web/app/workflows/[id]/page.tsx | Adds “Execute” button/handler and various debug logs; tweaks node config name handling and stage calculation. |
| apps/web/app/workflows/[id]/components/ConfigModal.tsx | Adds an extra import and minor formatting changes. |
| apps/web/app/workflow/lib/config.ts | Changes credential response parsing (Data → data) and adds debug logging. |
| apps/web/app/page.tsx | Changes unauthenticated sign-in form action to /login. |
| apps/web/app/login/page.tsx | Redirects to /workflows after successful login. |
| apps/web/app/lib/nodeConfigs/googleSheet.action.ts | Switches credentials type to google_oauth. |
| apps/web/app/lib/nodeConfigs/gmail.action.ts | Switches credentials type to google_oauth. |
| apps/web/app/lib/api.ts | Adds a workflow execute API wrapper. |
| apps/web/app/hooks/useCredential.ts | Adds debug logging around fetched credentials. |
| apps/web/app/components/ui/Design/WorkflowButton.tsx | Small UI tweak (cursor styling) for the create workflow button. |
| apps/http-backend/src/routes/userRoutes/userRoutes.ts | Persists node position fields, adjusts credentials response behavior, and adds /executeWorkflow route. |
| apps/http-backend/src/routes/google_callback.ts | Adds additional debug logging in OAuth callback. |
| apps/hooks/src/index.ts | Adds debug logging in webhook ingestion route and minor formatting cleanup. |
Comments suppressed due to low confidence (1)
apps/web/app/workflows/[id]/components/ConfigModal.tsx:8
apiis imported but not used in this component. Remove the unused import to avoid lint/no-unused-vars issues.
import { api } from "@/app/lib/api";
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| return res.status(statusCodes.FORBIDDEN).json({ | ||
| message: "Error in Zod Schma", | ||
| Data: parsedData.error |
There was a problem hiding this comment.
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").
| 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 |
| setLoading(true); | ||
| try { | ||
| const data = await api.workflows.execute({workflowId}) | ||
| console.log("This is from the Execute Button", data) |
There was a problem hiding this comment.
Remove this console.log (or gate it behind a debug flag). Logging full API responses in the browser console is noisy and can leak internal details.
| console.log("This is from the Execute Button", data) |
| HOOKS_URL, | ||
| } from "@repo/common/zod"; | ||
| import { GoogleSheetsNodeExecutor } from "@repo/nodes"; | ||
| import axios, { Axios } from "axios"; |
There was a problem hiding this comment.
Remove the unused Axios import; it isn’t referenced and will trigger lint/no-unused-vars checks.
| import axios, { Axios } from "axios"; | |
| import axios from "axios"; |
| }); | ||
| } | ||
| console.log("This is the Trigger Name of the workflow", trigger?.Trigger?.name) | ||
| console.log("This is the Trigger Data of the workflow", trigger) |
There was a problem hiding this comment.
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.
| 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, | |
| }); |
| <> | ||
| <p>Status: Not authenticated</p> | ||
| <form action="/api/auth/signin" method="post"> | ||
| <form action="/login" method="post"> |
There was a problem hiding this comment.
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.
|
|
||
| console.log("THIS LOG IS FROM HOOKS BACKEND THAT WE HAVE RECIEVED THE REQUEST") | ||
| const { userId, workflowId } = req.params; |
There was a problem hiding this comment.
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.
| "/callback", | ||
| userMiddleware, | ||
| async (req: Request, res: Response) => { | ||
| console.log("Request recieved to the callback from fronted ") |
There was a problem hiding this comment.
Avoid automated semicolon insertion (94% of all statements in the enclosing function have an explicit semicolon).
| console.log("Request recieved to the callback from fronted ") | |
| console.log("Request recieved to the callback from fronted "); |
| 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) |
There was a problem hiding this comment.
Avoid automated semicolon insertion (90% of all statements in the enclosing function have an explicit semicolon).
| console.log("The type of data comming to backed is ", type) | |
| console.log("The type of data comming to backed is ", type); |
| // 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) |
There was a problem hiding this comment.
Avoid automated semicolon insertion (90% of all statements in the enclosing function have an explicit semicolon).
| 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); |
| }) | ||
| } | ||
|
|
||
| }) |
There was a problem hiding this comment.
Avoid automated semicolon insertion (90% of all statements in the enclosing script have an explicit semicolon).
Summary by CodeRabbit
Release Notes
New Features
Improvements
✏️ Tip: You can customize this high-level summary in your review settings.