Skip to Content

Parallel Workflow Strategy: Meeting in the Middle

Parallel Workflow Strategy: Meeting in the Middle

Date: 2025-09-30
Objective: Both work simultaneously toward node creation on canvas
Meeting Point: The bridge method that connects overlay → node manager


The Strategy

YOU (Overlay Direction)          CLAUDE (Node Manager Direction)
        ↓                                      ↓
┌──────────────────────┐          ┌──────────────────────┐
│  overlay_manager.js  │          │  node_manager.js     │
│  Line 3401           │          │  Add bridge method   │
└──────────┬───────────┘          └─────────┬────────────┘
           │                                 │
           │  Modify selectOperation()       │  Add addNodeFromN8nJSON()
           │  to call bridge method          │  to accept n8n format
           │                                 │
           ▼                                 ▼
        ┌──────────────────────────────────────┐
        │      MEETING POINT: Node Creation    │
        │   window.nodeManager.addNodeFromN8nJSON(nodeData)   │
        └──────────────────────────────────────┘

Your Work (Overlay Direction)

File: overlay_manager.js

Focus: Finalize the overlay menu and modify line 3401 to call the bridge method

Your Tasks:

1. Current Line 3401 (selectOperation method)

// CURRENT CODE (Line 3401):
alert(`Canvas JSON Generated!\n\n${JSON.stringify(canvasNodeJSON, null, 2)}\n\nNext: Add to canvas!`);

2. Your Target Code

// NEW CODE - What you'll change line 3401 to:

// Add node to canvas via NodeManager
if (window.nodeManager && window.nodeManager.initialized) {
    // Extract node data from workflow JSON
    const nodeData = canvasNodeJSON.nodes[0];

    // Smart positioning: Place near last node if exists
    if (window.nodeManager.nodes.size > 0) {
        const lastNode = Array.from(window.nodeManager.nodes.values()).pop();
        nodeData.position = {
            x: lastNode.position.x + 250,
            y: lastNode.position.y
        };
    }

    // Call bridge method (Claude is adding this to node_manager.js)
    window.nodeManager.addNodeFromN8nJSON(nodeData);

    console.log('✅ Node added to canvas:', nodeData.name);

    // Optional: Brief success feedback
    this.showSuccessToast(`✅ ${nodeData.name} added to canvas`);
} else {
    console.error('❌ NodeManager not initialized');
    alert('Error: NodeManager not ready. Please check console.');
}

// Close overlay
this.closeN8nOverlay();

3. Optional: Add Success Toast Method

// Add this method to OverlayManager class (anywhere before the closing brace)

/**
 * Show brief success toast notification
 */
showSuccessToast(message) {
    const toast = document.createElement('div');
    toast.style.cssText = `
        position: fixed;
        top: 20px;
        right: 20px;
        background: #28a745;
        color: white;
        padding: 12px 20px;
        border-radius: 4px;
        box-shadow: 0 4px 12px rgba(0,0,0,0.3);
        z-index: 10000;
        font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
        font-size: 14px;
        animation: slideInRight 0.3s ease-out;
    `;
    toast.textContent = message;
    document.body.appendChild(toast);

    // Auto-remove after 2 seconds
    setTimeout(() => {
        toast.style.animation = 'slideOutRight 0.3s ease-in';
        setTimeout(() => toast.remove(), 300);
    }, 2000);
}

4. Testing Your Changes

Test Plan:

// In browser console, test that your modification works:

// 1. Check NodeManager is available
console.log('NodeManager ready?', window.nodeManager?.initialized);

// 2. Mock n8n JSON (simulate what overlay generates)
const mockNodeData = {
    id: "test-node-123",
    name: "Test Gmail Node",
    type: "n8n-nodes-base.gmail",
    typeVersion: 1,
    position: [100, 100],
    parameters: {
        resource: "message",
        operation: "send"
    }
};

// 3. Test the bridge method (after Claude adds it)
window.nodeManager.addNodeFromN8nJSON(mockNodeData);
// Expected: Node appears on canvas

