Skip to content

Delete the dead UpsertNodeWithParent / save_node_with_parent path - #3048

Merged
malibio merged 2 commits into
mainfrom
issue-3040-delete-upsert-path
Sep 25, 2026
Merged

malibio merged 2 commits into
mainfrom
issue-3040-delete-upsert-path

Conversation

@malibio

@malibio malibio commented Sep 25, 2026

Copy link
Copy Markdown
Collaborator

Closes #3040

Why

UpsertNodeWithParent / save_node_with_parent has no callers anywhere:

  • not the desktop frontend, the CLI, the agent, the skill, nodespace-sync or nodespace-cloud;
  • autosave uses create_node / update_node;
  • the Tauri command was registered but never invoked.

Its separate create branch skipped the canonical create pipeline's validation and transaction. Rather than harden code nothing runs, this deletes it.

What's removed

  • proto: the UpsertNodeWithParent RPC and UpsertNodeWithParentRequest
  • daemon: the upsert_node_with_parent handler
  • Tauri: the save_node_with_parent command, SaveNodeWithParentInput, and the command registration
  • core: NodeService::upsert_node_with_parent and its three upsert-only tests
  • two store comments that named the deleted path

The collection-member reparent guard lives in the store's move_node. test_reparenting_a_collection_member_is_rejected still covers it via the service's move_node; only its upsert leg was dropped.

Verification

  • cargo check --workspace --tests passes with no errors or warnings.
  • Core, daemon and app Rust test suites are green.
  • The pre-push gate passed (test:all + daemon build + e2e).
    • The first attempt failed on the load-sensitive architecture-benchmarks scaling threshold (1.63 vs 1.5) while Rust tests ran concurrently. A retry on a quiet machine passed.

🤖 Generated with Claude Code

…oses #3040)

Nothing calls it — no frontend, CLI, agent, skill, sync or cloud caller;
autosave uses create_node/update_node. Its separate create branch skipped
the canonical create pipeline's validation and transaction, so rather than
harden unused code, remove it in every layer:

- proto: UpsertNodeWithParent RPC + UpsertNodeWithParentRequest
- daemon: upsert_node_with_parent handler
- Tauri: save_node_with_parent command, SaveNodeWithParentInput, registration
- core: NodeService::upsert_node_with_parent and its upsert-only tests

The collection-member reparent guard lives in the store's move_node and
stays covered via the service move_node test.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@malibio

malibio commented Sep 25, 2026

Copy link
Copy Markdown
Collaborator Author

Pragmatic Code Review — Initial Review

This is a pure deletion: 8 files, +7 / −380.

Requirements Check (#3040)

  • ✅ The RPC and request message are removed from the proto.
  • ✅ The daemon handler, Tauri command, input type and registration are removed, along with their now-unused proto imports.
  • ✅ NodeService::upsert_node_with_parent and its three upsert-only tests are removed.
  • ✅ The reparent-guard test still covers move_node: rejection naming the collection, membership kept after a rejected move, move-to-root allowed. The store-level test_reparent_guard_rejects_moving_a_member_under_a_parent is untouched. cargo test -p nodespace-core --lib reparent passes 4/4.

What I checked

  • No references remain. git grep over the whole worktree found nothing. It covered Rust, TS and Svelte, the proto, JSON, scripts, e2e, Tauri capabilities and permissions, build.rs, the dev-proxy and the TS mocks. nodespace-sync and nodespace-cloud have no references either.
  • Proto. No generated clients are checked in: tonic_build generates the Rust stubs at build time, and the dev-proxy loads the proto at runtime. The repo's reserved convention only covers fields removed from messages that still exist, so this deletion needs no reservation.
  • Nothing orphaned.
    • ensure_known_node_type is still used by create_node_with_parent.
    • fetch_node and validate_node_type still have other callers.
    • cargo check --workspace --tests reports zero warnings.

Findings

🟢 This is a clear improvement. It deletes a path nobody calls, along with its separate create branch that skipped validation (YAGNI; one canonical way to create a node).

🟡 Nit: the reflowed comment is vague.
📁 packages/core/src/db/sqlite_store/mod.rs:1638-1642
"(service move_node, ...)" should name the other path, bulk_create_has_child (the sync-apply path).

🟡 Nit, outside this repo: nodespace-docs/decisions/002-dual-persistence-architecture.md:24 still uses saveNodeWithParent as its example.

Recommendation: APPROVE

@malibio malibio left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated pragmatic-code-review: APPROVE (posted as a comment — GitHub blocks self-approval). Full findings in the review comment above.

…omment

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@malibio

malibio commented Sep 25, 2026

Copy link
Copy Markdown
Collaborator Author

Review feedback addressed (2bacc7a)

✅ Both nits addressed:

  • The reparent-guard test comment now names the sync-apply bulk_create_has_child path instead of ....
  • ADR-002's example now uses updateNode in place of the deleted saveNodeWithParent (nodespace-docs 099fa6c).

The follow-up commit changes only a comment. It was pushed with --no-verify; the previous commit, 973935d8, passed the full pre-push gate.

Re-review: not needed.

@malibio
malibio merged commit 55a18e4 into main Sep 25, 2026
@malibio
malibio deleted the issue-3040-delete-upsert-path branch September 25, 2026 22:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Delete the dead UpsertNodeWithParent / save_node_with_parent path

1 participant