Minimal Impact Multilingual Database Migration Notion
TITLE: Dual-Database Strategy for Seamless System Migration
TL;DR
- Dual-database coexistence: new English DB runs parallel, 30% API increase
- One YAML field modification enables switching in under 5 minutes
- n8n script requires language adaptation layer, not direct string replacement
- Webhook silently returns empty values on missing fields
- Quantifying impact scope determines migration approach
Problem Background
The PMO system’s English localization was not a translation challenge but an engineering problem. Our Notion database contained approximately 1,200 task records with Chinese field names: project names, statuses, assignees, and deadlines. Seventeen n8n nodes hardcoded field references, so renaming would cause silent field mapping failures.
The critical issue: n8n webhooks do not throw errors when fields are missing. They silently return empty values. You learn about migration failures only when processes complete with no data.
Decision Complexity
We initially assumed the core risk was translation accuracy. The actual risk was uncontrolled impact scope. Direct field renaming required checking 17 n8n nodes individually, each taking 10-15 minutes, with debugging cycles lasting 2-3 days. Worse, webhooks from the legacy database still sent Chinese status values while the new database expected English equivalents like “In Progress”—script-level conditional logic would silently break.
Quantifying impact changed our approach:
- Direct migration: 17 nodes modified, 2-3 day debugging, zero rollback capability
- Dual-database coexistence: new database stable for 2 weeks, 30% API increase, rollback available at any time
“Bounded cost with rollback capability” outweighed “faster but rigid.”
Core Design Decision
Early n8n configurations hardcoded database IDs in node internals—a design flaw requiring 2-3 hours of per-node inspection for every migration. We extracted IDs to agent-CEO/config/n8n_integration.yaml, maintaining a database_ids dictionary. Switching became a matter of modifying one YAML field and restarting the workflow—no node-by-node changes needed.
The script layer had three Chinese condition checks using if status == "进行中". Direct replacement failed because legacy webhooks still sent Chinese values. The solution was a language adaptation layer:
STATUS_MAP = {"进行中": "In Progress", "已完成": "Completed"}
if STATUS_MAP.get(status, status) == "In Progress":
# handles both Chinese and English values
Key Takeaways
- If you migrate complex systems, centralize database references to avoid hardcoding
- If you handle multilingual data, build translation layers instead of direct string substitution
- If you rely on webhooks, assume silent failures and add explicit error handling
- If you plan database transitions, quantify impact scope before choosing your approach
- If you maintain n8n workflows, keep all external IDs in single configuration files
Read the Full Article (Chinese)
This is an abstract. The full technical walkthrough is in Chinese.