// 4. Verify node was created
console.log('Nodes count:', window.nodeManager.nodes.size);
window.nodeManager.getAllNodes().forEach(n => console.log(n.name));

Your Workflow Checklist

  • [ ] Open overlay_manager.js in your editor
  • [ ] Navigate to line 3401 (in selectOperation() method)
  • [ ] Replace the alert() line with the new code above
  • [ ] (Optional) Add showSuccessToast() method to OverlayManager class
  • [ ] Save file
  • [ ] Wait for Claude to add bridge method to node_manager.js
  • [ ] Test in browser: Click N8N button → Select node → Should appear on canvas
  • [ ] Verify with console commands

Claude's Work (Node Manager Direction)

File: node_manager.js

Focus: Add bridge methods to accept n8n-format JSON from overlay

Tasks:

1. Add Bridge Method (After line 306)

/**
 * Add node from n8n JSON format (from overlay manager)
 * Converts n8n node format to internal NodeManager format
 *
 * @param {Object} n8nNodeData - Node data in n8n format
 * @returns {Object} Created node
 */
addNodeFromN8nJSON(n8nNodeData) {
    console.log('➕ Adding node from n8n JSON:', n8nNodeData);

    // Validate input
    if (!n8nNodeData || !n8nNodeData.type) {
        console.error('❌ Invalid n8n node data:', n8nNodeData);
        return null;
    }

    // Extract n8n data with defaults
    const n8nType = n8nNodeData.type || 'n8n-nodes-base.unknown';
    const n8nName = n8nNodeData.name || 'Untitled Node';
    const n8nPosition = n8nNodeData.position || [100, 100];
    const n8nParameters = n8nNodeData.parameters || {};

    // Determine node type (trigger vs action)
    let nodeType = 'action';  // Default to action
    const lowerType = n8nType.toLowerCase();

    // Check for trigger indicators in n8n type
    if (lowerType.includes('trigger') ||
        lowerType.includes('webhook') ||
        lowerType.includes('schedule') ||
        lowerType.includes('poll')) {
        nodeType = 'trigger';
    }

    // Convert n8n position format [x, y] to { x, y }
    const position = {
        x: Array.isArray(n8nPosition) ? n8nPosition[0] : (n8nPosition.x || 100),
        y: Array.isArray(n8nPosition) ? n8nPosition[1] : (n8nPosition.y || 100)
    };

    // Build config for internal createNode method
    const config = {
        name: n8nName,
        description: this.buildNodeDescription(n8nParameters),
        parameters: n8nParameters,
        n8nType: n8nType,  // Store original n8n type for reference
        n8nId: n8nNodeData.id,  // Store original n8n ID if provided
        typeVersion: n8nNodeData.typeVersion || 1,
        status: 'ready'
    };

    // Create node using existing createNode method
    const node = this.createNode(nodeType, position, config);

    console.log(`✅ Added n8n node: ${n8nName} (Type: ${n8nType}, Internal Type: ${nodeType})`);

    // Return created node
    return node;
}

2. Add Description Builder Helper

/**
 * Build a readable description from n8n parameters
 *
 * @param {Object} parameters - n8n node parameters
 * @returns {string} Human-readable description
 */
buildNodeDescription(parameters) {
    if (!parameters || Object.keys(parameters).length === 0) {
        return '';
    }

    // Extract key parameters for description
    const parts = [];

    if (parameters.resource) {
        parts.push(`Resource: ${parameters.resource}`);
    }

    if (parameters.operation) {
        parts.push(`Operation: ${parameters.operation}`);
    }

    // Add other relevant parameters
    const relevantKeys = ['action', 'event', 'method', 'endpoint'];
    relevantKeys.forEach(key => {
        if (parameters[key]) {
            parts.push(`${key.charAt(0).toUpperCase() + key.slice(1)}: ${parameters[key]}`);
        }
    });

    return parts.join(' | ');
}

3. Add Batch Import Method

/**
 * Add multiple nodes from n8n workflow JSON
 *
 * @param {Object} workflowJSON - Complete n8n workflow with nodes array
 * @returns {Array} Array of created nodes
 */
