Skip to content

Refactor code structure for improved readability and maintainability#74

Merged
Vamsi-o merged 1 commit into
mainfrom
base-node-ui
Mar 13, 2026
Merged

Refactor code structure for improved readability and maintainability#74
Vamsi-o merged 1 commit into
mainfrom
base-node-ui

Conversation

@TejaBudumuru3

@TejaBudumuru3 TejaBudumuru3 commented Mar 12, 2026

Copy link
Copy Markdown
Contributor

Summary by CodeRabbit

  • New Features

    • Added icon display for triggers and action items across the interface
    • Introduced node testing capability directly from the canvas
  • Improvements

    • Enhanced node card visual design with improved icon rendering and layout
    • Refined icon display handling across workflow components

@TejaBudumuru3 TejaBudumuru3 requested a review from Vamsi-o as a code owner March 12, 2026 17:17
@coderabbitai

coderabbitai Bot commented Mar 12, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

This PR adds icon support throughout the application stack, from the database schema to the backend API routes to frontend UI components, while introducing a test execution capability for individual nodes. Icons are fetched from database metadata, transformed in API responses, and rendered dynamically in components with emoji fallbacks.

Changes

Cohort / File(s) Summary
Database Schema
packages/db/prisma/schema.prisma
Added optional icon fields to AvailableTrigger and AvailableNode models for icon metadata storage.
State Management
apps/web/store/slices/workflowSlice.ts
Extended Trigger and NodeItem interface definitions with optional icon fields.
Backend API Enhancement
apps/http-backend/src/routes/userRoutes/userRoutes.ts
Expanded GET /workflow/:workflowId to fetch related trigger type icons and node icons; transforms response to extract icons and remove nested objects.
Node & Action UI Components
apps/web/app/components/nodes/BaseNode.tsx, apps/web/app/components/nodes/TriggerSidebar.tsx, apps/web/app/components/Actions/ActionSidebar.tsx, apps/web/app/components/ui/variable-panel.tsx
Updated icon rendering across multiple components to display image elements with fallback emoji; includes layout restructuring in BaseNode with vertical flex arrangement and styled icon containers.
Modal & Workflow Page Logic
apps/web/app/workflows/[id]/components/ConfigModal.tsx, apps/web/app/workflows/[id]/page.tsx
Removed onSave prop from ConfigModal; added testNodeFromCanvas function for node test execution with variable resolution and test context building; integrated icon field population in node creation/update flows.
Build & Lifecycle Management
.gitignore, apps/http-backend/tsconfig.tsbuildinfo, apps/web/app/hooks/useAutoSave.ts
Added .gitignore entry for tsbuildinfo; deleted build cache file; disabled batchSave on beforeunload event while maintaining unload confirmation.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant Canvas as Frontend Canvas
    participant Logic as Test Logic
    participant Context as Context Builder
    participant API as Backend API
    participant Store as Redux Store
    participant UI as UI/Toast

    User->>Canvas: Click Test Button
    Canvas->>Logic: testNodeFromCanvas(nodeId)
    Logic->>Store: Get node config & selectAllOutputs
    Store-->>Logic: Node config, Previous outputs
    Logic->>Context: buildTestContext(selectAllOutputs)
    Context-->>Logic: Runtime context object
    Logic->>Logic: resolveConfigVariables(config, context)
    Logic->>API: POST /execute-node
    API-->>Logic: Execution result + output data
    alt Success
        Logic->>Store: setNodeOutput(nodeId, result)
        Logic->>UI: Show success toast
    else Error
        Logic->>Store: setNodeOutput with error
        Logic->>UI: Show error toast
    end
    UI-->>User: Display test result
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Suggested reviewers

  • Vamsi-o

Poem

🐰 Icons shimmer, nodes now gleam bright,
Tests cascade through the digital night,
From database root to UI's delight,
Each trigger and action in perfect sight,
A workflow's rebirth in icon's pure light! ✨

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The PR title is generic and vague, describing 'refactor for readability and maintainability' without conveying the actual substantial changes like adding icon fields, updating UI components, or modifying API responses. Use a more descriptive title that captures the primary changes, such as 'Add icon support to triggers and nodes with UI updates' or 'Implement icon display functionality across workflow components'.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch base-node-ui
📝 Coding Plan
  • Generate coding plan for human review comments

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Tip

