--- phase: 10-workflow-modularization plan: 02 type: execute wave: 2 depends_on: [10-01] files_modified: [n8n-workflow.json, n8n-container-update.json] autonomous: true must_haves: truths: - "Single container update via text command works" - "Single container update via inline keyboard works" - "Batch update operations work" - "Update flow exists in one place only (sub-workflow)" artifacts: - path: "n8n-container-update.json" provides: "Container update sub-workflow" contains: "executeWorkflowTrigger" - path: "n8n-workflow.json" provides: "Main workflow calling update sub-workflow" contains: "executeWorkflow" key_links: - from: "n8n-workflow.json" to: "n8n-container-update.json" via: "Execute Sub-workflow node" pattern: "executeWorkflow.*container-update" --- Extract the container update flow into a dedicated sub-workflow to consolidate duplicated code (DEBT-03). Purpose: The update logic is currently duplicated between the text command path (~lines 1656-2400) and the callback/inline keyboard path (~lines 3628-4010). Extracting to a sub-workflow creates a single source of truth, reduces main workflow complexity, and makes the update logic independently testable. Output: New container-update sub-workflow JSON file and updated main workflow that calls it from both text and callback paths. @/home/luc/.claude/get-shit-done/workflows/execute-plan.md @/home/luc/.claude/get-shit-done/templates/summary.md @.planning/PROJECT.md @.planning/ROADMAP.md @.planning/phases/10-workflow-modularization/10-RESEARCH.md @.planning/phases/10-workflow-modularization/10-01-SUMMARY.md @n8n-workflow.json Task 1: Create container-update sub-workflow n8n-container-update.json Create a new sub-workflow file `n8n-container-update.json` that encapsulates the entire container update flow. **Input contract (Execute Sub-workflow Trigger with defined fields):** ```json { "containerId": "string - Docker container ID", "containerName": "string - Container name for messages", "chatId": "number - Telegram chat ID", "messageId": "number - Message ID for inline edits (0 for text mode)", "responseMode": "string - 'text' or 'inline'" } ``` **Flow to extract (from research):** 1. Inspect container configuration (get current image, config, host config) 2. Pull latest image (with :latest tag protection) 3. Inspect new image and compare digests 4. If update needed: - Stop container - Remove old container - Create new container with same config - Start new container 5. Clean up old image 6. Return result **Output contract:** ```json { "success": "boolean", "message": "string - Result message for user", "updated": "boolean - Whether update was performed", "oldDigest": "string (optional)", "newDigest": "string (optional)" } ``` **Implementation notes:** - Use "Define using fields" schema type for input contract (per research best practice) - Include progress message editing for inline mode (messageId > 0) - Include new message sending for text mode (messageId == 0) - Handle both "update needed" and "already up to date" cases - Preserve :latest tag protection (default to :latest if no tag) - Preserve image cleanup after successful update - JSON file is valid: `python3 -c "import json; json.load(open('n8n-container-update.json'))"` - Contains "executeWorkflowTrigger" node - Has proper input schema with all 5 fields Container update sub-workflow created with proper input/output contracts Task 2: Wire main workflow to use sub-workflow n8n-workflow.json Modify the main workflow to call the container-update sub-workflow instead of having inline update logic. **Changes needed:** 1. **Text command path:** - Find the text update flow (around the "Update Container" text command routing) - Replace inline update nodes with: a. Code node to prepare sub-workflow input (containerId, containerName, chatId, messageId=0, responseMode='text') b. Execute Sub-workflow node pointing to container-update workflow - Remove the duplicate update logic nodes from text path 2. **Callback/inline path:** - Find the callback update flow (around "Handle Update Action" or similar) - Replace inline update nodes with: a. Code node to prepare sub-workflow input (containerId, containerName, chatId, messageId from callback, responseMode='inline') b. Execute Sub-workflow node pointing to container-update workflow - Remove the duplicate update logic nodes from callback path 3. **Batch update path:** - Find where batch update calls individual container updates - Ensure it also uses the sub-workflow (may already be structured to call the same code) **Execute Sub-workflow node configuration:** ```json { "parameters": { "source": "database", "workflowId": "", "mode": "once", "options": { "waitForSubWorkflow": true } }, "type": "n8n-nodes-base.executeWorkflow" } ``` **Important:** After extraction, the main workflow should be significantly shorter (estimate ~750 fewer lines per research). - Main workflow JSON is valid - Contains "executeWorkflow" node(s) for update paths - Old inline update nodes are removed (workflow is shorter) Main workflow updated to call container-update sub-workflow from all update paths Task 3: Deploy and verify update functionality n8n-workflow.json, n8n-container-update.json Deploy both workflows to n8n and verify all update paths work. **Deployment steps:** 1. Import container-update sub-workflow to n8n via API (create new workflow) 2. Note the workflow ID assigned by n8n 3. Update main workflow's Execute Sub-workflow node(s) with correct workflow ID 4. Deploy main workflow update to n8n via API **Verification tests:** 1. **Text command update:** - Send "update " to bot - Should show update confirmation prompt - Confirm and verify update completes (or shows "already up to date") 2. **Inline keyboard update:** - Use /status to get container list - Select a container - Tap "Update" button - Should show confirmation dialog - Confirm and verify update completes with progress messages 3. **Batch update (if time permits):** - Initiate a batch update for 2 containers - Verify both update correctly - Sub-workflow imported and has valid ID in n8n - Main workflow deployed with correct sub-workflow reference - Text "update " command works - Inline keyboard update flow works - Progress messages display correctly Update sub-workflow deployed and all update paths verified working 1. n8n-container-update.json exists and is valid JSON 2. Sub-workflow has proper Execute Sub-workflow Trigger with input schema 3. Main workflow contains Execute Sub-workflow nodes calling update workflow 4. Main workflow line count reduced by ~500+ lines 5. Text command "update " works end-to-end 6. Inline keyboard update with confirmation works end-to-end 7. "Already up to date" case handled correctly 8. Old image cleanup still occurs after successful update - Container update logic exists in ONE place (sub-workflow) - Both text and inline update paths use the sub-workflow - DEBT-03 (duplicated update flow) resolved - All update functionality works as before After completion, create `.planning/phases/10-workflow-modularization/10-02-SUMMARY.md`