⚡ Bolt: Optimize ERD edge handle column parsing - #641
Conversation
This commit introduces a new `parseColumnNameFromHandle` utility function that decodes edge handle IDs directly into column names in O(1) time. Previously, export functions like DBML, Mermaid, and Data Dictionary were using O(N * C) loops that repeatedly re-encoded every column in the entire table to find a match. This significantly reduces CPU overhead and garbage collection during export of large diagrams.
|
👋 Jules, reporting for duty! I'm here to lend a hand with this pull request. When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down. I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job! For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with New to Jules? Learn more at jules.google/docs. For security, I will only act on instructions from the user who triggered this task. |
|
|
||
| import type { ForeignKeyEdgeData, TableNodeData } from './convert'; | ||
| import { sourceColumnHandleId } from './handleUtils'; | ||
| import { parseColumnNameFromHandle, sourceColumnHandleId } from './handleUtils'; |
| import type { Node, Edge } from "@xyflow/react"; | ||
| import type { TableNodeData } from "./convert"; | ||
| import { sanitizeHandleId } from "./handleUtils"; | ||
| import { parseColumnNameFromHandle, sanitizeHandleId } from "./handleUtils"; |
There was a problem hiding this comment.
Pull request overview
This PR optimizes ERD export logic by decoding React Flow handle IDs back into original column names via a new utility (parseColumnNameFromHandle), avoiding repeated handle-encoding scans and fixing DBML fallback behavior when edge metadata is missing.
Changes:
- Added
parseColumnNameFromHandleto decodesrc-/tgt-handle IDs (e.g.src-c-0069-0064) back to the original column name. - Refactored Mermaid / Data Dictionary / DDL export column resolution to use decoded column names rather than re-encoding every column for comparisons.
- Updated/expanded export and handle utility tests and documented the optimization in
.jules/bolt.md.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| frontend/src/erd/mermaid.ts | Uses decoded handle column names to build FK lookups during Mermaid export. |
| frontend/src/erd/handleUtils.ts | Introduces parseColumnNameFromHandle for O(1) decode of handle IDs. |
| frontend/src/erd/handleUtils.test.ts | Adds unit tests covering handle decoding (ascii/unicode/emoji/empty). |
| frontend/src/erd/exportDataDictionary.ts | Simplifies FK column detection to use decoded handle columns. |
| frontend/src/erd/export.ts | Updates FK column resolution for DDL/export paths to use decoded handles. |
| frontend/src/erd/dbml.ts | Fixes DBML fallback to output real decoded column names from handles. |
| frontend/src/erd/tests/dbml.test.ts | Updates DBML tests to use encoded handle IDs. |
| frontend/src/erd/tests/coverageEdges.test.ts | Updates defensive coverage tests for encoded handles / empty-handle cases. |
| .jules/bolt.md | Records the performance learning/action for handle decoding optimization. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| export function parseColumnNameFromHandle(handleId: string | null | undefined): string | null { | ||
| if (!handleId) return null; | ||
| const match = handleId.match(/^(?:src-|tgt-)?c-(.+)$/); | ||
| if (!match) return null; | ||
| const encoded = match[1]; | ||
| if (encoded === 'empty') return ''; | ||
| return encoded.split('-').map(hex => String.fromCodePoint(parseInt(hex, 16))).join(''); | ||
| } |
| import type { Node, Edge } from "@xyflow/react"; | ||
| import type { TableNodeData } from "./convert"; | ||
| import { sanitizeHandleId } from "./handleUtils"; | ||
| import { parseColumnNameFromHandle, sanitizeHandleId } from "./handleUtils"; |
| import type { ForeignKeyEdgeData, TableNodeData } from './convert'; | ||
| import { sourceColumnHandleId } from './handleUtils'; | ||
| import { parseColumnNameFromHandle, sourceColumnHandleId } from './handleUtils'; | ||
|
|
💡 What:
Introduced a new O(1) utility function
parseColumnNameFromHandleto extract the original column name directly from the React Flow edge handles (e.g.,src-c-0069-0064), and applied it across all the ERD export functions (export.ts,dbml.ts,mermaid.ts,exportDataDictionary.ts).🎯 Why:
Previously, to resolve which column an edge was connected to, the export logic had to iterate through all columns on a node and run the expensive
sanitizeHandleIdencoding function on every single one until it found a match against the edge handle (an O(N * C) search). Additionally, the DBML export had a silent bug where it was just doing.replace('src-', '')and accidentally exporting the raw hex string (c-0069-0064) into the DBML schema instead of the real column name.📊 Impact:
🔬 Measurement:
coverageEdges.test.ts,export.test.ts,dbml.test.ts,mermaid.test.ts) were executed and pass, with updated mocks confirming the DBML bugfix.PR created automatically by Jules for task 10260667443787725602 started by @seonghobae