CodeRabbit can generate a title for your PR based on the changes.

Add @coderabbitai placeholder anywhere in the title of your PR and CodeRabbit will replace it with a title based on the changes in the PR. You can change the placeholder by changing the reviews.auto_title_placeholder setting.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 8

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
apps/web/app/workflows/[id]/page.tsx (1)

574-583: ⚠️ Potential issue | 🟠 Major

Persist the selected icon into Redux.

Lines 579 and 731 write icon: "" even though action.icon and trigger.icon are already available. Any store-driven rehydrate or autosave path will drop the icon, and downstream consumers like ConfigModal then receive a blank selectedNode.icon.

Also applies to: 726-734

🤖 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 around lines 574 - 583, The
addWorkflowNode payload is setting icon: "" which drops the selected node's icon
on rehydrate/autosave; update the dispatch calls that call
workflowActions.addWorkflowNode (the one using action and the one using trigger)
to pass the actual icon value (e.g., icon: action.icon or icon: trigger.icon)
instead of an empty string so downstream consumers like ConfigModal receive
selectedNode.icon correctly; ensure both occurrences around the NodeId/action.id
and the trigger branch are updated.
apps/web/app/workflows/[id]/components/ConfigModal.tsx (1)

567-585: ⚠️ Potential issue | 🟡 Minor

Normalize the webhook check before hiding Test Node.

Line 567 is case-sensitive, so a node named Webhook still gets a test button here even though the rest of the workflow page lowercases first.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/web/app/workflows/`[id]/components/ConfigModal.tsx around lines 567 -
585, The Test Node visibility check is case-sensitive; update the condition that
hides the button to normalize selectedNode.name (e.g., using
selectedNode.name.toLowerCase()) before checking for "webhook" so nodes like
"Webhook" are treated the same; modify the JSX conditional around the Test Node
button (where selectedNode.name is referenced, and the onClick uses
handleTestNode) to use the lowercased name for the includes check and keep
existing isTestingNode/loading disables and classes unchanged.
🧹 Nitpick comments (3)
apps/web/app/hooks/useAutoSave.ts (2)

64-71: Remove unnecessary return true statement.

Commenting out batchSave() in the beforeunload handler is correct—async operations here are unreliable since browsers don't wait for them to complete before closing.

However, return true on line 70 is non-standard and has no effect. Modern browsers only respect e.preventDefault() and e.returnValue for triggering the unload confirmation dialog. The return value from the handler is ignored.

♻️ Suggested cleanup
         const handleBeforeUnload = (e: BeforeUnloadEvent) =>{
             const { isChanged } = store.getState().workflow
             if(isChanged.edges || isChanged.nodes || isChanged.trigger){
                 e.preventDefault()
-                // batchSave();
-                e.returnValue = true;
-                return true
+                e.returnValue = '';
             }
         }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/web/app/hooks/useAutoSave.ts` around lines 64 - 71, In the beforeunload
handler function handleBeforeUnload, remove the redundant "return true"
statement (it has no effect in modern browsers); keep the existing
e.preventDefault() and e.returnValue = true logic that triggers the unload
confirmation, and leave the batchSave() call commented out as async work is
unreliable here; ensure the handler still checks
store.getState().workflow.isChanged (edges/nodes/trigger) before setting
e.returnValue.

61-81: Consider wrapping batchSave with useCallback for effect stability.

