- 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)
8.6 KiB
phase, plan, subsystem, tags, dependency_graph, tech_stack, key_files, decisions, metrics
| phase | plan | subsystem | tags | dependency_graph | tech_stack | key_files | decisions | metrics | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 16-api-migration | 04 | n8n-batch-ui |
|
|
|
|
|
|
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:
- Fetch Containers For Mode - Initial batch selection entry
- Fetch Containers For Update - After toggling container selection
- Fetch Containers For Exec - Before batch action execution
- Fetch Containers For Nav - Page navigation
- 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):
- ✓ Zero HTTP Request nodes contain "docker-socket-proxy"
- ✓ All 5 HTTP Request nodes use POST to
$env.UNRAID_HOST/graphql - ✓ 5 GraphQL Response Normalizer Code nodes exist (one per query path)
- ✓ All downstream Code nodes byte-for-byte identical to pre-migration
- ✓ Node count: 22 (17 original + 5 normalizers)
- ✓ All connection chains valid (15 connections verified)
- ✓ 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 (
/batchcommand 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.