addNodesFromN8nWorkflow(workflowJSON) {
    console.log('➕ Adding nodes from n8n workflow:', workflowJSON);

    // Validate workflow structure
    if (!workflowJSON || !workflowJSON.nodes || !Array.isArray(workflowJSON.nodes)) {
        console.error('❌ Invalid workflow JSON: missing nodes array');
        return [];
    }

    const createdNodes = [];

    // Create each node
    workflowJSON.nodes.forEach((nodeData, index) => {
        try {
            const node = this.addNodeFromN8nJSON(nodeData);
            if (node) {
                createdNodes.push(node);
            }
        } catch (error) {
            console.error(`❌ Failed to create node ${index}:`, error, nodeData);
        }
    });

    console.log(`✅ Added ${createdNodes.length} of ${workflowJSON.nodes.length} nodes from workflow`);

    // TODO: Handle connections from workflowJSON.connections (Phase 5)

    return createdNodes;
}

4. Testing Methods

Test Plan:

// Test with mock n8n data

// Test 1: Single node (Action)
const gmailNode = {
    id: "test-gmail-001",
    name: "Send Email",
    type: "n8n-nodes-base.gmail",
    typeVersion: 1,
    position: [150, 150],
    parameters: {
        resource: "message",
        operation: "send"
    }
};

window.nodeManager.addNodeFromN8nJSON(gmailNode);
// Expected: Blue action node with "Send Email" appears

// Test 2: Trigger node
const webhookNode = {
    id: "test-webhook-001",
    name: "Webhook Trigger",
    type: "n8n-nodes-base.webhook",
    typeVersion: 1,
    position: [150, 300],
    parameters: {
        path: "/webhook",
        method: "POST"
    }
};

window.nodeManager.addNodeFromN8nJSON(webhookNode);
// Expected: Green trigger node with "Webhook Trigger" appears

// Test 3: Batch import
const workflow = {
    nodes: [gmailNode, webhookNode],
    connections: {},
    meta: {}
};

window.nodeManager.addNodesFromN8nWorkflow(workflow);
// Expected: Both nodes appear

// Test 4: Verify nodes
console.log('Total nodes:', window.nodeManager.nodes.size);
window.nodeManager.getAllNodes().forEach(n => {
    console.log(`${n.name} - Type: ${n.type}, n8n Type: ${n.n8nType}`);
});

Claude's Workflow Checklist

  • [x] ✅ Read current node_manager.js structure
  • [ ] Add addNodeFromN8nJSON() method after line 306
  • [ ] Add buildNodeDescription() helper method
  • [ ] Add addNodesFromN8nWorkflow() batch method
  • [ ] Add inline documentation/comments
  • [ ] Test with mock n8n JSON data
  • [ ] Verify node type detection (trigger vs action)
  • [ ] Verify position conversion ([x,y] → {x,y})
  • [ ] Handle edge cases (missing data, invalid format)

Meeting Point: Integration Test

When You Both Finish

Integration Test Scenario:

  1. You (Overlay): User clicks N8N button → Selects Gmail → Selects "Send Message"
  2. Overlay generates:
    json { "nodes": [{ "id": "uuid-123", "name": "Send Message", "type": "n8n-nodes-base.gmail", "typeVersion": 1, "position": [250, 250], "parameters": { "resource": "message", "operation": "send" } }] }
  3. Your code calls: window.nodeManager.addNodeFromN8nJSON(nodeData)
  4. Claude's method receives: The nodeData object
  5. Claude's method processes:
  6. Detects type: "action" (not a trigger)
  7. Converts position: [250, 250] → { x: 250, y: 250 }
  8. Builds description: "Resource: message | Operation: send"
  9. Claude's method calls: this.createNode('action', {x: 250, y: 250}, config)
  10. Result: Blue action node appears on canvas with "Send Message" label

Success Criteria