The batchSave function is defined outside the effect but used within it and not listed in dependencies. While this works because it reads state via store.getState() directly, wrapping it in useCallback with proper dependencies would make the code more maintainable and prevent potential stale closure issues if the implementation changes.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/web/app/hooks/useAutoSave.ts` around lines 61 - 81, batchSave is used
inside the useEffect but isn't stable; wrap the batchSave function in
useCallback (export/define it as const batchSave = useCallback(..., [/* explicit
deps or none if it only uses store.getState() */])) so its identity is stable,
then include that batchSave in the useEffect dependency array (or keep
workflowId plus batchSave) to avoid stale closures; update the effect to depend
on batchSave (and workflowId) and ensure handleBeforeUnload and the interval use
the stable batchSave reference.
.gitignore (1)

53-53: Remove the duplicate ignore rule.

apps/http-backend/tsconfig.tsbuildinfo is already ignored on Line 50, so this extra entry only adds noise.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.gitignore at line 53, Duplicate ignore entry detected: the pattern
"apps/http-backend/tsconfig.tsbuildinfo" appears twice in .gitignore; remove the
redundant line (the second occurrence at the shown location) so the file
contains only the single ignore rule for apps/http-backend/tsconfig.tsbuildinfo.
🤖 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/http-backend/src/routes/userRoutes/userRoutes.ts`:
- Around line 375-388: The workflow payload is dropping trigger/node runtime
kinds by only selecting icon; update the query in userRoutes.ts so the Trigger
-> triggerType select and nodes -> AvailableNode select also include the type
field (e.g., select: { icon: true, type: true }) so the returned payload
contains trigger.type and node.type that apps/web/store/slices/workflowSlice.ts
expects; apply the same change to the analogous block around lines 396-408.

In `@apps/web/app/components/nodes/BaseNode.tsx`:
- Around line 95-99: The current JSX in BaseNode.tsx treats any truthy icon as
an image and renders <img src={icon} />, which breaks when icon is a glyph like
"⚡"; update the render logic in the BaseNode component so that it only uses an
<img> when icon is a real image URL/data URI/path (e.g., startsWith('http'),
startsWith('/'), startsWith('data:'), or has an image extension like
.png/.jpg/.svg), otherwise render the icon value directly as text inside the
span as the fallback glyph. Locate the span rendering the icon (variable name
icon) and change the conditional to distinguish image URLs from plain glyph
strings.

In `@apps/web/app/components/ui/variable-panel.tsx`:
- Around line 81-84: The variable panel currently always renders an <img
src={node.icon} className="w-12 h-8"/> even though node.icon can be null,
causing broken image icons; update the JSX in the component (around the
image/emoji rendering in variable-panel.tsx where node.icon and node.nodeName
are used) to conditionally render the <img> only when node.icon is a non-empty
string and otherwise render the existing emoji/text fallback (the current emoji
fallback used elsewhere in the app), ensuring you keep the same sizing/styling
for the fallback so layout doesn’t shift.

In `@apps/web/app/workflows/`[id]/components/ConfigModal.tsx:
- Around line 418-419: The header should render selectedNode.icon defensively:
update the ConfigModal header (where selectedNode.icon and selectedNode.name are
used) to only render an <img> when selectedNode.icon is a non-empty, valid image
URL (e.g. starts with http(s):, data:, or a local path) and otherwise render the
icon value as plain text/emoji or a default fallback element; add an alt
attribute and maintain the existing className for the image. Implement a small
predicate (e.g. isValidImageUrl(icon)) or inline checks before using <img> so
empty strings or emoji won’t produce a broken image.

In `@apps/web/app/workflows/`[id]/page.tsx:
- Around line 40-45: buildTestContext currently drops successful but falsy
outputs (0, false, "") by checking testOutput.data truthiness and also
overwrites keys when the same action (normalized nodeName) appears multiple
times; update buildTestContext to include any testOutput where
testOutput.success is true regardless of data value (do not gate on
testOutput.data truthiness) and create stable unique keys by combining the
normalized node name with the nodeId (e.g., `${normalizedName}__${nodeId}`) or
another stable unique identifier instead of using normalized name alone; apply
the identical change to the matching normalization/keying logic in
ConfigModal.tsx so both entry points produce the same stable interpolation
context and avoid silent overwrites.
- Around line 58-61: The code calls api.execute.node with resolvedConfig that
may still contain unresolved template strings because resolveConfigVariables
preserves missing variables; before calling api.execute.node (in the same block
that uses buildTestContext, resolveConfigVariables and resolvedConfig), detect
unresolved templates (e.g., scan resolvedConfig for "{{" / "}}" or implement a
small hasUnresolvedVariables util), and if any are found, do not call
api.execute.node — instead surface the same warning/error flow used by the modal
path (or throw/return early) so tests aren't executed with raw template
placeholders.

