fix: preserve workflow data during serialization (Issue #517) (#519)

Fixed a critical bug where workflow mutation data was corrupted during
serialization to Supabase. The recursive toSnakeCase() function was
converting nested workflow data, mangling:
- Connection keys (node names like "Webhook" → "_webhook")
- Node field names (typeVersion → type_version)

Solution: Replace recursive conversion with selective mutationToSupabaseFormat()
that only converts top-level field names to snake_case while preserving
nested workflow data exactly as-is.

Impact:
- 98.9% of workflow mutations had corrupted data
- Deployability rate improved from ~21% to ~68%

Changes:
- src/telemetry/batch-processor.ts: New selective converter
- tests/unit/telemetry/batch-processor.test.ts: 3 new regression tests

Conceived by Romuald Członkowski - https://www.aiadvisors.pl/en

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Romuald Członkowski <romualdczlonkowski@MacBook-Pro-Romuald.local>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Romuald Członkowski
2026-01-02 10:44:13 +01:00
committed by GitHub
parent 808088f25e
commit f10772a9d2
4 changed files with 321 additions and 17 deletions

View File

@@ -7,6 +7,43 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
## [2.31.4] - 2026-01-02
### Fixed
**Workflow Data Mangled During Serialization: snake_case Conversion (Issue #517)**
Fixed a critical bug where workflow mutation data was corrupted during serialization to Supabase, making 98.9% of collected workflow data invalid for n8n API operations.
**Problem:**
The `toSnakeCase()` function in `batch-processor.ts` was applied **recursively** to the entire mutation object, including nested workflow data that should be preserved exactly as-is:
- **Connection keys mangled**: Node names like `"Webhook"` became `"_webhook"`, `"AI Agent"` became `"_a_i _agent"`
- **Node field names mangled**: n8n camelCase fields like `typeVersion`, `webhookId`, `onError` became `type_version`, `webhook_id`, `on_error`
**Root Cause:**
```javascript
// Old code - recursive conversion corrupted nested data
result[snakeKey] = toSnakeCase(obj[key]); // WRONG
```
**Solution:**
Replaced recursive `toSnakeCase()` with selective `mutationToSupabaseFormat()` that:
- Converts **only** top-level field names to snake_case (for Supabase columns)
- Preserves all nested data (workflow JSON, operations, validations) **exactly as-is**
```javascript
// New code - preserves nested workflow structure
for (const [key, value] of Object.entries(mutation)) {
result[keyToSnakeCase(key)] = value; // Value preserved as-is
}
```
**Impact:**
- Workflow mutation data now maintains n8n API compatibility
- Deployability rate improved from ~21% to ~68%
- Added 3 regression tests to prevent future occurrences
## [2.31.3] - 2025-12-26
### Fixed