Conversation
… management - Deleted unused components: CreateWorkFlow, GoogleSheetFormClient, and actions.ts. - Refactored API calls to streamline workflow data fetching and management. - Updated workflow slice to handle backend data structure changes. - Improved sidebar functionality for workflow selection and management.
📝 WalkthroughWalkthroughThis PR removes the old ReactFlow-based workflow creation components and configuration helper functions, replacing them with an API-driven architecture. The changes eliminate local configuration code in favor of fetching workflow and credential data from backend endpoints via an Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
apps/web/app/workflows/[id]/page.tsx (2)
400-400:⚠️ Potential issue | 🟠 MajorIncorrect field access:
node.NodeIdis undefined on raw backend data.Similar to the trigger issue,
nodehere comes fromdbNodes(raw backend data) which usesid, notNodeId. TheNodeIdfield only exists after Redux normalization.🐛 Suggested fix
- onTest: ()=> testNodeFromCanvas(node.NodeId, node.name, "action") + onTest: ()=> testNodeFromCanvas(node.id, node.name || node.data?.label, "action")🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/web/app/workflows/`[id]/page.tsx at line 400, The onTest handler is accessing node.NodeId which doesn't exist on raw backend dbNodes; change the call to use the raw id field (node.id) instead of node.NodeId when invoking testNodeFromCanvas (e.g., replace node.NodeId with node.id) so the function receives the correct identifier from dbNodes prior to Redux normalization.
374-374:⚠️ Potential issue | 🟠 MajorIncorrect field access:
Trigger.TriggerIdis undefined on raw backend data.At this point in the code (the
elsebranch starting at line 327),Triggeris the raw backend object which hasid, notTriggerId. TheTriggerIdfield is only available after normalization viasetWorkflowFromBackend.This will cause
testNodeFromCanvasto receiveundefinedas the first argument.🐛 Suggested fix
- onTest: ( Trigger.name.toLowerCase() === 'webhook' ? undefined : ()=> testNodeFromCanvas(Trigger.TriggerId, Trigger.name, "trigger") ) + onTest: ( Trigger.name.toLowerCase() === 'webhook' ? undefined : ()=> testNodeFromCanvas(Trigger.id, Trigger.name, "trigger") )🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/web/app/workflows/`[id]/page.tsx at line 374, The call site passes an undefined id because it uses Trigger.TriggerId on raw backend data; change the argument to use the backend object's id field (Trigger.id) or ensure it is normalized first via setWorkflowFromBackend so testNodeFromCanvas receives a valid id; specifically update the onTest invocation that references Trigger.TriggerId to use Trigger.id (or pass the normalized object) when calling testNodeFromCanvas(…, "trigger").apps/web/app/components/ui/app-sidebar.tsx (1)
169-169:⚠️ Potential issue | 🟡 MinorTypo: "avaliable" should be "available".
✏️ Suggested fix
- <span>No credentials avaliable</span> + <span>No credentials available</span>🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/web/app/components/ui/app-sidebar.tsx` at line 169, Fix the typo in the AppSidebar component by replacing the incorrect string "No credentials avaliable" with the correct "No credentials available" in the JSX span (the message rendered when credentials are missing); ensure any other occurrences of this exact misspelling in the component or related UI helper functions are updated as well.
🧹 Nitpick comments (5)
apps/web/app/hooks/useCredential.ts (2)
3-4: Unused import:BACKEND_URLis no longer needed.After switching to the
apiclient, theBACKEND_URLimport is no longer used in this file.🧹 Suggested fix
import { useEffect, useState } from "react"; -import { BACKEND_URL } from "@repo/common/zod"; import { api } from "../lib/api";🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/web/app/hooks/useCredential.ts` around lines 3 - 4, Remove the unused BACKEND_URL import from useCredential.ts: the file now uses the api client (symbol: api) so delete the import line referencing BACKEND_URL to avoid the unused-import lint error and keep only the required imports.
20-22: Remove debug logging before merging.Console.log statements at lines 21-22 should be removed from production code.
🧹 Suggested fix
const response = await api.Credentials.getCredentials(type) - const data = JSON.stringify(response) - console.log("This is the log from usecredentials" , data) // Backend should ONLY return stored credentials🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/web/app/hooks/useCredential.ts` around lines 20 - 22, Remove the development-only console logging in useCredential.ts: delete the console.log call that prints the serialized response from api.Credentials.getCredentials(type) (the lines that create `data` and call console.log). Ensure the function still returns or handles `response` as intended (leave the `response` variable and any return/assignment intact) and avoid adding any other debug prints; if persistent logging is required use the application's standardized logger instead.apps/web/app/components/ui/app-sidebar.tsx (1)
27-27: Unused import:PlusCircleis no longer used.
PlusCircleis imported but replaced byLucidePlus. Remove the unused import.🧹 Suggested fix
-import { ChevronDown, ChevronUp, Key, LogOut, LucideLayoutDashboard, LucidePlus, PlusCircle, User2, WorkflowIcon } from 'lucide-react' +import { ChevronDown, ChevronUp, Key, LogOut, LucideLayoutDashboard, LucidePlus, User2, WorkflowIcon } from 'lucide-react'🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/web/app/components/ui/app-sidebar.tsx` at line 27, Remove the unused import PlusCircle from the import list in app-sidebar.tsx; update the import statement that currently includes "PlusCircle" (alongside ChevronDown, ChevronUp, Key, LogOut, LucideLayoutDashboard, LucidePlus, User2, WorkflowIcon) so it only imports the actually used icons (e.g., LucidePlus) to eliminate the unused-symbol warning.apps/web/app/lib/api.ts (2)
9-16: Duplicate API method:api.user.get()andapi.workflows.getAll()call the same endpoint.Both methods make identical
GETrequests to${BACKEND_URL}/user/workflows. Consider removingapi.user.get()or consolidating to avoid confusion and maintenance overhead.♻️ Suggested fix: Remove duplicate method
export const api = { - user: { - get: async () => { - return await axios.get(`${BACKEND_URL}/user/workflows`, - { - withCredentials: true, - headers: { "Content-Type": "application/json" }, - }) - } - }, workflows: {If
api.user.get()is used elsewhere, update those call sites to useapi.workflows.getAll()instead.Also applies to: 41-48
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/web/app/lib/api.ts` around lines 9 - 16, The api.user.get() method duplicates api.workflows.getAll() by calling the same `${BACKEND_URL}/user/workflows` endpoint; remove the redundant api.user.get() function (or consolidate it into api.workflows.getAll()) and update all call sites to use api.workflows.getAll() instead (search for usages of api.user.get and replace with api.workflows.getAll), ensuring exported API shape stays consistent and any imports/tests are updated accordingly.
91-104: Inconsistent response unwrapping inCredentialsnamespace.
getCredentialsextracts and returnsres.data.data(line 97), whilegetAllCredsreturns the raw axios response. This inconsistency forces callers to handle responses differently.In
app-sidebar.tsxline 63, the caller accessescredentials.data.data, which works but is inconsistent with howgetCredentialsis consumed.♻️ Suggested fix: Consistent response unwrapping
getAllCreds: async () => - await axios.get(`${BACKEND_URL}/user/getAllCreds`, { + { + const res = await axios.get(`${BACKEND_URL}/user/getAllCreds`, { withCredentials: true, headers: { "Content-Type": "application/json" }, - }), + }); + return res.data.data; + },Then update
app-sidebar.tsxline 63:- if(credentials.data) setCreds(credentials.data.data) + if(credentials) setCreds(credentials)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/web/app/lib/api.ts` around lines 91 - 104, getAllCreds currently returns the raw axios response while getCredentials returns res.data.data, causing inconsistent caller handling; update getAllCreds in the Credentials namespace to await the request, extract and return the same payload shape (res.data.data) as getCredentials, and then update callers (e.g., app-sidebar.tsx) to consume the unified return value from getAllCreds instead of accessing credentials.data.data.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@apps/web/app/components/ui/app-sidebar.tsx`:
- Around line 53-87: Wrap each async helper (getWorkflows, getCreds,
getWorkflowData) in a try-catch and handle failures: call the corresponding API
(api.workflows.getAll, api.Credentials.getAllCreds, api.workflows.get) inside
try, on success setWorkflows/setCreds and dispatch
workflowActions.setWorkflowFromBackend for getWorkflowData, and in catch log the
error and update a simple error or fallback state (e.g., setWorkflows([]) /
setCreds([]) or set an error flag) so the UI doesn't remain stuck on
"Loading..."; ensure the catch blocks reference the same functions
(getWorkflows/getCreds/getWorkflowData) so they live in the current useEffect
closure.
In `@apps/web/app/hooks/useTriggers.ts`:
- Around line 19-22: In useTriggers, guard against null/undefined and remove
debug logs: when handling the result of api.triggers.getAvailable()
(response.data.Data) ensure you coerce or validate it to an array before calling
setTriggers (e.g., setTriggers(Array.isArray(response.data?.Data) ?
response.data.Data : [])) and remove the console.log calls that print
response/data to avoid leaving debug logging in production; reference the
useTriggers function, setTriggers state updater, and api.triggers.getAvailable
to locate the code to change.
---
Outside diff comments:
In `@apps/web/app/components/ui/app-sidebar.tsx`:
- Line 169: Fix the typo in the AppSidebar component by replacing the incorrect
string "No credentials avaliable" with the correct "No credentials available" in
the JSX span (the message rendered when credentials are missing); ensure any
other occurrences of this exact misspelling in the component or related UI
helper functions are updated as well.
In `@apps/web/app/workflows/`[id]/page.tsx:
- Line 400: The onTest handler is accessing node.NodeId which doesn't exist on
raw backend dbNodes; change the call to use the raw id field (node.id) instead
of node.NodeId when invoking testNodeFromCanvas (e.g., replace node.NodeId with
node.id) so the function receives the correct identifier from dbNodes prior to
Redux normalization.
- Line 374: The call site passes an undefined id because it uses
Trigger.TriggerId on raw backend data; change the argument to use the backend
object's id field (Trigger.id) or ensure it is normalized first via
setWorkflowFromBackend so testNodeFromCanvas receives a valid id; specifically
update the onTest invocation that references Trigger.TriggerId to use Trigger.id
(or pass the normalized object) when calling testNodeFromCanvas(…, "trigger").
---
Nitpick comments:
In `@apps/web/app/components/ui/app-sidebar.tsx`:
- Line 27: Remove the unused import PlusCircle from the import list in
app-sidebar.tsx; update the import statement that currently includes
"PlusCircle" (alongside ChevronDown, ChevronUp, Key, LogOut,
LucideLayoutDashboard, LucidePlus, User2, WorkflowIcon) so it only imports the
actually used icons (e.g., LucidePlus) to eliminate the unused-symbol warning.
In `@apps/web/app/hooks/useCredential.ts`:
- Around line 3-4: Remove the unused BACKEND_URL import from useCredential.ts:
the file now uses the api client (symbol: api) so delete the import line
referencing BACKEND_URL to avoid the unused-import lint error and keep only the
required imports.
- Around line 20-22: Remove the development-only console logging in
useCredential.ts: delete the console.log call that prints the serialized
response from api.Credentials.getCredentials(type) (the lines that create `data`
and call console.log). Ensure the function still returns or handles `response`
as intended (leave the `response` variable and any return/assignment intact) and
avoid adding any other debug prints; if persistent logging is required use the
application's standardized logger instead.
In `@apps/web/app/lib/api.ts`:
- Around line 9-16: The api.user.get() method duplicates api.workflows.getAll()
by calling the same `${BACKEND_URL}/user/workflows` endpoint; remove the
redundant api.user.get() function (or consolidate it into
api.workflows.getAll()) and update all call sites to use api.workflows.getAll()
instead (search for usages of api.user.get and replace with
api.workflows.getAll), ensuring exported API shape stays consistent and any
imports/tests are updated accordingly.
- Around line 91-104: getAllCreds currently returns the raw axios response while
getCredentials returns res.data.data, causing inconsistent caller handling;
update getAllCreds in the Credentials namespace to await the request, extract
and return the same payload shape (res.data.data) as getCredentials, and then
update callers (e.g., app-sidebar.tsx) to consume the unified return value from
getAllCreds instead of accessing credentials.data.data.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 8b5e0f04-1ad1-48ab-8350-e7bacb28e3ad
📒 Files selected for processing (12)
apps/web/app/components/nodes/CreateWorkFlow.tsxapps/web/app/components/nodes/GoogleSheetFormClient.tsxapps/web/app/components/nodes/actions.tsapps/web/app/components/ui/Logs.tsxapps/web/app/components/ui/app-sidebar.tsxapps/web/app/hooks/useCredential.tsapps/web/app/hooks/useTriggers.tsapps/web/app/lib/api.tsapps/web/app/workflow/lib/config.tsapps/web/app/workflow/page.tsxapps/web/app/workflows/[id]/page.tsxapps/web/store/slices/workflowSlice.ts
💤 Files with no reviewable changes (5)
- apps/web/app/workflow/page.tsx
- apps/web/app/components/nodes/actions.ts
- apps/web/app/components/nodes/GoogleSheetFormClient.tsx
- apps/web/app/components/nodes/CreateWorkFlow.tsx
- apps/web/app/workflow/lib/config.ts
| useEffect(()=>{ | ||
|
|
||
| async function getWorkflows(){ | ||
| const flows = await api.workflows.getAll(); | ||
| if(flows) setWorkflows(flows.data.Data) | ||
| } | ||
|
|
||
| async function getCreds(){ | ||
| const credentials = await getAllCredentials(); | ||
| if(credentials) setCreds(credentials) | ||
| const credentials = await api.Credentials.getAllCreds(); | ||
| console.log(`--- 60 ${JSON.stringify(credentials)}`) | ||
| if(credentials.data) setCreds(credentials.data.data) | ||
| } | ||
|
|
||
| async function getWorkflowData(){ | ||
| console.log("workflow data called") | ||
| if(!flow.workflow_id) return | ||
| const workflow = await getworkflowData(flow.workflow_id) | ||
| if(workflow.success){ | ||
| console.log("workflow data fetchedsuceesully: ", workflow.data) | ||
| dispatch(workflowActions.setWorkflowStatus(false)) | ||
| dispatch(workflowActions.setWorkflowNodes(workflow.data.nodes)) | ||
| dispatch(workflowActions.setWorkflowTrigger(workflow.data.Trigger)) | ||
| if(!selectedWorkflow) return | ||
| const workflow = await api.workflows.get(selectedWorkflow); | ||
| if(workflow.data){ | ||
| console.log("workflow data fetchedsuceesully: ", workflow.data.Data) | ||
| // dispatch(workflowActions.addWorkflowNode(workflow.data.nodes)) | ||
| dispatch( | ||
| workflowActions.setWorkflowFromBackend({ | ||
| workflowId: selectedWorkflow, | ||
| data: workflow.data.Data, | ||
| }) | ||
| ) | ||
| // dispatch(workflowActions.setWorkflowTrigger(workflow.data.Trigger)) | ||
| // console.log(`workfklow from redux: ${workflow.data}`) | ||
| } | ||
| } | ||
| // async function setEmptyFlow(){ | ||
| // const workflow = await getEmptyWorkflow() | ||
| // if(workflow){ | ||
| // const {id, isEmpty} = workflow | ||
| // dispatch(workflowActions.setWorkflowId(id)) | ||
| // dispatch(workflowActions.setWorkflowStatus(isEmpty)) | ||
| // } | ||
| // else{ | ||
| // const newWorkflow = await createWorkflow() | ||
| // dispatch(workflowActions.clearWorkflow()) | ||
| // setSelectedWorkflow(null) | ||
| // dispatch(workflowActions.setWorkflowId(newWorkflow.id)) | ||
| // dispatch(workflowActions.setWorkflowStatus(newWorkflow.isEmpty)) | ||
| // toast.success("Workflow created") | ||
| // getWorkflows() | ||
| // } | ||
| // } | ||
|
|
||
| if(!creds) getCreds() | ||
| if(!workflow) { | ||
| if(!workflows) { | ||
| getWorkflows() | ||
| createNewWorkflow() | ||
| } | ||
| getWorkflowData() | ||
| },[flow.workflow_id, dispatch]) | ||
| },[selectedWorkflow, dispatch]) |
There was a problem hiding this comment.
Missing error handling in async data fetching.
The getWorkflows(), getCreds(), and getWorkflowData() functions lack try-catch blocks. If any API call fails, the corresponding state remains in its initial value (undefined for workflows/creds), causing the UI to show "Loading..." indefinitely.
🛡️ Suggested fix: Add error handling
async function getWorkflows(){
+ try {
const flows = await api.workflows.getAll();
if(flows) setWorkflows(flows.data.Data)
+ } catch (err) {
+ console.error("Failed to fetch workflows:", err);
+ setWorkflows([]);
+ }
}
async function getCreds(){
+ try {
const credentials = await api.Credentials.getAllCreds();
console.log(`--- 60 ${JSON.stringify(credentials)}`)
if(credentials.data) setCreds(credentials.data.data)
+ } catch (err) {
+ console.error("Failed to fetch credentials:", err);
+ setCreds([]);
+ }
}
async function getWorkflowData(){
if(!selectedWorkflow) return
+ try {
const workflow = await api.workflows.get(selectedWorkflow);
if(workflow.data){
// ... dispatch logic
}
+ } catch (err) {
+ console.error("Failed to fetch workflow data:", err);
+ toast.error("Failed to load workflow");
+ }
}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@apps/web/app/components/ui/app-sidebar.tsx` around lines 53 - 87, Wrap each
async helper (getWorkflows, getCreds, getWorkflowData) in a try-catch and handle
failures: call the corresponding API (api.workflows.getAll,
api.Credentials.getAllCreds, api.workflows.get) inside try, on success
setWorkflows/setCreds and dispatch workflowActions.setWorkflowFromBackend for
getWorkflowData, and in catch log the error and update a simple error or
fallback state (e.g., setWorkflows([]) / setCreds([]) or set an error flag) so
the UI doesn't remain stuck on "Loading..."; ensure the catch blocks reference
the same functions (getWorkflows/getCreds/getWorkflowData) so they live in the
current useEffect closure.
| const response = await api.triggers.getAvailable(); | ||
| setTriggers(response.data.Data); | ||
| console.log(response.data.Data); | ||
| console.log(JSON.stringify(response)); |
There was a problem hiding this comment.
Missing null safety and debug logging left in production code.
- If
response.data.Dataisundefinedornull,setTriggerswill set state to a non-array value, potentially causing runtime errors in components that expect an array. - Console.log statements at lines 21-22 should be removed before merging.
🛡️ Suggested fix
const response = await api.triggers.getAvailable();
- setTriggers(response.data.Data);
- console.log(response.data.Data);
- console.log(JSON.stringify(response));
+ setTriggers(response.data.Data ?? []);📝 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 response = await api.triggers.getAvailable(); | |
| setTriggers(response.data.Data); | |
| console.log(response.data.Data); | |
| console.log(JSON.stringify(response)); | |
| const response = await api.triggers.getAvailable(); | |
| setTriggers(response.data.Data ?? []); |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@apps/web/app/hooks/useTriggers.ts` around lines 19 - 22, In useTriggers,
guard against null/undefined and remove debug logs: when handling the result of
api.triggers.getAvailable() (response.data.Data) ensure you coerce or validate
it to an array before calling setTriggers (e.g.,
setTriggers(Array.isArray(response.data?.Data) ? response.data.Data : [])) and
remove the console.log calls that print response/data to avoid leaving debug
logging in production; reference the useTriggers function, setTriggers state
updater, and api.triggers.getAvailable to locate the code to change.
… management
Summary by CodeRabbit
Removed Features
UI Changes
Refactoring