In `@packages/db/prisma/schema.prisma`:
- Around line 51-52: The code reads AvailableTrigger.icon and AvailableNode.icon
at startup but the new icon columns may not exist in production because
migrations are ignored and the build only runs prisma generate; to fix this,
ensure schema rollout is coordinated by (1) creating and committing a proper
Prisma migration for the icon fields (or otherwise keeping a canonical migration
history instead of ignoring the migrations directory), (2) adding a deployment
step that runs "prisma migrate deploy" (or "prisma db push" if you accept
destructive sync) as part of CI/CD or the packages/db/package.json build script,
and (3) documenting the chosen process in repo docs; update CI/deploy config to
run the migration step before starting services that import userRoutes.ts so
AvailableTrigger.icon and AvailableNode.icon exist at runtime.

---

Outside diff comments:
In `@apps/web/app/workflows/`[id]/components/ConfigModal.tsx:
- Around line 567-585: The Test Node visibility check is case-sensitive; update
the condition that hides the button to normalize selectedNode.name (e.g., using
selectedNode.name.toLowerCase()) before checking for "webhook" so nodes like
"Webhook" are treated the same; modify the JSX conditional around the Test Node
button (where selectedNode.name is referenced, and the onClick uses
handleTestNode) to use the lowercased name for the includes check and keep
existing isTestingNode/loading disables and classes unchanged.

In `@apps/web/app/workflows/`[id]/page.tsx:
- Around line 574-583: The addWorkflowNode payload is setting icon: "" which
drops the selected node's icon on rehydrate/autosave; update the dispatch calls
that call workflowActions.addWorkflowNode (the one using action and the one
using trigger) to pass the actual icon value (e.g., icon: action.icon or icon:
trigger.icon) instead of an empty string so downstream consumers like
ConfigModal receive selectedNode.icon correctly; ensure both occurrences around
the NodeId/action.id and the trigger branch are updated.

---

Nitpick comments:
In @.gitignore:
- Line 53: Duplicate ignore entry detected: the pattern
"apps/http-backend/tsconfig.tsbuildinfo" appears twice in .gitignore; remove the
redundant line (the second occurrence at the shown location) so the file
contains only the single ignore rule for apps/http-backend/tsconfig.tsbuildinfo.

In `@apps/web/app/hooks/useAutoSave.ts`:
- Around line 64-71: In the beforeunload handler function handleBeforeUnload,
remove the redundant "return true" statement (it has no effect in modern
browsers); keep the existing e.preventDefault() and e.returnValue = true logic
that triggers the unload confirmation, and leave the batchSave() call commented
out as async work is unreliable here; ensure the handler still checks
store.getState().workflow.isChanged (edges/nodes/trigger) before setting
e.returnValue.
- Around line 61-81: batchSave is used inside the useEffect but isn't stable;
wrap the batchSave function in useCallback (export/define it as const batchSave
= useCallback(..., [/* explicit deps or none if it only uses store.getState()
*/])) so its identity is stable, then include that batchSave in the useEffect
dependency array (or keep workflowId plus batchSave) to avoid stale closures;
update the effect to depend on batchSave (and workflowId) and ensure
handleBeforeUnload and the interval use the stable batchSave reference.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 22b3debe-8aa6-47b1-bf56-9bdc177e08d8

📥 Commits

Reviewing files that changed from the base of the PR and between c07be29 and ff11ffb.

⛔ Files ignored due to path filters (4)
  • apps/web/public/gmail.png is excluded by !**/*.png
  • apps/web/public/google_sheet.png is excluded by !**/*.png
  • apps/web/public/webhook.png is excluded by !**/*.png
  • apps/web/public/webhook1.png is excluded by !**/*.png
