docs(16-06): add critical lessons from hotfix to gap closure plan
Incorporates 5 lessons from commit 216f3a4 into the plan:
- Connection keys/targets must use node names, not IDs
- HTTP auth must use Header Auth credential, not manual env vars
- Node names must be unique
- Use $('Node Name') after GraphQL chains, not $input.item.json
- Added validation checklist to verification section
Marks Task 2 as already completed (dead code removal done in hotfix).
Updates node counts from 193 to 181 baseline.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -34,13 +34,40 @@ must_haves:
|
||||
---
|
||||
|
||||
<objective>
|
||||
Migrate the 3 remaining text command entry points in the main workflow from Docker socket proxy Execute Command nodes to Unraid GraphQL API queries, and remove dead code nodes.
|
||||
Migrate the 3 remaining text command entry points in the main workflow from Docker socket proxy Execute Command nodes to Unraid GraphQL API queries.
|
||||
|
||||
Purpose: Close the verification gaps that block Phase 17 (docker-socket-proxy removal). The 3 text command paths (start/stop/restart, update, batch) still use Execute Command nodes with `curl` to the docker-socket-proxy. After this plan, ALL container operations in the main workflow use GraphQL -- zero Docker socket proxy dependencies remain.
|
||||
|
||||
Output: Updated n8n-workflow.json with 3 GraphQL query chains replacing 3 Execute Command nodes, 6 dead code nodes removed.
|
||||
Output: Updated n8n-workflow.json with 3 GraphQL query chains replacing 3 Execute Command nodes.
|
||||
|
||||
NOTE: Dead code removal (Task 2 originally) and orphan cleanup were already completed in commit 216f3a4. The current node count is 181, not 193. Only Task 1 remains.
|
||||
</objective>
|
||||
|
||||
<critical_lessons>
|
||||
Plans 16-02 through 16-05 introduced defects that required a hotfix (commit 216f3a4). Do NOT repeat these mistakes:
|
||||
|
||||
1. **Connection keys MUST use node NAMES, never node IDs.**
|
||||
n8n resolves connections by node name. Using IDs as dictionary keys (e.g., `"http-get-container-for-action"`) creates orphaned wiring that silently fails at runtime.
|
||||
- WRONG: `"connections": { "http-my-node-id": { "main": [...] } }`
|
||||
- RIGHT: `"connections": { "My Node Display Name": { "main": [...] } }`
|
||||
|
||||
2. **Connection targets MUST also use node NAMES, never IDs.**
|
||||
- WRONG: `{ "node": "code-normalizer-action", "type": "main", "index": 0 }`
|
||||
- RIGHT: `{ "node": "Normalize GraphQL Response (Action)", "type": "main", "index": 0 }`
|
||||
|
||||
3. **GraphQL HTTP Request nodes MUST use Header Auth credential, NOT manual headers.**
|
||||
Using `$env.UNRAID_API_KEY` as a manual header causes `Invalid CSRF token` / `UNAUTHENTICATED` errors. The correct config:
|
||||
- `"authentication": "genericCredentialType"`
|
||||
- `"genericAuthType": "httpHeaderAuth"`
|
||||
- `"credentials": { "httpHeaderAuth": { "id": "unraid-api-key-credential-id", "name": "Unraid API Key" } }`
|
||||
- Do NOT add `x-api-key` to `headerParameters` — the credential handles it.
|
||||
Copy the exact auth config from any existing working node (e.g., "Get Container For Action").
|
||||
|
||||
4. **Node names MUST be unique.** Duplicate names cause connection ambiguity. n8n cannot distinguish which node a connection refers to.
|
||||
|
||||
5. **After a GraphQL query chain (HTTP → Normalizer → Registry), downstream Code nodes receive container item arrays, NOT upstream preparation data.** Use `$('Upstream Node Name').item.json` to reference data from before the chain. Using `$input.item.json` will give you a container object, not the preparation data.
|
||||
</critical_lessons>
|
||||
|
||||
<execution_context>
|
||||
@/home/luc/.claude/get-shit-done/workflows/execute-plan.md
|
||||
@/home/luc/.claude/get-shit-done/templates/summary.md
|
||||
@@ -77,11 +104,14 @@ Replace with 3 nodes:
|
||||
- type: n8n-nodes-base.httpRequest, typeVersion: 4.2
|
||||
- method: POST
|
||||
- url: `={{ $env.UNRAID_HOST }}/graphql`
|
||||
- authentication: predefinedCredentialType, httpHeaderAuth, credential "Unraid API Key"
|
||||
- authentication: genericCredentialType, genericAuthType: httpHeaderAuth
|
||||
- credentials: `{ "httpHeaderAuth": { "id": "unraid-api-key-credential-id", "name": "Unraid API Key" } }`
|
||||
- Do NOT add manual x-api-key headers — the credential handles auth automatically
|
||||
- sendBody: true, specifyBody: json
|
||||
- jsonBody: `{"query": "query { docker { containers { id names state image status } } }"}`
|
||||
- options: timeout: 15000
|
||||
- position: [1120, 400]
|
||||
- Copy the full node structure from an existing working node (e.g., "Get Container For Action") and only change name, id, position, and jsonBody
|
||||
|
||||
1b. **"Normalize Action Containers"** — Code node (GraphQL response normalizer)
|
||||
- Inline normalizer code (same as Plan 16-01/16-05 pattern):
|
||||
@@ -176,58 +206,20 @@ All 3 text command entry points (action, update, batch) query containers via Unr
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 2: Remove dead code nodes and clean stale references</name>
|
||||
<name>Task 2: ALREADY COMPLETED — dead code and orphan removal</name>
|
||||
<files>n8n-workflow.json</files>
|
||||
<action>
|
||||
Remove 6 dead code nodes that are no longer connected to any live path. These are remnants of the old Docker API direct-execution pattern that was replaced by sub-workflow calls during modularization.
|
||||
SKIP THIS TASK — already completed in hotfix commit 216f3a4.
|
||||
|
||||
**Dead code nodes to remove from the nodes array:**
|
||||
Removed 12 nodes: 6 dead code chains (Build/Execute/Parse Action Command × 2) and 6 orphan utility templates (GraphQL Response Normalizer, Container ID Registry, GraphQL Error Handler, Unraid API HTTP Template, Callback Token Encoder/Decoder). Node count went from 193 to 181.
|
||||
|
||||
1. **"Build Action Command"** (id: code-build-action-cmd) — Code node that built docker curl commands for text command actions. No incoming connections from any live path.
|
||||
|
||||
2. **"Execute Action"** (id: exec-action) — Execute Command node that ran the curl command built by "Build Action Command". Only fed by dead node above.
|
||||
|
||||
3. **"Parse Action Result"** (id: code-parse-action-result) — Code node that parsed curl HTTP status codes. Only fed by dead node above. NOTE: Its output went to "Send Action Result" which IS still live (also receives from "Handle Text Action Result"), so only remove this node, not "Send Action Result".
|
||||
|
||||
4. **"Build Immediate Action Command"** (id: code-build-immediate-action-cmd) — Code node that built docker curl commands for inline keyboard immediate actions. No incoming connections from any live path.
|
||||
|
||||
5. **"Execute Immediate Action"** (id: exec-immediate-action) — Execute Command node that ran the curl command built by "Build Immediate Action Command". Only fed by dead node above.
|
||||
|
||||
6. **"Format Immediate Result"** (id: code-format-immediate-result) — Code node that formatted immediate action results. Only fed by dead node above. NOTE: Its output went to "Send Immediate Result" which IS still live (also receives from "Handle Inline Action Result"), so only remove this node, not "Send Immediate Result".
|
||||
|
||||
**Connection entries to remove:**
|
||||
|
||||
Remove the following entries from the connections object:
|
||||
- "Build Action Command" (connects to "Execute Action")
|
||||
- "Execute Action" (connects to "Parse Action Result")
|
||||
- "Parse Action Result" (connects to "Send Action Result")
|
||||
- "Build Immediate Action Command" (connects to "Execute Immediate Action")
|
||||
- "Execute Immediate Action" (connects to "Format Immediate Result")
|
||||
- "Format Immediate Result" (connects to "Send Immediate Result")
|
||||
|
||||
**DO NOT remove:**
|
||||
- "Send Action Result" — still receives from "Handle Text Action Result" (live path)
|
||||
- "Send Immediate Result" — still receives from "Handle Inline Action Result" (live path)
|
||||
|
||||
**After removal:**
|
||||
- Verify node count decreased by 6 (from 193, accounting for 9 new nodes added in Task 1, net change should be 193 + 9 - 6 = 196 nodes, but the 3 Execute Command nodes from Task 1 were also removed, so: 193 - 3 removed + 9 added - 6 dead = 193 nodes)
|
||||
- Push updated workflow to n8n
|
||||
|
||||
**Stale docker-socket-proxy references:**
|
||||
The 2 remaining `socket-proxy` references in "Check Available Updates" and "Prepare Update All Batch" Code nodes are functional infrastructure exclusion filters (they exclude `socket-proxy` named containers from update-all operations). These are NOT stale -- they serve a valid purpose as long as the docker-socket-proxy container exists on the Unraid server. They will be addressed in Phase 17 (Cleanup) when the docker-socket-proxy container is actually removed.
|
||||
The 2 remaining `socket-proxy` string references in "Check Available Updates" and "Prepare Update All Batch" are functional infrastructure exclusion filters — they will be addressed in Phase 17.
|
||||
</action>
|
||||
<verify>
|
||||
1. Count nodes in n8n-workflow.json -- should be 193 (193 original - 3 Execute Commands replaced + 9 new GraphQL nodes - 6 dead code removed = 193)
|
||||
2. Search for "Build Action Command" -- should NOT exist
|
||||
3. Search for "Build Immediate Action Command" -- should NOT exist
|
||||
4. Search for "exec-action" -- should NOT exist
|
||||
5. Search for "exec-immediate-action" -- should NOT exist
|
||||
6. Verify "Send Action Result" still exists and is connected from "Handle Text Action Result"
|
||||
7. Verify "Send Immediate Result" still exists and is connected from "Handle Inline Action Result"
|
||||
8. Push workflow to n8n and verify HTTP 200 response
|
||||
Already verified. Node count is 181.
|
||||
</verify>
|
||||
<done>
|
||||
6 dead code nodes removed. "Send Action Result" and "Send Immediate Result" preserved with their live connections. Workflow node count is 193. Zero dead Execute Command or docker curl code nodes remain.
|
||||
Completed in prior hotfix.
|
||||
</done>
|
||||
</task>
|
||||
|
||||
@@ -240,15 +232,20 @@ The 2 remaining `socket-proxy` references in "Check Available Updates" and "Prep
|
||||
4. `grep "Query Containers for Action\|Query Containers for Update\|Query Containers for Batch" n8n-workflow.json` finds all 3 new query nodes
|
||||
5. Workflow pushes to n8n successfully (HTTP 200)
|
||||
6. All connection chains intact: Parse Command -> Query -> Normalize -> Registry -> Prepare Match -> Execute Match -> Route Result
|
||||
7. **Connection integrity check:** All connection dictionary keys match actual node names (no node IDs as keys)
|
||||
8. **Auth check:** All new HTTP Request nodes use `genericCredentialType` + `httpHeaderAuth` credential, NOT manual `x-api-key` headers
|
||||
9. **Name uniqueness check:** No duplicate node names exist
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
- Zero Execute Command nodes with docker-socket-proxy curl commands
|
||||
- 3 new GraphQL HTTP Request + Normalizer + Registry Update chains for text command paths
|
||||
- 6 dead code nodes removed
|
||||
- Total node count: 193
|
||||
- Total node count: 181 + 9 new - 3 removed = 187
|
||||
- Workflow pushes to n8n successfully
|
||||
- All text command paths route through GraphQL before reaching matching sub-workflow
|
||||
- All new connection keys use node NAMES (not IDs)
|
||||
- All new HTTP nodes use Header Auth credential (not $env.UNRAID_API_KEY)
|
||||
- No duplicate node names introduced
|
||||
- Phase 16 verification gaps closed: all 3 partial truths become fully verified
|
||||
</success_criteria>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user