Files
unraid-docker-manager/.planning/phases/16-api-migration/16-04-SUMMARY.md
T
Lucas Berger 8e8a5f9dc3 docs(16-04): complete Batch UI GraphQL migration plan
- Created 16-04-SUMMARY.md with full execution details
- Updated STATE.md: Phase 16 in progress (1/5 plans)
- Recorded decisions: 5 normalizer nodes, 15s timeout
- Updated progress: v1.4 now 30% complete (3/10 plans)
2026-02-09 10:24:47 -05:00

211 lines
8.6 KiB
Markdown

---
phase: 16-api-migration
plan: 04
subsystem: n8n-batch-ui
tags: [api-migration, graphql, batch-operations, normalizer]
dependency_graph:
requires:
- phase: 15
plan: 02
artifact: "GraphQL Response Normalizer pattern"
provides:
- artifact: "n8n-batch-ui.json with Unraid GraphQL API"
consumers: ["Main workflow Batch UI callers"]
affects:
- "Batch container selection flow"
- "All 5 batch action paths (mode, toggle, exec, nav, clear)"
tech_stack:
added: []
patterns:
- "GraphQL API queries with normalizer transformation"
- "5 identical normalizer nodes (one per query path)"
- "Docker API contract compatibility layer"
key_files:
created: []
modified:
- path: "n8n-batch-ui.json"
lines_changed: 354
description: "Migrated all 5 container queries from Docker socket proxy to Unraid GraphQL API with normalizer nodes"
decisions:
- summary: "5 identical normalizer nodes instead of shared utility node"
rationale: "n8n sub-workflows cannot share nodes across independent paths - each path needs its own node instance"
alternatives: ["Single normalizer with complex routing (rejected: architectural constraint)"]
- summary: "15-second timeout for GraphQL queries"
rationale: "myunraid.net cloud relay adds 200-500ms latency, increased from 5s Docker socket proxy timeout for safety margin"
alternatives: ["Keep 5s timeout (rejected: insufficient for cloud relay)", "30s timeout (rejected: too long for UI interaction)"]
- summary: "Keep full PrefixedID in normalizer output"
rationale: "Container ID Registry (Phase 15) handles translation downstream, normalizer preserves complete Unraid ID"
alternatives: ["Truncate to 12-char in normalizer (rejected: breaks registry lookup)"]
metrics:
duration_minutes: 2
completed_date: "2026-02-09"
tasks_completed: 1
files_modified: 1
nodes_added: 5
nodes_modified: 5
connections_rewired: 15
---
# Phase 16 Plan 04: Batch UI GraphQL Migration Summary
**One-liner:** Migrated n8n-batch-ui.json from Docker socket proxy to Unraid GraphQL API with 5 normalizer nodes preserving zero-change contract for downstream consumers
## What Was Delivered
### Core Implementation
**n8n-batch-ui.json transformation (nodes: 17 → 22):**
All 5 container listing queries migrated from Docker socket proxy to Unraid GraphQL API:
1. **Fetch Containers For Mode** - Initial batch selection entry
2. **Fetch Containers For Update** - After toggling container selection
3. **Fetch Containers For Exec** - Before batch action execution
4. **Fetch Containers For Nav** - Page navigation
5. **Fetch Containers For Clear** - After clearing selection
**For each query path:**
```
[upstream] → HTTP Request (GraphQL) → Normalizer (Code) → [existing downstream]
```
**HTTP Request nodes transformed:**
- Method: `GET``POST`
- URL: `http://docker-socket-proxy:2375/containers/json?all=true``={{ $env.UNRAID_HOST }}/graphql`
- Query: `query { docker { containers { id names state image } } }`
- Headers: `Content-Type: application/json`, `x-api-key: ={{ $env.UNRAID_API_KEY }}`
- Timeout: 5000ms → 15000ms (cloud relay safety margin)
- Error handling: `continueRegularOutput`
**GraphQL Response Normalizer (5 identical nodes):**
- Input: `{data: {docker: {containers: [{id, names, state, image}]}}}`
- Output: `[{Id, Names, State, Status, Image, _unraidId}]` (Docker API contract)
- State mapping: `RUNNING → running`, `STOPPED → exited`, `PAUSED → paused`
- n8n multi-item output format: `[{json: container}, ...]`
**Downstream Code nodes (UNCHANGED - verified):**
- Build Batch Keyboard (bitmap encoding, pagination, keyboard building)
- Handle Toggle (bitmap toggle logic)
- Handle Exec (bitmap to names resolution, confirmation routing)
- Rebuild Keyboard After Toggle (bitmap decoding, keyboard rebuild)
- Rebuild Keyboard For Nav (page navigation, keyboard rebuild)
- Rebuild Keyboard After Clear (reset to empty bitmap)
- Handle Cancel (return to container list)
All bitmap encoding, container sorting, pagination, and keyboard building logic preserved byte-for-byte.
### Zero-Change Migration Pattern
**Docker API contract fields preserved:**
- `Id` - Full Unraid PrefixedID (Container ID Registry handles translation)
- `Names` - Array with `/` prefix (e.g., `["/plex"]`)
- `State` - Lowercase state (`running`, `exited`, `paused`)
- `Status` - Same as State (Docker API convention)
- `Image` - Empty string (not queried, not used by batch UI)
**Why this works:**
- All downstream Code nodes reference `Names[0]`, `State`, `Id.substring(0, 12)`
- Normalizer ensures these fields exist in the exact format expected
- Bitmap encoding uses array indices, not IDs (migration transparent)
- Container sorting uses state and name (both preserved)
## Deviations from Plan
None - plan executed exactly as written.
## Authentication Gates
None encountered.
## Testing & Verification
**Automated verification (all passed):**
1. ✓ Zero HTTP Request nodes contain "docker-socket-proxy"
2. ✓ All 5 HTTP Request nodes use POST to `$env.UNRAID_HOST/graphql`
3. ✓ 5 GraphQL Response Normalizer Code nodes exist (one per query path)
4. ✓ All downstream Code nodes byte-for-byte identical to pre-migration
5. ✓ Node count: 22 (17 original + 5 normalizers)
6. ✓ All connection chains valid (15 connections verified)
7. ✓ Pushed to n8n successfully (HTTP 200, workflow ID `ZJhnGzJT26UUmW45`)
**Connection chain validation:**
- Route Batch UI Action → Fetch Containers For Mode → Normalizer → Build Batch Keyboard ✓
- Needs Keyboard Update? → Fetch Containers For Update → Normalizer → Rebuild Keyboard ✓
- Route Batch UI Action → Fetch Containers For Exec → Normalizer → Handle Exec ✓
- Handle Nav → Fetch Containers For Nav → Normalizer → Rebuild Keyboard For Nav ✓
- Handle Clear → Fetch Containers For Clear → Normalizer → Rebuild Keyboard After Clear ✓
**Manual testing required:**
- Open Telegram bot, start batch selection (`/batch` command path)
- Verify container list displays with correct names and states
- Toggle container selection, verify checkmarks update correctly
- Navigate between pages, verify pagination works
- Execute batch start action, verify correct containers are started
- Execute batch stop action, verify confirmation prompt appears
- Clear selection, verify UI resets to empty state
## Impact Assessment
**User-facing changes:**
- None - UI and behavior identical to pre-migration
**System changes:**
- Removed dependency on docker-socket-proxy for batch container listing
- Added dependency on Unraid GraphQL API + myunraid.net cloud relay
- Increased query timeout from 5s to 15s (cloud relay latency)
- Added 5 normalizer nodes (increased workflow complexity slightly)
**Performance impact:**
- Query latency: +200-500ms (cloud relay overhead vs local Docker socket)
- User-perceivable: Minimal (batch selection already async)
- Timeout safety: 15s provides 30x safety margin over typical 500ms latency
**Risk mitigation:**
- GraphQL error handling: normalizer throws on errors → captured by n8n error handling
- Invalid response structure: explicit validation with descriptive errors
- State mapping: comprehensive (RUNNING, STOPPED, PAUSED) + fallback to lowercase
## Known Limitations
**Current state:**
- Image field empty (not queried) - batch UI doesn't use it, no impact
- No retry logic on GraphQL failures (relies on n8n default retry)
- Cloud relay adds latency (200-500ms) - acceptable for batch operations
**Future improvements:**
- Could add retry logic with exponential backoff for cloud relay transient failures
- Could query image field if future batch features need it
- Could implement local caching if latency becomes problematic (unlikely for batch ops)
## Next Steps
**Immediate:**
- Phase 16 Plan 05: Migrate remaining workflows (Container Status, Confirmation, etc.)
**Follow-up:**
- Manual testing of batch selection end-to-end
- Monitor cloud relay latency in production
- Consider removing docker-socket-proxy container once all migrations complete
## Self-Check: PASSED
**Files verified:**
- ✓ FOUND: n8n-batch-ui.json (modified, 22 nodes)
- ✓ FOUND: n8n-batch-ui.json pushed to n8n (HTTP 200)
**Commits verified:**
- ✓ FOUND: 73a01b6 (feat(16-04): migrate Batch UI to Unraid GraphQL API)
**Claims verified:**
- ✓ 5 GraphQL Response Normalizer nodes exist in workflow
- ✓ All 5 HTTP Request nodes use GraphQL (verified in workflow JSON)
- ✓ Zero docker-socket-proxy references (verified in workflow JSON)
- ✓ Downstream Code nodes unchanged (verified byte-for-byte during transformation)
All summary claims verified against actual implementation.