📒 Files selected for processing (12)
  • .gitignore
  • apps/http-backend/src/routes/userRoutes/userRoutes.ts
  • apps/http-backend/tsconfig.tsbuildinfo
  • apps/web/app/components/Actions/ActionSidebar.tsx
  • apps/web/app/components/nodes/BaseNode.tsx
  • apps/web/app/components/nodes/TriggerSidebar.tsx
  • apps/web/app/components/ui/variable-panel.tsx
  • apps/web/app/hooks/useAutoSave.ts
  • apps/web/app/workflows/[id]/components/ConfigModal.tsx
  • apps/web/app/workflows/[id]/page.tsx
  • apps/web/store/slices/workflowSlice.ts
  • packages/db/prisma/schema.prisma
💤 Files with no reviewable changes (1)
  • apps/http-backend/tsconfig.tsbuildinfo

Comment on lines +375 to +388
Trigger: {
include: {
triggerType: {
select:{icon : true}
}
}
},
nodes: { orderBy: { stage: "asc" },
include: {
AvailableNode: {
select: { icon: true}
}
}
},

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Keep type in the workflow payload.

These selects now keep only icon from triggerType and AvailableNode, but Trigger and Node themselves do not have a type column in packages/db/prisma/schema.prisma. After this transform, /workflow/:workflowId returns icon but drops the runtime trigger.type / node.type information that apps/web/store/slices/workflowSlice.ts still expects. Reloading a saved workflow will lose the node/trigger kind needed to rebuild the editor state.

Also applies to: 396-408

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/http-backend/src/routes/userRoutes/userRoutes.ts` around lines 375 -
388, The workflow payload is dropping trigger/node runtime kinds by only
selecting icon; update the query in userRoutes.ts so the Trigger -> triggerType
select and nodes -> AvailableNode select also include the type field (e.g.,
select: { icon: true, type: true }) so the returned payload contains
trigger.type and node.type that apps/web/store/slices/workflowSlice.ts expects;
apply the same change to the analogous block around lines 396-408.

Comment on lines +95 to +99
<div className="flex flex-col items-center gap-2 mb-1">
<span className="text-xl p-2 rounded-full object-center">
{ icon ?
<img src={icon ? icon : "⚡"} className="w-16 h-16 object-cover"
/> : ("⚡")}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Don’t treat the fallback glyph as an image URL.

This branch renders <img> for any truthy icon, including the "⚡" fallback currently passed by other UI paths. That produces a broken image instead of the fallback glyph on nodes without a real icon asset.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/web/app/components/nodes/BaseNode.tsx` around lines 95 - 99, The current
JSX in BaseNode.tsx treats any truthy icon as an image and renders <img
src={icon} />, which breaks when icon is a glyph like "⚡"; update the render
logic in the BaseNode component so that it only uses an <img> when icon is a
real image URL/data URI/path (e.g., startsWith('http'), startsWith('/'),
startsWith('data:'), or has an image extension like .png/.jpg/.svg), otherwise
render the icon value directly as text inside the span as the fallback glyph.
Locate the span rendering the icon (variable name icon) and change the
conditional to distinguish image URLs from plain glyph strings.

Comment on lines 81 to 84
<div className="flex items-center justify-between">
<div className="flex items-center gap-2 text-sm font-medium text-gray-300">
<span>{node.icon || "⚙️"}</span>
<span><img src={node.icon} className="w-12 h-8"/></span>
<span>{node.nodeName}</span>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Guard the image fallback here.

