docs(09): create phase plan

Phase 09: Batch Operations
- 4 plans in 4 waves
- 3 autonomous, 1 with checkpoint
- Ready for execution

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Lucas Berger
2026-02-03 21:01:06 -05:00
parent 3ca89c3815
commit a409671dc6
5 changed files with 817 additions and 4 deletions
+12 -4
View File
@@ -66,9 +66,9 @@ Plans:
**Plans:** 3 plans
Plans:
- [ ] 08-01-PLAN.md — Container list keyboard and submenu navigation
- [ ] 08-02-PLAN.md — Action execution and confirmation flow
- [ ] 08-03-PLAN.md — Progress feedback and completion messages
- [x] 08-01-PLAN.md — Container list keyboard and submenu navigation
- [x] 08-02-PLAN.md — Action execution and confirmation flow
- [x] 08-03-PLAN.md — Progress feedback and completion messages
**Success Criteria:**
1. Status command returns a message with inline buttons showing available actions per container
@@ -87,6 +87,14 @@ Plans:
**Requirements:** BAT-01, BAT-02, BAT-03, BAT-04, BAT-05, BAT-06
**Plans:** 4 plans
Plans:
- [ ] 09-01-PLAN.md — Batch command parsing and container matching
- [ ] 09-02-PLAN.md — Sequential batch execution with progress feedback
- [ ] 09-03-PLAN.md — "Update all" and inline multi-select
- [ ] 09-04-PLAN.md — Verification and testing
**Success Criteria:**
1. User can type "update plex sonarr radarr" and all three containers update sequentially
2. Each container shows individual progress/result as it completes (not waiting until all finish)
@@ -136,7 +144,7 @@ Plans:
|-------|------|--------------|--------|
| 6 | n8n API Access | API-01, API-02, API-03, API-04 | Complete |
| 7 | Socket Security | SEC-01, SEC-02, SEC-03, SEC-04 | Complete |
| 8 | Inline Keyboard Infrastructure | KEY-01, KEY-02, KEY-03, KEY-04, KEY-05 | Pending |
| 8 | Inline Keyboard Infrastructure | KEY-01, KEY-02, KEY-03, KEY-04, KEY-05 | Complete |
| 9 | Batch Operations | BAT-01, BAT-02, BAT-03, BAT-04, BAT-05, BAT-06 | Pending |
| 10 | Polish & Audit | UNR-01, ENV-01, ENV-02, WEB-01 | Pending |
| 11 | Documentation Overhaul | TBD | Pending |
@@ -0,0 +1,188 @@
---
phase: 09-batch-operations
plan: 01
type: execute
wave: 1
depends_on: []
files_modified: [n8n-workflow.json]
autonomous: true
must_haves:
truths:
- "User can type 'update plex sonarr radarr' and bot recognizes multiple containers"
- "Fuzzy matching finds containers even with partial names"
- "Exact match gets priority (plex matches plex, not jellyplex)"
- "Ambiguous matches show disambiguation prompt"
artifacts:
- path: "n8n-workflow.json"
provides: "Batch command parsing and container matching"
contains: "Parse Batch Command"
key_links:
- from: "Parse Batch Command node"
to: "Match Containers node"
via: "Parsed action and container names array"
pattern: "containerNames.*split"
- from: "Match Containers node"
to: "disambiguation or execution path"
via: "Switch based on match results"
pattern: "needsDisambiguation"
---
<objective>
Parse multi-container batch commands and match container names with fuzzy matching and exact-match priority.
Purpose: Enable batch operations by recognizing commands like "update plex sonarr radarr" and resolving container names accurately.
Output: Workflow nodes that parse batch commands and match containers, with disambiguation for ambiguous matches.
</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/09-batch-operations/09-CONTEXT.md
@.planning/phases/09-batch-operations/09-RESEARCH.md
@.planning/phases/08-inline-keyboard-infrastructure/08-01-SUMMARY.md
@n8n-workflow.json
</context>
<tasks>
<task type="auto">
<name>Task 1: Add batch command detection and parsing</name>
<files>n8n-workflow.json</files>
<action>
Add a new branch in the command routing logic to detect batch commands (multiple container names after action keyword).
1. In the existing command matching flow (after "Extract Keywords" or equivalent), add a Code node "Detect Batch Command":
- Input: message text
- Check if command matches pattern: `{action} {name1} {name2} ...` where action is update/start/stop/restart
- Parse action and container names array (split by spaces after action keyword)
- Output: `{ isBatch: boolean, action: string, containerNames: string[], originalMessage: string }`
- Single container = not batch (handled by existing flow)
- Two or more containers = batch
2. Add an IF node "Is Batch Command" that routes:
- TRUE: To new batch processing flow (Plan 01-02 nodes)
- FALSE: To existing single-container flow (preserve current behavior)
3. The batch flow should NOT trigger for:
- "status" (always shows list)
- "logs {name} {count}" (second word is line count, not container)
- Commands with only one container name
Callback format from context: Existing callbacks use colon-separated format. Batch text commands use space-separated. Keep them distinct.
</action>
<verify>
Test via n8n execution:
- "update plex sonarr" -> isBatch: true, action: "update", containerNames: ["plex", "sonarr"]
- "update plex" -> isBatch: false (single container, use existing flow)
- "logs plex 50" -> isBatch: false (logs has line count parameter)
- "status" -> Not routed to batch flow
</verify>
<done>Batch commands detected and parsed into action + container names array; single-container commands continue to existing flow</done>
</task>
<task type="auto">
<name>Task 2: Add container name matching with exact-match priority</name>
<files>n8n-workflow.json</files>
<action>
Add container matching logic that resolves user-provided names to actual container names.
1. Add Code node "Match Batch Containers":
- Input: `containerNames` array from batch parser, `containers` array from Docker API (reuse existing "Get All Containers" HTTP node)
- For each user-provided name:
a. Normalize: lowercase, trim whitespace
b. Check exact match first: `containers.find(c => c.Names[0].replace('/', '').toLowerCase() === normalized)`
c. If no exact match, check substring match: `containers.filter(c => c.Names[0].toLowerCase().includes(normalized))`
d. Record match result: { input: "plex", matched: "plex", type: "exact" } or { input: "plex", matches: ["plex", "jellyplex"], type: "ambiguous" }
- Aggregate results into: `{ allMatched: Container[], needsDisambiguation: { input, matches }[], notFound: string[] }`
2. Add IF node "Needs Disambiguation":
- TRUE (any ambiguous matches): Route to disambiguation message
- FALSE (all matched or some not found): Continue to batch execution or error
3. Add Code node "Build Disambiguation Message" for ambiguous matches:
- Format: "Multiple matches found:\n- 'plex' could match: plex, jellyplex\nPlease be more specific."
- Include inline keyboard with exact container names as buttons for user to select
4. Add Code node "Build Not Found Message" for completely unmatched names:
- Format: "Container not found: {name}"
- Only show if notFound array is not empty and no disambiguation needed
Decision from context: "if 'plex' matches both 'plex' and 'jellyplex', user should be able to specify they want only 'plex'" - this is why exact match has priority. If user types exact name, it wins.
</action>
<verify>
Test via n8n execution with mock container list ["plex", "jellyplex", "sonarr", "radarr"]:
- Input ["plex"] -> exact match "plex", no disambiguation
- Input ["jelly"] -> ambiguous, matches ["jellyplex"], could ask if they meant jellyplex
- Input ["plex", "sonarr"] -> both exact match, no disambiguation
- Input ["notacontainer"] -> notFound: ["notacontainer"]
</verify>
<done>Container names resolved with exact-match priority; ambiguous matches show disambiguation; not-found names reported clearly</done>
</task>
<task type="auto">
<name>Task 3: Wire batch routing and add "batch stop" confirmation</name>
<files>n8n-workflow.json</files>
<action>
Complete the batch command routing and add confirmation for batch stop operations.
1. Wire the routing from "Is Batch Command" TRUE output:
- Connect to "Get All Containers" (reuse existing node or create duplicate for batch)
- Then to "Match Batch Containers"
- Then to "Needs Disambiguation" IF node
- Disambiguation TRUE -> "Build Disambiguation Message" -> "Send Disambiguation" (HTTP editMessageText or sendMessage)
- Disambiguation FALSE -> Check action type
2. Add Switch node "Route Batch Action":
- update: Continue to batch execution (Plan 02)
- start/restart: Continue to batch execution (Plan 02) - immediate, no confirmation
- stop: Route to confirmation flow (batch stop is dangerous per context)
3. Add confirmation flow for batch stop (per context: "Batch stop confirms due to fuzzy matching risk"):
- Code node "Build Batch Stop Confirmation": "Stop {N} containers?\n\n{list names}\n\n[Confirm] [Cancel]"
- Callback format: `bstop:confirm:{comma-separated-names}:{timestamp}` or `bstop:cancel`
- HTTP node to send confirmation message with inline keyboard
- Add to Route Callback node: handle `bstop:` prefix callbacks
- On confirm: check 30-second timeout, then continue to batch execution
- On cancel: return to container list
4. Named batch update/start/restart run immediately without confirmation (per context: "Named batches run immediately without confirmation").
</action>
<verify>
Test via n8n execution:
- "update plex sonarr" -> Matches containers, routes to batch update (output waits for Plan 02)
- "stop plex sonarr" -> Shows confirmation "Stop 2 containers? plex, sonarr [Confirm] [Cancel]"
- "start plex sonarr" -> Routes to batch start immediately (no confirmation)
- Disambiguation keyboard buttons work and re-route correctly
</verify>
<done>Batch commands route correctly; batch stop shows confirmation; other batch actions proceed immediately; disambiguation allows user selection</done>
</task>
</tasks>
<verification>
1. Workflow imports successfully in n8n
2. Batch command detection works for all action types
3. Container matching prioritizes exact matches
4. Disambiguation shows when multiple fuzzy matches exist
5. Batch stop shows confirmation dialog
6. Existing single-container commands still work unchanged
</verification>
<success_criteria>
- "update plex sonarr" parses into batch update for two containers
- "stop plex sonarr" shows confirmation before executing
- "plex" exactly matches "plex" even when "jellyplex" exists
- Ambiguous input like "jelly" prompts for clarification
- Single-container commands route to existing flow (no regression)
</success_criteria>
<output>
After completion, create `.planning/phases/09-batch-operations/09-01-SUMMARY.md`
</output>
@@ -0,0 +1,251 @@
---
phase: 09-batch-operations
plan: 02
type: execute
wave: 2
depends_on: [09-01]
files_modified: [n8n-workflow.json]
autonomous: true
must_haves:
truths:
- "Batch operations execute sequentially, not in parallel"
- "Each container shows progress as it completes"
- "One container failure does not abort remaining batch"
- "Final message shows summary with failures emphasized"
artifacts:
- path: "n8n-workflow.json"
provides: "Sequential batch execution with error handling"
contains: "Loop Over Items"
key_links:
- from: "Loop Over Items node"
to: "Execute Container Action"
via: "Single item per iteration (batch size 1)"
pattern: "batchSize.*1"
- from: "Error handler"
to: "Continue loop"
via: "Log failure, increment counter, proceed"
pattern: "failureCount"
- from: "Batch summary"
to: "Telegram editMessageText"
via: "Formatted result with failure details"
pattern: "Failed.*reason"
---
<objective>
Implement sequential batch execution with per-container progress, error isolation, and failure-emphasized summaries.
Purpose: Enable multi-container operations that don't fail entirely when one container has issues.
Output: Loop Over Items execution pattern with progress updates and actionable error reporting.
</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/09-batch-operations/09-CONTEXT.md
@.planning/phases/09-batch-operations/09-RESEARCH.md
@.planning/phases/09-batch-operations/09-01-SUMMARY.md
@n8n-workflow.json
</context>
<tasks>
<task type="auto">
<name>Task 1: Add Loop Over Items for sequential batch execution</name>
<files>n8n-workflow.json</files>
<action>
Implement the sequential execution loop for batch operations.
1. After "Route Batch Action" (from Plan 01), add Code node "Initialize Batch State":
- Input: matched containers array, action type, chat_id, message_id (for editing)
- Output batch state object:
```javascript
return {
json: {
containers: $json.allMatched, // Array of container objects
action: $json.action, // 'update', 'start', 'stop', 'restart'
totalCount: $json.allMatched.length,
successCount: 0,
failureCount: 0,
warningCount: 0,
results: [], // Array of { name, status: 'success'|'error'|'warning', reason? }
chatId: $json.chatId,
messageId: $json.messageId,
currentIndex: 0
}
};
```
2. Add HTTP node "Send Batch Start Message":
- POST to Telegram sendMessage (new message, not edit - we'll edit this one during progress)
- Text: "Starting batch {action} for {N} containers..."
- Save message_id from response for progress edits
3. Add Loop Over Items node "Batch Loop":
- Input: containers array
- Batch Size: 1 (critical - sequential execution)
- Output: Single container per iteration
4. For each iteration, the loop should:
- Edit progress message with current container name
- Execute the action (reuse existing action execution nodes where possible)
- Handle success or error
- Update counters and results array
- Continue to next item
5. Important: Use n8n's "Continue On Fail" option on HTTP Request nodes within the loop so one failure doesn't abort the whole batch.
Note from RESEARCH: n8n Loop Over Items with "Continue (using error output)" has known issues. Use HTTP Request's "Continue On Fail" and check status code in subsequent Code node instead.
</action>
<verify>
Test with mock batch of 3 containers:
- Loop executes 3 times (one per container)
- Batch state tracks progress correctly
- Initial message is sent before loop starts
</verify>
<done>Sequential loop executes containers one at a time with batch state tracking</done>
</task>
<task type="auto">
<name>Task 2: Add per-container progress updates and action execution</name>
<files>n8n-workflow.json</files>
<action>
Wire action execution within the loop with progress feedback.
1. Inside the loop, add Code node "Build Progress Message":
- Input: current container, batch state
- Output message text:
```
Batch {action} in progress...
Current: {containerName}
Progress: {current}/{total}
Success: {successCount}
Failed: {failureCount}
```
- Rate limit consideration: Only edit message every container (small batches <5). For larger batches, research suggests editing every 3-5 items, but since typical batch is 2-5 containers, edit every time is fine.
2. Add HTTP node "Edit Progress Message":
- POST to Telegram editMessageText
- Use saved progress_message_id from batch start
- parse_mode: HTML
3. Add Switch node "Route Batch Loop Action" (within loop):
- update: Execute full update flow (pull image, check digest, stop, remove, create, start)
- start: Execute container start
- stop: Execute container stop
- restart: Execute container restart
4. For each action type, wire to existing action execution nodes where possible:
- Start: Can reuse "Execute Immediate Action" from Phase 8 or create dedicated "Execute Batch Start"
- Stop/Restart: Similar reuse pattern
- Update: This is complex - need to execute the full update sequence per container
5. Add Code node "Handle Action Result" after each action execution:
- Check HTTP response status or exec output
- Determine success/error/warning:
- Success: Container action completed normally
- Warning: "Already stopped", "No update available", "Already running"
- Error: Network error, timeout, pull failed, etc.
- Update batch state: increment appropriate counter, add to results array
- Output updated batch state for next iteration
6. Key pattern for continue-on-error:
- HTTP nodes: Enable "Continue On Fail"
- After HTTP node, Code node checks `$json.error` or `$json.statusCode >= 400`
- Log failure to results array but don't throw - return updated state to continue loop
</action>
<verify>
Test batch update with 2 containers where one has no update available:
- First container: pulls, updates, succeeds
- Second container: "No update available" -> warning
- Progress message updates for each container
- Both counted in results (1 success, 1 warning)
</verify>
<done>Per-container progress shown during execution; actions execute correctly; errors logged but don't abort batch</done>
</task>
<task type="auto">
<name>Task 3: Add batch summary with failure emphasis</name>
<files>n8n-workflow.json</files>
<action>
Create the final summary message after batch completes.
1. After Loop Over Items completes, add Code node "Build Batch Summary":
- Input: final batch state with all results
- Build summary following pattern from CONTEXT: "Summary emphasizes failures over successes"
- Format:
```html
<b>Batch {action} Complete</b>
{if errors exist:}
<b>Failed ({errorCount}):</b>
- {containerName}: {reason}
- {containerName}: {reason}
{if warnings exist AND Claude's discretion to show them:}
<b>Warnings ({warningCount}):</b>
- {containerName}: {reason}
<b>Successful:</b> {successCount}/{totalCount}
```
- Per CONTEXT, Claude's discretion on warnings. Recommendation: Show warning count but not individual warnings unless there are few: `Warnings: 2 (containers already in desired state)`
2. Add HTTP node "Send Batch Summary":
- POST to Telegram editMessageText
- Edit the progress message to show final summary
- Add inline keyboard with "Back to List" button
3. Error classification in the result handler (Task 2):
- ERROR (red, show in summary):
- HTTP status 4xx/5xx from Docker API
- "image pull failed", "timeout", "permission denied"
- Container not found during execution
- WARNING (yellow, optional in summary):
- "Already stopped" (for stop action)
- "Already running" (for start action)
- "No update available" (for update action)
- HTTP 304 Not Modified
4. Summary should be actionable - if something failed, user knows what and why, not just a count.
</action>
<verify>
Test batch with mixed results:
- 2 success, 1 error, 1 warning
- Summary shows: "Failed (1): containerX: Connection timeout"
- Summary shows: "Warnings: 1"
- Summary shows: "Successful: 2/4"
- "Back to List" button works
</verify>
<done>Final summary shows after batch; failures emphasized with names and reasons; warnings handled per discretion; navigation button returns to list</done>
</task>
</tasks>
<verification>
1. Workflow imports successfully in n8n
2. "update plex sonarr radarr" executes all three sequentially
3. Progress message updates for each container
4. One failure doesn't abort remaining containers
5. Final summary shows clear failure/success breakdown
6. Errors include container name and reason
</verification>
<success_criteria>
- Batch of 3 containers executes sequentially (not parallel)
- Each container shows progress as it completes
- If container 2 fails, container 3 still attempts
- Summary: "Failed (1): sonarr: image pull timeout" + "Successful: 2/3"
- User can navigate back to container list after batch
</success_criteria>
<output>
After completion, create `.planning/phases/09-batch-operations/09-02-SUMMARY.md`
</output>
@@ -0,0 +1,199 @@
---
phase: 09-batch-operations
plan: 03
type: execute
wave: 3
depends_on: [09-02]
files_modified: [n8n-workflow.json]
autonomous: true
must_haves:
truths:
- "'Update all' command updates only containers with available updates"
- "'Update all' shows confirmation with count before executing"
- "If no containers have updates, shows 'All up to date' message"
- "Inline keyboard allows selecting multiple containers for batch action"
artifacts:
- path: "n8n-workflow.json"
provides: "Update all command and inline batch selection"
contains: "Check Available Updates"
key_links:
- from: "'update all' command"
to: "Docker API image inspection"
via: "Compare current vs latest image digests"
pattern: "update.*all"
- from: "Multi-select keyboard"
to: "Batch execution"
via: "Toggle selection encoded in callback_data"
pattern: "batch:toggle"
---
<objective>
Add "update all" command targeting only containers with available updates, plus inline keyboard multi-select for batch operations via buttons.
Purpose: Enable convenient bulk updates and UI-based batch selection without typing container names.
Output: "Update all" flow with pre-flight check and confirmation; multi-select toggle keyboard for batch actions.
</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/09-batch-operations/09-CONTEXT.md
@.planning/phases/09-batch-operations/09-RESEARCH.md
@.planning/phases/09-batch-operations/09-01-SUMMARY.md
@.planning/phases/09-batch-operations/09-02-SUMMARY.md
@n8n-workflow.json
</context>
<tasks>
<task type="auto">
<name>Task 1: Add "update all" command with update availability check</name>
<files>n8n-workflow.json</files>
<action>
Implement "update all" that only targets containers with updates available.
1. In command detection (early in workflow), detect "update all" as special case:
- Add to command matching: if message.toLowerCase() includes "update all" or "updateall"
- Route to dedicated "Update All" flow (not the batch parsing flow)
2. Add HTTP node "Get All Containers For Update All":
- GET from Docker API via proxy: `http://docker-socket-proxy:2375/containers/json?all=true`
- Returns all containers
3. Add Code node "Check Available Updates":
- For each container, need to check if update is available
- This requires comparing current image digest to remote latest
- Pattern from existing update flow:
a. Get container's current image ID
b. Pull :latest tag (or appropriate tag)
c. Compare digests
- This is expensive for many containers - consider approach:
- Option A: Full check for each (slow but accurate)
- Option B: Only check containers using :latest tag (faster, common case)
- Recommendation: Use Option B as default - most containers use :latest
4. For containers using :latest tag:
- Execute: `docker pull {image}:latest` (via proxy exec or curl)
- Compare pulled image digest to running container's image digest
- Mark container as "has update" if different
5. Add Code node "Build Update All Preview":
- If no containers have updates: Return "All containers are up to date!"
- If some have updates: Build list of containers with updates
- Output: `{ containersToUpdate: Container[], count: number }`
6. Add IF node "Has Updates Available":
- TRUE: Continue to confirmation
- FALSE: Send "All up to date" message and stop
7. Add Code node "Build Update All Confirmation":
- Text: "Update {N} containers?\n\n{list container names with versions if available}"
- Inline keyboard: [Confirm] [Cancel]
- Callback format: `uall:confirm:{timestamp}` and `uall:cancel`
- Store containers to update in workflow context (or encode in callback if small enough)
8. Handle callbacks:
- `uall:confirm`: Check 30-second timeout, then pass containers to batch execution flow (Plan 02)
- `uall:cancel`: Send "Update cancelled" and return to list
Note: The actual batch execution reuses Plan 02's Loop Over Items infrastructure.
</action>
<verify>
Test "update all" command:
- With containers that have updates: Shows confirmation "Update 3 containers? plex, sonarr, radarr"
- With no updates available: Shows "All containers are up to date!"
- Confirm executes batch update for listed containers
- Cancel returns to normal state
</verify>
<done>"Update all" checks for available updates, shows confirmation with count and list, executes batch for only updatable containers</done>
</task>
<task type="auto">
<name>Task 2: Add inline keyboard multi-select for batch operations</name>
<files>n8n-workflow.json</files>
<action>
Implement toggle-style multi-select via inline keyboard buttons.
1. Add entry point to batch selection mode:
- In container list keyboard (from Phase 8), add button row: "Select Multiple"
- Callback: `batch:mode`
2. Handle `batch:mode` callback - Add Code node "Build Batch Select Keyboard":
- Show container list with toggle checkmarks
- Each container button: text shows name with/without checkmark
- Callback format: `batch:toggle:{selected_csv}:{container_name}`
- `selected_csv`: comma-separated currently selected containers
- `container_name`: container being toggled
- Example: `batch:toggle:plex,sonarr:radarr` means "plex and sonarr selected, toggling radarr"
3. Handle `batch:toggle:*` callbacks:
- Parse callback data to get current selection and container being toggled
- Toggle the container in/out of selection
- Rebuild keyboard with updated checkmarks
- Edit message to show new keyboard
4. Add action buttons when selection exists:
- At bottom of keyboard, show: "[Update Selected] [Start Selected] [Stop Selected]"
- Only show relevant actions based on container states (or show all and handle gracefully)
- Callback format: `batch:exec:{action}:{selected_csv}`
5. Handle `batch:exec:*` callbacks:
- Parse action and selected containers
- For stop: Show confirmation (per existing batch stop rule)
- For start/restart: Execute immediately via batch loop
- For update: Execute immediately via batch loop
- Pass selected containers to batch execution infrastructure (Plan 02)
6. 64-byte callback_data limit handling (per RESEARCH):
- Average container name: 6-10 chars
- With format `batch:toggle:{csv}:{name}`, limit ~8-10 containers
- If limit approached, show warning: "Maximum selection reached. Use 'update all' for more."
- Add Code node "Check Selection Size" before toggle to enforce limit
7. Add "Clear Selection" and "Cancel" buttons:
- "Clear": `batch:clear` - reset selection, rebuild keyboard
- "Cancel": `batch:cancel` - return to normal container list
Note: This is Claude's discretion area from CONTEXT. Toggle checkmark pattern chosen for consistency with Phase 8 keyboard patterns.
</action>
<verify>
Test batch selection flow:
- Click "Select Multiple" -> Container list with toggle buttons appears
- Click container -> Checkmark appears/disappears
- With 2+ selected -> Action buttons appear at bottom
- Click "Update Selected" -> Batch update executes for selected containers
- Clear selection resets all checkmarks
- Cancel returns to normal container list
</verify>
<done>Inline keyboard multi-select works with toggle checkmarks; action buttons execute batch for selected containers; callback_data size limit enforced</done>
</task>
</tasks>
<verification>
1. Workflow imports successfully in n8n
2. "update all" shows only containers with available updates
3. "update all" with no updates shows "All up to date"
4. Multi-select keyboard allows toggling containers
5. Selected containers can be batch updated/started/stopped
6. Callback data stays within 64-byte limit
</verification>
<success_criteria>
- "Update all" scans and shows "Update 3 containers?" only for those needing updates
- When all up to date, shows "All containers are up to date!"
- Inline multi-select: checkmarks toggle on click
- "Update Selected" with 3 containers executes batch update
- Selection limit prevents callback_data overflow
</success_criteria>
<output>
After completion, create `.planning/phases/09-batch-operations/09-03-SUMMARY.md`
</output>
@@ -0,0 +1,167 @@
---
phase: 09-batch-operations
plan: 04
type: execute
wave: 4
depends_on: [09-03]
files_modified: [n8n-workflow.json]
autonomous: false
must_haves:
truths:
- "All batch operation flows work correctly via text commands"
- "All batch operation flows work correctly via inline keyboard"
- "Error handling behaves correctly when containers fail"
- "Existing single-container commands still work (no regression)"
artifacts: []
key_links: []
---
<objective>
Verify all batch operation flows work correctly and existing functionality is preserved.
Purpose: Ensure batch operations meet requirements before marking phase complete.
Output: Verified working batch system with human confirmation.
</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/09-batch-operations/09-CONTEXT.md
@.planning/phases/09-batch-operations/09-01-SUMMARY.md
@.planning/phases/09-batch-operations/09-02-SUMMARY.md
@.planning/phases/09-batch-operations/09-03-SUMMARY.md
@n8n-workflow.json
</context>
<tasks>
<task type="auto">
<name>Task 1: Deploy and test batch text commands</name>
<files>n8n-workflow.json</files>
<action>
Deploy the updated workflow and test all batch text command flows.
1. Import updated workflow to n8n (via API or manual upload)
2. Test batch text commands via Telegram:
Test A: Multi-container update
- Send: "update plex sonarr" (use actual container names from your server)
- Expected: Progress shows for each container, summary shows results
Test B: Multi-container start
- First stop two containers via existing single commands
- Send: "start plex sonarr"
- Expected: Both start without confirmation, summary shows results
Test C: Multi-container stop (requires confirmation)
- Send: "stop plex sonarr"
- Expected: Confirmation prompt appears
- Tap Confirm: Both stop, summary shows
- (Test cancel in separate attempt)
Test D: Fuzzy matching
- Send: "update plex" (when jellyplex also exists, or use your actual partial matches)
- Expected: Exact match wins, no disambiguation
Test E: Disambiguation
- Send: "update jelly" (if it matches multiple containers)
- Expected: Disambiguation prompt with options
3. Test "update all" command:
- Send: "update all"
- Expected: Shows confirmation with count of containers needing updates
- If all up to date: Shows "All containers are up to date!"
- Confirm: Batch update executes for listed containers
4. Document any issues found for fixing before checkpoint.
</action>
<verify>
All text command tests pass:
- "update plex sonarr" executes sequential batch update
- "stop plex sonarr" shows confirmation first
- "update all" only targets containers with updates
- Disambiguation works for ambiguous names
</verify>
<done>All batch text commands tested and working</done>
</task>
<task type="checkpoint:human-verify" gate="blocking">
<what-built>Complete batch operations system with text commands and inline keyboard multi-select</what-built>
<how-to-verify>
Test the following flows in Telegram:
**Text Command Tests:**
1. **Batch Update:**
- Send: "update {container1} {container2}" (replace with your container names)
- Verify: Progress updates for each container, final summary shows
2. **Batch Stop (confirmation required):**
- Send: "stop {container1} {container2}"
- Verify: Confirmation prompt appears
- Tap Confirm and verify both stop
3. **Update All:**
- Send: "update all"
- Verify: Shows count of containers with updates, or "All up to date"
- If updates exist, confirm and verify batch executes
**Inline Keyboard Tests:**
4. **Multi-Select Mode:**
- Send: "/status"
- Tap "Select Multiple" button
- Verify: Container list appears with toggle capability
5. **Toggle Selection:**
- Tap containers to toggle checkmarks
- Verify: Checkmarks appear/disappear on each tap
6. **Execute Batch:**
- With 2+ containers selected, tap action button (e.g., "Update Selected")
- Verify: Batch executes for selected containers with progress
**Error Handling Test:**
7. **Failure Isolation:**
- If possible, trigger a failure (e.g., update a container that doesn't exist)
- Verify: Other containers in batch still process, summary shows failure details
**Regression Tests:**
8. **Single-container commands still work:**
- "status" shows keyboard
- "start plex" starts single container
- "logs plex" shows logs
</how-to-verify>
<resume-signal>Type "approved" if all flows work, or describe any issues found</resume-signal>
</task>
</tasks>
<verification>
Human verified all batch flows work correctly via Telegram testing.
</verification>
<success_criteria>
- BAT-01: User can update multiple containers in one command
- BAT-02: Batch updates execute sequentially with per-container feedback
- BAT-03: "Update all" updates only containers with updates available
- BAT-04: "Update all" requires confirmation
- BAT-05: One failure doesn't abort remaining batch
- BAT-06: Final summary shows success/failure count
- Inline keyboard batch selection works
- No regression in existing commands
</success_criteria>
<output>
After completion, create `.planning/phases/09-batch-operations/09-04-SUMMARY.md`
</output>