✅ Working when:
- Click N8N button → menu opens
- Select any node → menu closes
- Node appears on canvas at correct position
- Node shows correct name and type
- Node is interactive (can click, drag, delete)
- Console shows: "✅ Added n8n node: [name]"
- Multiple nodes can be added without conflicts

❌ Not working if:
- Console shows: "❌ NodeManager not initialized"
- Console shows: "undefined is not a function"
- Node doesn't appear on canvas
- Node appears but can't be interacted with
- Page errors or crashes


Communication Protocol

What You Should Tell Claude

After you finish your changes:

"I've modified overlay_manager.js line 3401.
The selectOperation() method now calls:
window.nodeManager.addNodeFromN8nJSON(nodeData)

I tested with console and nodeManager is initialized.
Ready for you to add the bridge method."

What Claude Will Tell You

After adding bridge methods:

"I've added addNodeFromN8nJSON() to node_manager.js at line 307.
The method accepts n8n format and converts to internal format.
Tested with mock data and nodes render correctly.
Ready for your overlay to call it."

Integration Testing Together

Once both sides are done:

  1. You open the page in browser
  2. Open console (F12)
  3. Click N8N button
  4. Select a node (e.g., Gmail → Send Email)
  5. Report what happens:
  6. ✅ Node appears → Success!
  7. ❌ Error in console → Share the error
  8. ❌ Nothing happens → Check window.nodeManager.initialized

Conflict Resolution

If Something Doesn't Work

Scenario 1: Method Not Found

Error: window.nodeManager.addNodeFromN8nJSON is not a function

Cause: Claude hasn't added the method yet, or file not loaded
Solution: Claude adds method, refresh page

Scenario 2: NodeManager Not Initialized

Error: Cannot read property 'initialized' of undefined

Cause: NodeManager not initialized before overlay calls it
Solution: Check initialization order in main file

Scenario 3: Node Appears but Wrong Type

Node appears as blue action when it should be green trigger

Cause: Type detection logic in addNodeFromN8nJSON
Solution: Claude adjusts trigger detection conditions

Scenario 4: Position Wrong

Node appears at [0,0] or NaN,NaN

Cause: Position conversion issue
Solution: Claude adds better position validation/defaults


Advantages of Parallel Workflow

✅ Speed: Both work simultaneously → Faster completion

✅ Separation of Concerns:
- You focus on overlay (UI/UX)
- Claude focuses on node manager (data processing)

✅ Testing: Each side can test independently before integration

✅ Clear Interface: The bridge method is the contract between both sides

✅ Rollback Safety: Changes isolated to specific files


Next Steps After Integration

Phase 5: Connection Lines (Next Session)

Once nodes appear on canvas, the next step is connecting them:

  1. Claude: Add SVG connection layer
  2. Claude: Add connection creation methods
  3. Claude: Add drag-to-connect from ports
  4. You: Test connection UI
  5. Both: Handle n8n connections JSON format

Phase 6: Backend Persistence

Save/load workflows to Odoo database:

  1. You: Python controller endpoints
  2. Claude: JavaScript save/load methods
  3. Both: Test workflow persistence

Timeline Estimate

Your Work (Overlay):
- Modify line 3401: 5-10 minutes
- Add success toast (optional): 10 minutes
- Test in browser: 10-15 minutes
- Total: 25-35 minutes

Claude's Work (Node Manager):
- Add bridge method: 10 minutes
- Add helper methods: 10 minutes
- Add tests/comments: 10 minutes
- Mock testing: 10 minutes
- Total: 40 minutes

Integration Testing:
- First test: 10 minutes
- Debug if needed: 10-20 minutes
- Final verification: 10 minutes
- Total: 30-40 minutes

Grand Total: 95-115 minutes (~1.5-2 hours)


Ready to Start?

Your Mission: Modify overlay_manager.js line 3401 to call the bridge method

Claude's Mission: Add addNodeFromN8nJSON() and helpers to node_manager.js

Meeting Point: window.nodeManager.addNodeFromN8nJSON(nodeData)

Let me know when you're ready, and we'll both start working from our directions! 🚀

Was this helpful?