node.icon is nullable, and some paths still use an emoji fallback when no icon exists. Rendering <img src={node.icon}> unconditionally turns both cases into a broken image in the variable panel.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/web/app/components/ui/variable-panel.tsx` around lines 81 - 84, The
variable panel currently always renders an <img src={node.icon} className="w-12
h-8"/> even though node.icon can be null, causing broken image icons; update the
JSX in the component (around the image/emoji rendering in variable-panel.tsx
where node.icon and node.nodeName are used) to conditionally render the <img>
only when node.icon is a non-empty string and otherwise render the existing
emoji/text fallback (the current emoji fallback used elsewhere in the app),
ensuring you keep the same sizing/styling for the fallback so layout doesn’t
shift.

Comment on lines +418 to +419
<h2 className="text-xl font-semibold flex gap-1 text-white">
<img src={selectedNode.icon} className="w-12 h-8"/> {selectedNode.name}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Render the header icon defensively.

selectedNode.icon is not always an image URL here. The workflow page still uses emoji fallbacks like and ⚙️, and it can also surface an empty string from store state, so Line 419 will show a broken image for common nodes.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/web/app/workflows/`[id]/components/ConfigModal.tsx around lines 418 -
419, The header should render selectedNode.icon defensively: update the
ConfigModal header (where selectedNode.icon and selectedNode.name are used) to
only render an <img> when selectedNode.icon is a non-empty, valid image URL
(e.g. starts with http(s):, data:, or a local path) and otherwise render the
icon value as plain text/emoji or a default fallback element; add an alt
attribute and maintain the existing className for the image. Implement a small
predicate (e.g. isValidImageUrl(icon)) or inline checks before using <img> so
empty strings or emoji won’t produce a broken image.

