docs(10.1): create UAT gap closure plans (08-09)

This commit is contained in:
Lucas Berger
2026-02-08 09:35:34 -05:00
parent b74fb3c19c
commit f3ab7cf312
3 changed files with 370 additions and 3 deletions
@@ -0,0 +1,212 @@
---
phase: 10.1-aggressive-workflow-modularization
plan: 09
type: execute
wave: 1
depends_on: []
files_modified: [n8n-workflow.json]
autonomous: true
gap_closure: true
must_haves:
truths:
- "Multiple container matches show disambiguation keyboard with correct action in button text"
- "Cancel button on confirmation dialog returns to container status view"
- "/list command shows container list (or documented as /status)"
artifacts:
- path: "n8n-workflow.json"
provides: "Build Batch Keyboard with correct actionType reference"
contains: "$json.actionType"
- path: "n8n-workflow.json"
provides: "Build Cancel Return Submenu with dynamic input reference"
contains: "$input.item.json"
- path: "n8n-workflow.json"
provides: "Keyword Router with list command handling"
contains: "list"
key_links:
- from: "Build Batch Keyboard"
to: "actionType field"
via: "$json.actionType (not $json.action)"
pattern: "\\$json\\.actionType"
- from: "Build Cancel Return Submenu"
to: "dynamic predecessor data"
via: "$input.item.json (not hardcoded node reference)"
pattern: "\\$input\\.item\\.json"
---
<objective>
Fix three data flow bugs in main workflow: Build Batch Keyboard reading wrong field, Build Cancel Return Submenu referencing wrong predecessor, and Keyword Router missing /list command.
Purpose: Close UAT gaps for disambiguation keyboard, confirmation cancel, and /list command
Output: Updated n8n-workflow.json with corrected node logic
</objective>
<execution_context>
@/home/luc/.claude/get-shit-done/workflows/execute-plan.md
@/home/luc/.claude/get-shit-done/templates/summary.md
</execution_context>
<context>
@.planning/PROJECT.md
@.planning/ROADMAP.md
@.planning/STATE.md
@.planning/phases/10.1-aggressive-workflow-modularization/10.1-UAT.md
@.planning/phases/10.1-aggressive-workflow-modularization/10.1-CONTEXT.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
</context>
<tasks>
<task type="auto">
<name>Task 1: Fix Build Batch Keyboard to use actionType field</name>
<files>n8n-workflow.json</files>
<action>
Update **Build Batch Keyboard** Code node (id: code-build-batch-keyboard) in n8n-workflow.json:
**Current code reads:**
```javascript
const action = $json.action; // This is "multiple" - the routing label
```
**Change to:**
```javascript
const action = $json.actionType; // This contains the actual action: stop/start/restart/update
```
**Why:** When the matching sub-workflow returns `action: "multiple"` (indicating multiple matches found), it also includes `actionType` with the user's requested action (e.g., "stop"). The keyboard builder needs the actual action for:
1. Button callback_data: `bexec:{action}:{containerId}:all`
2. Message text: "Found multiple containers matching '{term}'. Select containers to {action}:"
Using `$json.action` produces "multiple all?" as button text and `bexec:multiple:...` callbacks which won't be recognized.
**Location:** Find node with `"id": "code-build-batch-keyboard"` and update its JavaScript code parameter.
</action>
<verify>
1. Read n8n-workflow.json and find node with id "code-build-batch-keyboard"
2. Verify code contains `const action = $json.actionType;`
3. Verify no other references to `$json.action` in the action variable assignment
</verify>
<done>Build Batch Keyboard node reads actionType field instead of action field for constructing disambiguation keyboard</done>
</task>
<task type="auto">
<name>Task 2: Fix Build Cancel Return Submenu to use dynamic input</name>
<files>n8n-workflow.json</files>
<action>
Update **Build Cancel Return Submenu** Code node (id: code-build-cancel-return-submenu) in n8n-workflow.json:
**Current code reads:**
```javascript
const data = $('Prepare Cancel Return').item.json;
```
**Change to:**
```javascript
const data = $input.item.json;
```
**Why:** This node has two incoming paths:
1. From "Prepare Cancel Return" (batch cancel path)
2. From "Prepare Cancel From Confirm" (confirmation dialog cancel path)
The hardcoded node reference `$('Prepare Cancel Return')` only works for path 1. When user cancels from confirmation dialog, the data flows through "Prepare Cancel From Confirm" instead, causing the node reference to fail.
Both predecessors output the same data structure (containerId, containerName, chatId, messageId, queryId, page), so using `$input.item.json` works for both paths.
**Location:** Find node with `"id": "code-build-cancel-return-submenu"` and update its JavaScript code parameter.
</action>
<verify>
1. Read n8n-workflow.json and find node with id "code-build-cancel-return-submenu"
2. Verify code contains `const data = $input.item.json;`
3. Verify the node has connections from both "Prepare Cancel Return" and "Prepare Cancel From Confirm"
</verify>
<done>Build Cancel Return Submenu node uses dynamic $input reference instead of hardcoded predecessor, allowing it to work with both cancel paths</done>
</task>
<task type="auto">
<name>Task 3: Add /list command to Keyword Router</name>
<files>n8n-workflow.json</files>
<action>
Update **Keyword Router** Switch node (id: switch-keyword-router) in n8n-workflow.json:
**Current routes:** status, restart, start, stop, update, update all, logs, (default to "Show Menu")
**Decision:** Add "list" as an alias that routes to the same output as "status".
**Implementation:** Find the switch node rules array and add a new rule:
```json
{
"type": "string",
"value": "list",
"output": 0
}
```
Where `output: 0` matches the same output index as the "status" rule (both should route to the same node - likely "Prepare Status Input" or similar).
**Rationale:** The "status" command with no arguments already correctly displays the container list (per UAT note "Accessed via 'status' command (no args), not /list. Pagination works."). Adding "list" as an alias provides the user-expected command while leveraging existing functionality.
**Alternative if routing proves complex:** Instead of adding the route, document in verification that "/status" is the correct command for listing containers, and suggest updating any user-facing help text to clarify this.
**Location:** Find node with `"id": "switch-keyword-router"` and update its routing rules.
</action>
<verify>
1. Read n8n-workflow.json and find node with id "switch-keyword-router"
2. Verify routing rules include "list" with same output as "status" rule
3. Check what output index "status" routes to and confirm "list" routes to same
</verify>
<done>Keyword Router accepts "list" command as alias for "status", routing to the same container list display path</done>
</task>
<task type="auto">
<name>Task 4: Deploy updated main workflow via n8n API</name>
<files>n8n-workflow.json</files>
<action>
Deploy updated n8n-workflow.json to n8n instance:
```bash
source .env.n8n-api
curl -X PUT "$N8N_HOST/api/v1/workflows/HmiXBlJefBRPMS0m4iNYc" \
-H "X-N8N-API-KEY: $N8N_API_KEY" \
-H "Content-Type: application/json" \
--data @n8n-workflow.json
```
Verify deployment success (returns 200 with workflow object).
</action>
<verify>
curl returns 200 status code and JSON response containing workflow ID HmiXBlJefBRPMS0m4iNYc
</verify>
<done>Updated n8n-workflow.json deployed to n8n instance successfully</done>
</task>
</tasks>
<verification>
## Manual Test Cases
After deployment, test using Telegram bot:
1. **Disambiguation keyboard:** Send "stop plex" (assuming multiple containers match "plex") → expect keyboard showing containers with "Select containers to stop:" and buttons with correct action callbacks
2. **Confirmation cancel:** From container status view → tap Stop → confirmation dialog appears → tap Cancel → expect return to container status view (not failure)
3. **List command:** Send "/list" → expect container list with pagination (same as "/status" with no args)
All three should now work correctly per UAT expectations.
</verification>
<success_criteria>
- Build Batch Keyboard reads $json.actionType for correct action in disambiguation keyboards
- Build Cancel Return Submenu uses $input.item.json to support both cancel paths
- Keyword Router accepts "list" command routing to status handler
- Updated main workflow deployed via n8n API
- Three UAT gaps closed: disambiguation keyboard text/callbacks, confirmation cancel, /list command
</success_criteria>
<output>
After completion, create `.planning/phases/10.1-aggressive-workflow-modularization/10.1-09-SUMMARY.md`
</output>