Repository navigation
Description
Audit and Fix: Complete Parent Relationship Migration for Graph-Native Architecture
Problem
Issue #528 fixed placeholder promotion to include _parentId/_containerId transient fields, but there are 128 other references to parentId in the frontend codebase that may need similar fixes. Without these fields, nodes are created as orphans with no has_child edges, breaking the tree structure and reactivity.
Status
Partially Fixed in #528:
- ✅ Placeholder promotion in base-node-viewer now includes
_parentId/_containerId - ✅ Typing in placeholder nodes works
- ❌ Other node creation paths still broken
See: #528
Root Cause
The graph-native migration (#511, #514) moved parent-child relationships from fields (parent_id, container_node_id) to graph edges (has_child), but the frontend still has code paths that:
- Try to read
node.parentId(no longer exists) - Create nodes without establishing parent edges
- Query by parent without using the new hierarchy APIs
Scope
Found: 128 references to parentId in frontend (excluding tests)
Critical paths that need parent relationship:
- Placeholder promotion (✅ FIXED in Bug: Placeholder node loses focus immediately after typing, preventing text input #528)
- Node splitting operations (❓ needs verification)
- Indent/outdent operations (❓ needs verification)
- Enter key creating sibling/child nodes (❓ needs verification)
- Slash command node creation (❓ needs verification)
- Mention node creation (❓ needs verification)
- Manual node creation APIs (❓ needs verification)
Audit Checklist
Phase 1: Identify All Node Creation Points
Files to audit:
-
base-node-viewer.svelte- Placeholder promotion (✅ FIXED in Bug: Placeholder node loses focus immediately after typing, preventing text input #528) -
base-node.svelte- Split/Enter operations -
shared-node-store.ts- Persistence layer createNode calls (5+ instances) -
node-reference-service.ts- Mention node creation -
hierarchy-service.ts- Tree manipulation operations -
reactive-node-service.svelte.ts- Node management APIs
For each createNode() call, verify:
- Does it pass
_parentIdand_containerId? - If not, should it? (Is this a child node or root node?)
- Is the parent relationship established via
set_parent()afterward?
Phase 2: Categorize by Fix Needed
Category A: Needs _parentId/_containerId (like #528 fix)
- Nodes created as children of existing nodes
- Need parent edge created immediately
Category B: Needs Explicit setParent() Call
- Complex creation where parent isn't known at creation time
- Two-step: create node, then establish relationship
Category C: Already Correct (Root Nodes)
- Container nodes (dates, etc.)
- Should NOT have parent
- No fix needed
Phase 3: Fix Each Category
For Category A nodes:
// Add transient fields before createNode
const nodeToCreate = {
...node,
_parentId: currentParentId,
_containerId: currentContainerId
};
await tauriNodeService.createNode(nodeToCreate);For Category B nodes:
// Create first
const newNode = await tauriNodeService.createNode(node);
// Then establish relationship
await tauriNodeService.setParent(newNode.id, parentId);Implementation Plan
Step 1: Comprehensive Audit
Create a spreadsheet/document listing:
- File:Line number
- Function name
- Current code
- Category (A, B, or C)
- Fix needed (yes/no)
- Priority (critical/high/medium/low)
Step 2: Fix Critical Paths First
Priority order:
- Placeholder typing (✅ DONE in Bug: Placeholder node loses focus immediately after typing, preventing text input #528)
- Enter key operations (create sibling/child)
- Indent/outdent (moves nodes, changes parent)
- Node splitting (creates new node with same parent)
- Slash commands (create typed nodes)
- Mention creation (create referenced nodes)
Step 3: Update Shared Services
Centralize parent handling in shared-node-store:
// shared-node-store.ts
/**
* Helper: Enrich node with parent context before persistence
* Adds transient _parentId/_containerId fields for backend edge creation
*/
function enrichNodeWithParentContext(
node: Node,
parentCache: Map<string, string>
): Node & { _parentId?: string; _containerId?: string } {
const parentId = parentCache.get(node.id);
if (!parentId) {
// Root node - no parent fields
return node;
}
return {
...node,
_parentId: parentId,
_containerId: parentId // Assuming parent === container for most cases
};
}
// Use in all createNode paths
async function persistNode(node: Node) {
const enrichedNode = enrichNodeWithParentContext(node, this.parentChildCache);
await tauriNodeService.createNode(enrichedNode);
}Step 4: Testing Strategy
For each fixed createNode() path:
- Unit test: Verify
_parentIdfield is included - Integration test: Verify
has_childedge is created - Manual test: Verify tree structure appears correctly
Regression tests:
- Can type in placeholder nodes (✅ from Bug: Placeholder node loses focus immediately after typing, preventing text input #528)
- Can press Enter to create siblings
- Can indent/outdent nodes
- Can use slash commands to create typed nodes
- Tree structure displays correctly after operations
Acceptance Criteria
Functional
- All node creation paths establish parent relationships correctly
- Tree structure is correct (can query children via
getChildren()) - No orphan nodes created (except intentional root nodes)
- Reactivity works (UI updates when hierarchy changes)
Technical
- All 128
parentIdreferences audited and categorized - Critical paths (placeholder, Enter, indent/outdent) fixed
- Less critical paths (mentions, slash commands) fixed
- Shared services centralize parent context handling
- All tests pass
Testing
- Unit tests for each fix
- Integration tests verify
has_childedges created - Manual testing confirms tree operations work
- No regressions in existing functionality
Known Issues
Fixed in #528:
- ✅ Placeholder promotion in base-node-viewer
Likely Still Broken (needs verification):
- ❓ Node splitting (creates sibling without parent edge?)
- ❓ Indent/outdent (changes parent but edge not updated?)
- ❓ Enter key (creates sibling/child - edge created?)
- ❓ Slash command nodes (created with parent edge?)
- ❓ Mention autocomplete creating referenced nodes
Related Issues
- Bug: Placeholder node loses focus immediately after typing, preventing text input #528: Placeholder typing fix (partial solution - REFERENCE THIS)
- Remove parent_id/container_node_id from Node API - Complete Graph Migration #514: Removed parent_id fields (introduced the problem)
- SurrealDB Schema Refactor: Graph-Native Architecture #511: Graph-native architecture (root cause of migration)
- Implement Atomic Transactional Node Operations #532: Atomic operations (can be implemented alongside this)
Estimated Effort
- Audit: 2-3 hours (catalog all 128 references)
- Critical fixes: 4-6 hours (Enter, indent/outdent, split)
- Remaining fixes: 6-8 hours (mentions, slash commands, etc.)
- Testing: 4-6 hours (unit + integration + manual)
- Total: 16-23 hours (2-3 days)
Priority
CRITICAL - Core functionality (typing, tree manipulation) is broken without these fixes.
Activity
malibio commentedon Nov 17, 2025
Combining with #531 into a single comprehensive issue