Comment on lines +40 to +45
const buildTestContext = ()=>{
const context: Record<string, any> = {};
for (const [nodeId, testOutput] of Object.entries(allTestedOutputs)){
if(testOutput.success && testOutput.data){
const normalizedName = testOutput.nodeName.toLowerCase().replace(/\s+/g, '_')
context[normalizedName] = testOutput.data

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Make the interpolation context stable.

Line 43 drops successful outputs like 0, false, or "", and Line 44 keys the context by normalized display name. Since this canvas can add the same action more than once, later test results overwrite earlier ones and variable resolution becomes ambiguous. The same normalization exists in ConfigModal.tsx, so both entry points need the same fix.

🤖 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 around lines 40 - 45, buildTestContext
currently drops successful but falsy outputs (0, false, "") by checking
testOutput.data truthiness and also overwrites keys when the same action
(normalized nodeName) appears multiple times; update buildTestContext to include
any testOutput where testOutput.success is true regardless of data value (do not
gate on testOutput.data truthiness) and create stable unique keys by combining
the normalized node name with the nodeId (e.g., `${normalizedName}__${nodeId}`)
or another stable unique identifier instead of using normalized name alone;
apply the identical change to the matching normalization/keying logic in
ConfigModal.tsx so both entry points produce the same stable interpolation
context and avoid silent overwrites.

Comment on lines +58 to +61
const interpolationContext = buildTestContext();
const resolvedConfig = resolveConfigVariables(savedConfig, interpolationContext);
console.log(resolvedConfig, "--from 60")
const response = await api.execute.node(nodeId,resolvedConfig);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Don't execute canvas tests with unresolved {{...}} values.

resolveConfigVariables preserves missing variables as raw template strings. This path sends resolvedConfig straight to api.execute.node, so testing before upstream nodes run can issue malformed requests instead of surfacing the warning the modal path already has.

🤖 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 around lines 58 - 61, The code calls
api.execute.node with resolvedConfig that may still contain unresolved template
strings because resolveConfigVariables preserves missing variables; before
calling api.execute.node (in the same block that uses buildTestContext,
resolveConfigVariables and resolvedConfig), detect unresolved templates (e.g.,
scan resolvedConfig for "{{" / "}}" or implement a small hasUnresolvedVariables
util), and if any are found, do not call api.execute.node — instead surface the
same warning/error flow used by the modal path (or throw/return early) so tests
aren't executed with raw template placeholders.

name: Trigger.name,
icon: Trigger.icon
}),
onTest: ( Trigger.name.toLowerCase() === 'webhook' ? undefined : ()=> testNodeFromCanvas(Trigger.TriggerId, Trigger.name, "trigger") )

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Use the actual created or loaded IDs in onTest.

Line 378 uses Trigger.TriggerId, Line 404 uses node.NodeId, Line 604 uses action.NodeId, and Line 696 uses trigger.TriggerId, but these branches are populated with id, actionId, or triggerId. Those callbacks will call the execute endpoint with undefined for DB-loaded or freshly added nodes.

Also applies to: 404-404, 604-604, 696-696

Comment on lines +51 to 52
icon String?
triggers Trigger[]

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Schema changes =="
rg -n 'icon\s+String\?' packages/db/prisma/schema.prisma

echo
echo "== Tracked migration files =="
fd . packages/db/prisma/migrations || true

echo
echo "== Repo commands that roll Prisma schema changes forward =="
rg -n 'prisma (migrate|db push|deploy)' -g 'package.json' -g '*.yml' -g '*.yaml' -g 'README*' .

echo
echo "== Ignore rules affecting Prisma migrations =="
rg -n 'packages/db/prisma/migrations|prisma/migrations' .gitignore

Repository: Dev-Pross/BuildFlow

Length of output: 450


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== CI/CD pipeline files =="
fd -e yml -e yaml . .github || echo "No .github workflows"

echo
echo "== Docker/deployment configs =="
fd -e dockerfile -e 'docker-compose*' . . || echo "No docker files found"

echo
echo "== Prisma deployment commands in package.json =="
jq '.scripts | keys[] | select(. | contains("prisma") or contains("migrate") or contains("deploy"))' package.json 2>/dev/null || echo "No scripts found or invalid JSON"

echo
echo "== Full package.json scripts section (filtered) =="
jq '.scripts' package.json 2>/dev/null | grep -E '(prisma|migrate|deploy)' || echo "No migration/deploy scripts in package.json"

Repository: Dev-Pross/BuildFlow

Length of output: 320


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Auto-approve workflow content =="
cat .github/workflows/auto-approve-after-coderabbit.yml 2>/dev/null | head -50

echo
echo "== All files in .github directory =="
fd . .github 2>/dev/null

echo
echo "== Any mention of migrate/deploy in .github =="
rg -r 'migrate|deploy|prisma db' .github 2>/dev/null || echo "No migration/deploy references found"

echo
echo "== Root-level config files (docker, deploy, etc) =="
ls -la | grep -E '(docker|deploy|Makefile|.env|.github)' || echo "None found"

echo
echo "== Check if migrations are generated at build time =="
rg -n 'prisma' packages/db/package.json || echo "No prisma references in db package.json"

Repository: Dev-Pross/BuildFlow

Length of output: 2435


Ensure the database schema rollout is coordinated with this code change.

userRoutes.ts reads AvailableTrigger.icon and AvailableNode.icon immediately upon deployment. The new icon columns exist in schema.prisma (lines 51, 63) but I found no production migration deployment mechanism. The migrations directory is gitignored (line 40), and the build script (packages/db/package.json) only runs prisma generate for client generation—not prisma migrate deploy or prisma db push. Without an explicit schema rollout step, the database may not have these columns when queries attempt to read them, causing runtime failures.

Confirm how schema changes are deployed to production (e.g., via a manual prisma db push during deployment, a separate migration deployment step, or documentation on the deployment process).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/db/prisma/schema.prisma` around lines 51 - 52, The code reads
AvailableTrigger.icon and AvailableNode.icon at startup but the new icon columns
may not exist in production because migrations are ignored and the build only
runs prisma generate; to fix this, ensure schema rollout is coordinated by (1)
creating and committing a proper Prisma migration for the icon fields (or
otherwise keeping a canonical migration history instead of ignoring the
migrations directory), (2) adding a deployment step that runs "prisma migrate
deploy" (or "prisma db push" if you accept destructive sync) as part of CI/CD or
the packages/db/package.json build script, and (3) documenting the chosen
process in repo docs; update CI/deploy config to run the migration step before
starting services that import userRoutes.ts so AvailableTrigger.icon and
AvailableNode.icon exist at runtime.

@Vamsi-o Vamsi-o left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Potential issue | 🟠 Major

Render the header icon defensively.

selectedNode.icon is not always an image URL here. The workflow page still uses emoji fallbacks like ⚡ and ⚙️, and it can also surface an empty string from store state, so Line 419 will show a broken image for common nodes.

@Vamsi-o Vamsi-o merged commit cd56ebc into main Mar 13, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants