12 KiB
phase, plan, type, wave, depends_on, files_modified, autonomous, gap_closure, must_haves
| phase | plan | type | wave | depends_on | files_modified | autonomous | gap_closure | must_haves | ||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 10.1-aggressive-workflow-modularization | 06 | execute | 1 |
|
true | true |
|
Purpose: Close Gap 1 from VERIFICATION.md (node count target). While the 115-125 target is structurally unachievable (86 nodes are locked to main), extracting matching completes the extraction of all viable domains and reduces main workflow complexity.
Output: n8n-matching.json sub-workflow + updated n8n-workflow.json
<execution_context> @/home/luc/.claude/get-shit-done/workflows/execute-plan.md @/home/luc/.claude/get-shit-done/templates/summary.md </execution_context>
@.planning/PROJECT.md @.planning/ROADMAP.md @.planning/STATE.md @.planning/phases/10.1-aggressive-workflow-modularization/10.1-01-domain-analysis.md @.planning/phases/10.1-aggressive-workflow-modularization/10.1-02-SUMMARY.md @.planning/phases/10.1-aggressive-workflow-modularization/10.1-04-SUMMARY.md @n8n-workflow.json @n8n-actions.json Task 1: Create n8n-matching.json sub-workflow n8n-matching.json Create a new n8n-matching.json sub-workflow that encapsulates container matching and disambiguation logic. Follow the exact same patterns used in n8n-confirmation.json, n8n-batch-ui.json, and n8n-status.json (action-based return pattern).Sub-workflow structure:
-
Execute Workflow Trigger — Entry point receiving inputs
-
Input contract:
action: one of "match_action", "match_update", "match_batch"containerList: JSON array of containers from Docker APIsearchTerm: container name to match (for action/update)selectedContainers: CSV of selected containers (for batch)chatId,messageId: for context passing
-
Route Action (Switch node) — Routes by action field to appropriate matching logic
-
Logic nodes to include (extract from main workflow):
Match Container(code) — Fuzzy matches container name against list for action commandsMatch Update Container(code) — Fuzzy matches for update commandsMatch Batch Containers(code) — Matches batch-selected containers against Docker listCheck Match Count(switch) — Routes by match count (0, 1, 2+)Check Update Match Count(switch) — Routes by update match countFind Closest Match(code) — Finds closest match for suggestionsCheck Suggestion(if) — Checks if suggestion is close enoughBuild Suggestion Keyboard(code) — Builds inline keyboard for suggestionBuild Disambiguation Message(code) — Builds disambiguation textBuild Not Found Message(code) — Builds not-found message textNeeds Disambiguation(if) — Checks if batch has ambiguous matchesHas Not Found(if) — Checks if batch has not-found containers
-
Return pattern (action-based, like other sub-workflows): Each exit path returns a JSON object with an
actionfield that the main workflow routes on:action: "matched"+containerId,containerName— Single match foundaction: "matched_update"+containerId,containerName— Single update match foundaction: "multiple_update"+matches— Multiple update matches (for Handle Update Multiple)action: "suggestion"+keyboard,text— Close match suggestion to displayaction: "no_match"— No match and no suggestionaction: "disambiguation"+text— Disambiguation message to displayaction: "not_found"+text,keyboard— Batch not-found messageaction: "batch_matched"+matchedContainers— Batch containers matched successfullyaction: "error"+errorMessage— Docker list erroraction: "no_match_update"— No update match found
CRITICAL: Copy the actual JavaScript code from each Code node in n8n-workflow.json. Do NOT rewrite or approximate the logic. Read the jsCode property from each node's parameters and transplant it exactly, adjusting only input references (change $json or $('Node Name').item.json references to use the sub-workflow's input data).
Follow existing sub-workflow patterns:
- Use typeVersion that matches existing sub-workflows (check n8n-confirmation.json for reference)
- Include proper metadata (name: "Container Matching", tags, etc.)
- Position nodes in a readable layout (increment x/y coordinates)
Do NOT include Telegram response nodes — per locked decision, Send Disambiguation, Send Suggestion, Send No Match, Send Not Found Message, Send Update No Match, and Delete Suggestion Message stay in main workflow. Verify with Python script:
- n8n-matching.json is valid JSON
- Has Execute Workflow Trigger node
- Has Switch/Route node for action routing
- Contains all 12 logic nodes (Match Container, Match Update Container, Match Batch Containers, Check Match Count, Check Update Match Count, Find Closest Match, Check Suggestion, Build Suggestion Keyboard, Build Disambiguation Message, Build Not Found Message, Needs Disambiguation, Has Not Found)
- All Code nodes have non-empty jsCode
- No Telegram/HTTP Send nodes in sub-workflow n8n-matching.json exists with 14-16 nodes (12 logic + trigger + router + any merge nodes), valid JSON, all matching logic transplanted from main workflow
Step 2: Remove extracted nodes Remove the 12 matching logic nodes from n8n-workflow.json:
- Match Container, Match Update Container, Match Batch Containers
- Check Match Count, Check Update Match Count
- Find Closest Match, Check Suggestion
- Build Suggestion Keyboard, Build Disambiguation Message, Build Not Found Message
- Needs Disambiguation, Has Not Found
Step 3: Add integration nodes
The matching domain has 3 distinct entry points. Create integration for each:
Entry 1: Action matching (text command like "stop nginx")
- Add
Prepare Action Match Input(Code node) — Takes output fromDocker List for Action, prepares: action="match_action", containerList, searchTerm from parsed command, chatId, messageId - Add
Execute Action Match(Execute Workflow node) — Calls n8n-matching.json with TODO_DEPLOY_MATCHING_WORKFLOW placeholder. Use typeVersion 1.2 withworkflowId: { "__rl": true, "mode": "list", "value": "TODO_DEPLOY_MATCHING_WORKFLOW" } - Add
Route Action Match Result(Switch node) — Routes by returned action field:- "matched" ->
Prepare Text Action Input(existing) - "suggestion" ->
Send Suggestion(existing Telegram node) - "no_match" ->
Send No Match(existing Telegram node) - "disambiguation" ->
Send Disambiguation(existing HTTP node) - "error" ->
Send Docker Error(existing)
- "matched" ->
Entry 2: Update matching (text command like "update nginx")
- Add
Prepare Update Match Input(Code node) — Takes output fromDocker List for Update, prepares: action="match_update", containerList, searchTerm, chatId, messageId - Add
Execute Update Match(Execute Workflow node) — Calls n8n-matching.json - Add
Route Update Match Result(Switch node) — Routes by returned action:- "matched_update" ->
Prepare Text Update Input(existing) - "multiple_update" ->
Handle Update Multiple(existing) - "no_match_update" ->
Send Update No Match(existing) - "error" ->
Send Update Error(existing)
- "matched_update" ->
Entry 3: Batch matching
- Add
Prepare Batch Match Input(Code node) — Takes output fromGet Containers for Batch, prepares: action="match_batch", containerList, selectedContainers, chatId, messageId - Add
Execute Batch Match(Execute Workflow node) — Calls n8n-matching.json - Add
Route Batch Match Result(Switch node) — Routes by returned action:- "batch_matched" ->
Build Batch Keyboard(existing) or equivalent downstream - "disambiguation" ->
Send Disambiguation(existing) - "not_found" ->
Send Not Found Message(existing) then ->Route Batch Action(existing)
- "batch_matched" ->
Step 4: Rewire connections
Docker List for Action->Prepare Action Match Input->Execute Action Match->Route Action Match Result-> (existing targets)Docker List for Update->Prepare Update Match Input->Execute Update Match->Route Update Match Result-> (existing targets)Get Containers for Batch->Prepare Batch Match Input->Execute Batch Match->Route Batch Match Result-> (existing targets)- Remove old connections from Docker List nodes to removed matching nodes
- Preserve all connections from Telegram response nodes (Send Disambiguation, etc.) to their downstream targets
Step 5: Update Answer Action Query connection
Currently Answer Action Query -> Delete Suggestion Message. This connection stays as-is since Delete Suggestion Message remains in main workflow.
Node count verification:
- Removed: 12 nodes
- Added: 9 nodes (3 Prepare + 3 Execute + 3 Route)
- Net reduction: 3 nodes (168 -> ~165)
- 6 Telegram response nodes remain in main (as required by locked decision)
IMPORTANT: Maintain exact connection format used in existing workflow. Check existing Execute Workflow nodes (e.g., Execute Confirmation, Execute Batch UI) for correct connection structure, parameter format, and typeVersion. Verify with Python script:
- n8n-workflow.json is valid JSON
- Backup file exists at n8n-workflow.json.backup-matching
- Node count is 165 or fewer (168 - 12 removed + 9 added = 165)
- None of the 12 removed nodes exist in main workflow
- 3 Execute Workflow nodes reference TODO_DEPLOY_MATCHING_WORKFLOW (or actual ID)
- All 6 Telegram response nodes (Send Disambiguation, Send Suggestion, Send No Match, Send Not Found Message, Send Update No Match, Delete Suggestion Message) still exist
- No orphan nodes (every node has at least one connection in or out, except trigger)
- All existing Execute Workflow nodes for other sub-workflows still present (14 original) Main workflow updated with matching sub-workflow calls, 12 logic nodes removed, 9 integration nodes added, 6 Telegram response nodes preserved, backup created, all connections properly wired
<success_criteria>
- n8n-matching.json exists with all 12 matching logic nodes transplanted
- Main workflow reduced from 168 to ~165 nodes
- All 3 matching entry paths (action, update, batch) routed through sub-workflow
- 6 Telegram response nodes remain in main workflow per locked decision
- Backup file created before modification
- Both workflow files are valid JSON with no orphan nodes </success_criteria>