Skip to content

Refactor/Zero shell-only mutators#396

Merged
urjitc merged 2 commits into
stagingfrom
capy/shell-only-mutators
Apr 18, 2026
Merged

Refactor/Zero shell-only mutators#396
urjitc merged 2 commits into
stagingfrom
capy/shell-only-mutators

Conversation

@urjitc

@urjitc urjitc commented Apr 18, 2026

Copy link
Copy Markdown
Member

This PR optimizes Zero mutators by introducing a shell-only update path to avoid unnecessary writes to workspace_item_content during layout and move operations. Additionally, it fixes the updateMany server mutator to only sync extracted rows for content-affecting operations.

  • src/lib/zero/mutators.ts
    • Add updateShellOnly() helper for targeted workspace_items updates.
    • Refactor updateMany.layoutUpdates, move, moveMany, and folder.createWithItems to use updateShellOnly().
    • Update deleteItemById folder child promotion to use updateShellOnly().
  • src/lib/zero/server-mutators.ts
    • Replace withAuth wrapper for item.updateMany with custom defineMutator to conditionally sync extracted rows.
  • src/lib/db/schema.ts
    • Remove dead workspaceSnapshots table definition.
  • src/contexts/WorkspaceContext.tsx
    • Update stale comment referencing event sourcing architecture.

Open ENG-001 ENG-001

@urjitc urjitc added the capy Generated by capy.ai label Apr 18, 2026 — with Capy AI
@vercel

vercel Bot commented Apr 18, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
thinkex Ready Ready Preview, Comment Apr 18, 2026 10:34pm

Request Review

@coderabbitai

coderabbitai Bot commented Apr 18, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 11a8238e-ee2c-491b-8146-36472004a72b

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch capy/shell-only-mutators

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@greptile-apps

greptile-apps Bot commented Apr 18, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR introduces a updateShellOnly() helper in the client mutators to skip unnecessary workspace_item_content writes during layout, move, and folder-assignment operations, and updates the item.updateMany server mutator to skip extracted-row syncs for layout-only changes. The workspaceSnapshots dead code and a stale comment are also cleaned up.

  • One inconsistency in folder.createWithItems: the server mutator still passes [args.folder.id, ...args.itemIds] to withAuth, triggering extracted-row syncs for all moved items — even though those items only receive a shell-only folderId change (same pattern fixed for move/moveMany). Only args.folder.id needs syncing.

Confidence Score: 4/5

Safe to merge with one minor inconsistency: folder.createWithItems still performs unnecessary extracted-row syncs for moved items.

All core optimizations are correctly applied. The single finding is a P2 inefficiency (redundant DB work) that contradicts the PR's stated goal but does not break correctness or cause data loss.

src/lib/zero/server-mutators.ts — the folder.createWithItems withAuth item-ID list should be narrowed to [args.folder.id] only.

Important Files Changed

Filename Overview
src/lib/zero/mutators.ts Adds updateShellOnly() helper and refactors layout/move/folder operations to use it, correctly avoiding unnecessary workspace_item_content writes.
src/lib/zero/server-mutators.ts Replaces withAuth for updateMany with a custom mutator that skips extracted-row sync for layout-only updates. However, folder.createWithItems still syncs extracted rows for all moved items despite those items only receiving shell-only folderId changes.
src/lib/db/schema.ts Removes dead workspaceSnapshots table definition; no other changes.
src/contexts/WorkspaceContext.tsx Updates stale comment referencing event-sourcing architecture; no logic changes.

Comments Outside Diff (1)

  1. src/lib/zero/server-mutators.ts, line 352-357 (link)

    P2 folder.createWithItems still syncs extracted rows for shell-only moved items

    withAuth is called with (args) => [args.folder.id, ...args.itemIds], which syncs extracted rows for the folder AND all moved items. However, in the shared mutator, the existing items are only updated via updateShellOnly() — just a folderId change with no content write. This is exactly the same pattern that was fixed for updateMany.layoutUpdates and for move/moveMany, which were both downgraded to withAuthOnly.

    Only the new folder itself (args.folder.id) needs an extracted-row sync; the moved items' content is unchanged and their extracted records are already up to date.

    Fix in Cursor

Fix All in Cursor

Reviews (1): Last reviewed commit: "Optimize Zero mutators to eliminate unne..." | Re-trigger Greptile

@capy-ai capy-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Added 1 comment

Comment thread src/lib/db/schema.ts

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

1 issue found across 4 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="src/lib/zero/mutators.ts">

<violation number="1" location="src/lib/zero/mutators.ts:385">
P2: `updateShellOnly` performs a blind `update` without verifying the item exists. Because Zero `update` is a no-op for missing PKs, move/layout operations can now silently succeed on nonexistent items instead of returning a not-found error.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread src/lib/zero/mutators.ts Outdated
updates.lastModified = params.shellChanges.lastModified;
}

await tx.mutate.workspace_items.update(updates);

@cubic-dev-ai cubic-dev-ai Bot Apr 18, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2: updateShellOnly performs a blind update without verifying the item exists. Because Zero update is a no-op for missing PKs, move/layout operations can now silently succeed on nonexistent items instead of returning a not-found error.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/lib/zero/mutators.ts, line 385:

<comment>`updateShellOnly` performs a blind `update` without verifying the item exists. Because Zero `update` is a no-op for missing PKs, move/layout operations can now silently succeed on nonexistent items instead of returning a not-found error.</comment>

<file context>
@@ -353,6 +353,38 @@ async function upsertItem(
+    updates.lastModified = params.shellChanges.lastModified;
+  }
+
+  await tx.mutate.workspace_items.update(updates);
+}
+
</file context>
Suggested change
await tx.mutate.workspace_items.update(updates);
const existing = await tx.run(
zql.workspace_items
.where("workspaceId", params.workspaceId)
.where("itemId", params.itemId)
.one(),
);
if (!existing) {
throw new ApplicationError(`Workspace item ${params.itemId} was not found.`);
}
await tx.mutate.workspace_items.update(updates);
Fix with Cubic

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

0 issues found across 1 file (changes from recent commits).

Requires human review: Auto-approval blocked by 1 unresolved issue from previous reviews.

@urjitc
urjitc merged commit d4d2365 into staging Apr 18, 2026
5 checks passed
@github-project-automation github-project-automation Bot moved this from Backlog to Done in Dev Board Apr 18, 2026
@urjitc
urjitc deleted the capy/shell-only-mutators branch June 29, 2026 17:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

capy Generated by capy.ai

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant