Skip to content

Fix Electric create sync txids#4632

Open
KyleAMathews wants to merge 8 commits into
superset-sh:mainfrom
KyleAMathews:fix/electric-create-sync-txids
Open

Fix Electric create sync txids#4632
KyleAMathews wants to merge 8 commits into
superset-sh:mainfrom
KyleAMathews:fix/electric-create-sync-txids

Conversation

@KyleAMathews
Copy link
Copy Markdown

@KyleAMathews KyleAMathews commented May 16, 2026

Summary

Hardens workspace/project/chat writes against Electric sync races by returning correct txids from backend mutations, awaiting them in renderer collection handlers, and removing the parallel in-memory workspace-create sidecar that modeled in-flight cloud rows outside TanStack DB.

User-visible impact: Workspace create, rename, delete, import/adopt, and secondary navigation surfaces no longer race ahead of Electric confirmation, and optimistic UI is gated on sync/delete state.

Approach

Electric txid correctness

  • getCurrentTxid() now returns pg_current_xact_id()::xid::text, parsed and validated as a safe integer.
  • Added a shared ELECTRIC_WRITE_SYNC_TIMEOUT_MS = 30_000 constant for all write confirmation waits.
  • Collection mutation handlers return a txid match only when numeric, using the shared timeout.
  • v2Workspaces.onUpdate now uses the same txid matching helper (previously returned { txid: result.txid } directly).
  • No-op mutations return no txid instead of inventing a confirmation token.
  • Backend update/delete paths now use .returning() or equivalent affected-row checks before calling getCurrentTxid(), so a raced no-op DML cannot fabricate a txid Electric will never emit.

Note on xid casting: We discovered getCurrentTxid() was using pg_current_xact_id()::text without the ::xid:: cast. Electric receives 32-bit xid values through logical replication, so the correct form is pg_current_xact_id()::xid::text. Without the cast, the values happen to match on fresh databases (epoch = 0), but would diverge after ~4.29B txids when the epoch increments. Whether this contributed to reported timeouts is unconfirmed (depends on transaction volume), but it's a correctness fix regardless.

Workspace create/import flow

  • v2Workspace.create, v2Project.create, and chat.createSession wrap writes in transactions and return txids.
  • useWorkspaceCreates.submit() flow:
    1. Optimistic v2Workspaces.insert()
    2. Await TanStack tx.isPersisted.promise
    3. Wait for canonical workspace id to exist locally with $synced === true
    4. Write local sidebar/pane state
    5. Return the canonical id
  • Existing unsynced optimistic rows no longer short-circuit as successful creates.
  • Canonical-id mismatches still rollback the optimistic id, but only after the canonical row is confirmed.
  • V1 workspace import/adopt now waits for the adopted v2 workspace row to be synced before writing sidebar state.

Navigation and UI guards

  • New workspace modal and task sidebar OpenInWorkspaceV2 no longer navigate optimistically; they await submit() and open the confirmed id.
  • V2WorkspaceLayout refuses to mount host-backed workspace UI for unsynced optimistic rows ($synced check).
  • Sidebar workspace data and /v2-workspaces list filter out unsynced rows and rows being deleted, preventing stale actions and hotkey targets.
  • Command palette workspace context is only populated for synced, non-deleting workspaces.
  • Resource monitor and sidebar ports now filter workspace metadata through the same synced/non-deleting boundary before exposing navigation.

Delete/update coverage

  • v2Workspace.delete and deleteMainForHost now return txids for real deletes and return no txid for already-gone raced deletes.
  • Renderer waits for the cloud delete txid and for the row to disappear from the local Electric collection before considering delete complete.
  • If Electric confirmation is slow, the renderer hides the entry and keeps it in deleting state rather than re-enabling stale actions.
  • Auxiliary mutations (setTask, updateNameFromHost) return txids for real writes.
  • Host membership rename/remove/role update paths no longer return txids unless the underlying replicated row actually changed.
  • Chat delete no-op no longer returns a txid.

Removed workspace-create sidecar

Removed the renderer-memory workspace-create model and related fallback UI:

  • WorkspaceCreatingState/, WorkspaceCreateErrorState/, workspace-creates/Manager.tsx, workspace-creates/store.ts
  • Sidebar creationStatus plumbing, pending/failed in-flight row injection
  • V2WorkspaceTitle in-flight fallback

The remaining create path uses TanStack DB's optimistic entry plus Electric confirmation only.

Key Invariants

  • getCurrentTxid() must be called inside the same SQL transaction as a real replicated write.
  • The returned txid must match Electric's logical-replication xid form: pg_current_xact_id()::xid::text.
  • Renderer navigation into host-backed workspace UI only happens after the cloud row is present locally with $synced === true.
  • Sidebar, /v2-workspaces, command palette, resource monitor, and port actions only see synced rows not currently being deleted.
  • No collection handler returns { txid: null } or { txid: undefined } to TanStack's Electric adapter.

Non-goals

  • Didn't address unrelated pre-existing crypto/Buffer type errors in packages/trpc.
  • No changes to Electric's logical replication protocol itself; only how we match against it.
  • The legacy host-service/CLI workspace.delete path is not converted into a renderer-observed Electric wait. The desktop delete dialog path now uses workspaceCleanup.destroy with Electric confirmation.

Verification

bun --cwd apps/desktop typecheck
bun --cwd packages/host-service typecheck
bun --cwd packages/db typecheck
bun --cwd apps/electric-proxy typecheck
bun test packages/trpc/src/router/v2-project/v2-project.test.ts
bun test packages/trpc/src/router/task/task.test.ts
bun run lint:fix
bun run lint

Latest reviewer-driven follow-up validation also passed:

bun --cwd apps/desktop typecheck
bun --cwd packages/host-service typecheck
bun run lint:fix
bun run lint

Full bun --cwd packages/trpc typecheck has unrelated pre-existing crypto/Buffer type errors.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 16, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Remove renderer-side in-flight cloud-row caching/fallback and creation-status UI; backend create mutations now run in transactions, compute numeric txid, and return txid with created records. Collections typing updated; client creation flow writes local state and awaits txid when provided.

Changes

Workspace creation refactor: cloud-row to txid

Layer / File(s) Summary
Sidebar & UI cleanup
apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/**/*, apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/TopBar/components/V2WorkspaceTitle/V2WorkspaceTitle.tsx, apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/layout.tsx, apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/types.ts
Removed renderer-side in-flight-derived pending/fallback rows and creationStatus from sidebar workspace type; simplified sidebar item/icon/row components and removed creating/error UI and WorkspaceCreatesManager.
Renderer create flow & store refactor
apps/desktop/src/renderer/stores/workspace-creates/*, apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/**/*, apps/desktop/src/renderer/routes/_authenticated/_dashboard/tasks/*/OpenInWorkspaceV2.tsx
Narrowed useWorkspaceCreates API to { submit }; removed in-flight cloudRow state and manager; submit inserts into collections.v2Workspaces with WorkspaceCreateInsertMetadata, awaits persistence/txid when present, waits for local sync, and writes paneLayout into v2WorkspaceLocalState.
Collections onInsert & electric proxy sync
apps/desktop/src/renderer/routes/_authenticated/providers/CollectionsProvider/collections.ts, apps/electric-proxy/*
Introduced Electric-backed collection typing and workspace-create insert metadata; v2Workspaces.onInsert calls host-service workspaces.create, writes host result into metadata, optionally awaits txid via Electric utilities, and throws rollback sentinel on canonical ID mismatch; proxy derives protocol params from @electric-sql/client.
Backend transactions & txid propagation
packages/trpc/src/router/v2-workspace/v2-workspace.ts, packages/trpc/src/router/v2-project/v2-project.ts, packages/trpc/src/router/chat/chat.ts
Create mutations run inside dbWs.transaction, capture numeric txid via getCurrentTxid(tx), and return { ...record, txid } (or txid: null for idempotent/unchanged paths).
Tests & mocks adjusted for txid
packages/trpc/src/router/v2-project/v2-project.test.ts
Expanded transactional INSERT mocks, set numeric getCurrentTxid mock, and updated assertions/queued results to expect numeric txid.
Navigation/docs & small UI tweaks
apps/desktop/src/renderer/routes/_authenticated/components/DashboardNewWorkspaceModal/*, apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/components/WorkspaceNotFoundState/WorkspaceNotFoundState.tsx
Removed optimistic navigation to snapshot ids; submit now navigates after canonical id is returned; small inline docs and minor styling tweaks applied.

Sequence Diagram(s)

sequenceDiagram
  participant Renderer as Renderer (useWorkspaceCreates / UI)
  participant Collections as CollectionsProvider (v2Workspaces.onInsert)
  participant Host as HostService (workspaces.create)
  participant TRPC as trpc.v2Workspace.create
  participant DB as dbWs.transaction
  participant TxUtil as getCurrentTxid

  Renderer->>Collections: insert v2Workspace with WorkspaceCreateInsertMetadata
  Collections->>Host: call host-service workspaces.create with input
  Host-->>Collections: returns canonical workspace (id[, txid])
  Collections-->>Collections: write host result into insert metadata
  Collections->>Renderer: electric insert persists (metadata may include txid)
  Renderer->>TRPC: call create mutation
  TRPC->>DB: perform insert/update inside transaction
  DB->>TxUtil: compute current txid
  TxUtil-->>TRPC: txid
  TRPC-->>Renderer: return { ...workspace, txid }
  Renderer->>Collections: await collection utils for txid (when needed)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Poem

A rabbit hops through transactions so fleet,
Cloud rows slip away, and txids take the seat,
Inserts hum safe inside a stream,
The client waits, then follows the beam,
🐰✨ Canonical IDs snug and neat.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 12.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Fix Electric create sync txids' clearly summarizes the main technical change: fixing how transaction IDs are synced in Electric's create flows.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The pull request description is comprehensive and well-structured, covering all essential sections: Summary, Approach (with multiple subsections), Key Invariants, Non-goals, and Verification steps.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@capy-ai
Copy link
Copy Markdown

capy-ai Bot commented May 16, 2026

Capy auto-review is paused for this organization because the monthly auto-review limit has been reached. Increase the limit or turn it off in billing settings to resume automatic reviews.

@stage-review
Copy link
Copy Markdown

stage-review Bot commented May 16, 2026

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/desktop/src/renderer/stores/workspace-creates/useWorkspaceCreates.ts`:
- Around line 131-133: The code is prematurely removing the snapshot-keyed
optimistic entry in the alreadyExists && workspace.id !== workspaceId branch
which causes V2WorkspaceLayout to briefly render WorkspaceNotFoundState;
instead, change the handling inside the result.alreadyExists && workspace.id !==
workspaceId branch to either defer removal until after the caller performs the
redirect or retarget the optimistic entry to the canonical id before removing
the snapshot key (i.e., update the store entry for the snapshot key to point to
workspace.id or call a retarget/rename helper on useWorkspaceCreatesStore rather
than immediately calling
useWorkspaceCreatesStore.getState().remove(workspaceId)), ensuring the entry
remains available during the redirect so the inFlight/syncedWorkspace state
doesn’t vanish.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 952fdc87-ffb9-4499-bdcf-bbac0968633a

📥 Commits

Reviewing files that changed from the base of the PR and between 2b86c05 and c7d9339.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (14)
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/hooks/useDashboardSidebarData/useDashboardSidebarData.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/TopBar/components/V2WorkspaceTitle/V2WorkspaceTitle.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/layout.tsx
  • apps/desktop/src/renderer/routes/_authenticated/providers/CollectionsProvider/collections.ts
  • apps/desktop/src/renderer/stores/workspace-creates/store.ts
  • apps/desktop/src/renderer/stores/workspace-creates/useWorkspaceCreates.ts
  • apps/electric-proxy/package.json
  • apps/electric-proxy/src/electric.ts
  • packages/host-service/src/trpc/router/workspace-creation/shared/adopt-existing-worktree.ts
  • packages/host-service/src/trpc/router/workspaces/workspaces.ts
  • packages/trpc/src/router/chat/chat.ts
  • packages/trpc/src/router/v2-project/v2-project.test.ts
  • packages/trpc/src/router/v2-project/v2-project.ts
  • packages/trpc/src/router/v2-workspace/v2-workspace.ts
💤 Files with no reviewable changes (1)
  • apps/desktop/src/renderer/stores/workspace-creates/store.ts

Comment thread apps/desktop/src/renderer/stores/workspace-creates/useWorkspaceCreates.ts Outdated
Copy link
Copy Markdown
Contributor

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

Choose a reason for hiding this comment

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

1 issue found across 15 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="packages/trpc/src/router/v2-project/v2-project.test.ts">

<violation number="1" location="packages/trpc/src/router/v2-project/v2-project.test.ts:74">
P2: Transaction insert is mocked through the same return queue as the normal insert, so the create tests cannot detect if the implementation uses the wrong insert path.</violation>
</file>

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

Comment thread packages/trpc/src/router/v2-project/v2-project.test.ts Outdated
@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented May 16, 2026

Greptile Summary

This PR plumbs same-transaction txid values out of the workspace, project, and chat-session create mutations and uses them on the renderer side to awaitTxId before proceeding, replacing the previous "cloudRow sidecar" pattern.

  • Server layer (v2-workspace.ts, v2-project.ts, chat.ts): each create/upsert is wrapped in an explicit transaction; getCurrentTxid() is called inside and returned alongside the row.
  • Renderer layer (useWorkspaceCreates.ts, layout.tsx, sidebar): cloudRow storage and the cloudRowFallbackWorkspaces memo are deleted; dispatch now awaits awaitTxId to guarantee the workspace is in the Electric collection before the caller navigates.
  • Electric proxy (electric.ts): the hand-rolled PROTOCOL_PARAMS set is replaced with the library-canonical ELECTRIC_PROTOCOL_QUERY_PARAMS constant.

Confidence Score: 3/5

The workspace creation flow now blocks until Electric confirms the row, removing the cloudRow safety net — if Electric drops after the server write, the user is stuck with no escape path.

The awaitTxId call has no timeout: if Electric drops after the cloud mutation succeeds, dispatch hangs indefinitely. The test mock type mismatch (string vs number txid) means the typeof txid === 'number' guard is never exercised in tests, so regressions in the sync-wait path would not be caught.

useWorkspaceCreates.ts (missing timeout on awaitTxId) and v2-project.test.ts (mock returns string instead of number) need attention before merge.

Important Files Changed

Filename Overview
apps/desktop/src/renderer/stores/workspace-creates/useWorkspaceCreates.ts Replaces cloudRow fallback with awaitTxId — blocks dispatch indefinitely if Electric is unreachable after a successful server mutation.
packages/trpc/src/router/v2-project/v2-project.test.ts Adds tx-level insert mocks; getCurrentTxidMock returns a string but the real implementation returns a number, making txid type assertions misleading.
packages/trpc/src/router/v2-workspace/v2-workspace.ts Wraps workspace create/update in a transaction and returns same-transaction txid; covers all branches correctly.
packages/trpc/src/router/v2-project/v2-project.ts Moves project insert into a transaction to capture txid; returns { ...project, txid } — additive, non-breaking.
packages/trpc/src/router/chat/chat.ts Wraps chat session insert in a transaction; correctly returns txid: null on conflict.
apps/electric-proxy/src/electric.ts Replaces hand-maintained PROTOCOL_PARAMS set with library-provided ELECTRIC_PROTOCOL_QUERY_PARAMS constant.

Comments Outside Diff (1)

  1. packages/trpc/src/router/v2-project/v2-project.test.ts, line 280-281 (link)

    P1 getCurrentTxidMock returns a string "txid-123", but getCurrentTxid has return type Promise<number> (it calls Number.parseInt internally). The test assertions that check txid: "txid-123" therefore verify a string value that never appears in production — in production the txid will be an integer. The client guard typeof workspace.txid === "number" in useWorkspaceCreates.ts evaluates to false against the mock value, so tests never exercise the actual awaitTxId branch. Using a numeric mock value keeps the mock type-accurate and makes the guard testable.

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: packages/trpc/src/router/v2-project/v2-project.test.ts
    Line: 280-281
    
    Comment:
    `getCurrentTxidMock` returns a string `"txid-123"`, but `getCurrentTxid` has return type `Promise<number>` (it calls `Number.parseInt` internally). The test assertions that check `txid: "txid-123"` therefore verify a string value that never appears in production — in production the txid will be an integer. The client guard `typeof workspace.txid === "number"` in `useWorkspaceCreates.ts` evaluates to `false` against the mock value, so tests never exercise the actual `awaitTxId` branch. Using a numeric mock value keeps the mock type-accurate and makes the guard testable.
    
    
    
    How can I resolve this? If you propose a fix, please make it concise.
Prompt To Fix All With AI
Fix the following 2 code review issues. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 2
apps/desktop/src/renderer/stores/workspace-creates/useWorkspaceCreates.ts:79-81
**`awaitTxId` has no timeout or cancellation path**

`awaitTxId` blocks the entire `dispatch` call until Electric delivers the workspace row. If the Electric connection is lost or degraded after the server mutation succeeds, this promise can hang indefinitely, leaving the user stuck on the "creating" spinner with no escape. The `cloudRow` fallback that was removed specifically protected against this scenario — the server had confirmed the workspace, so the UI could proceed regardless of Electric's liveness. Consider wrapping `awaitTxId` with a `Promise.race` against a reasonable timeout so a slow-Electric situation degrades gracefully rather than silently stalling.

### Issue 2 of 2
packages/trpc/src/router/v2-project/v2-project.test.ts:280-281
`getCurrentTxidMock` returns a string `"txid-123"`, but `getCurrentTxid` has return type `Promise<number>` (it calls `Number.parseInt` internally). The test assertions that check `txid: "txid-123"` therefore verify a string value that never appears in production — in production the txid will be an integer. The client guard `typeof workspace.txid === "number"` in `useWorkspaceCreates.ts` evaluates to `false` against the mock value, so tests never exercise the actual `awaitTxId` branch. Using a numeric mock value keeps the mock type-accurate and makes the guard testable.

```suggestion
	getCurrentTxidMock.mockReset();
	getCurrentTxidMock.mockImplementation(async () => 123);
```

Reviews (1): Last reviewed commit: "fix electric create sync txids" | Re-trigger Greptile

Comment on lines +79 to +81
if (typeof workspace.txid === "number") {
await collections.v2Workspaces.utils.awaitTxId(workspace.txid);
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 awaitTxId has no timeout or cancellation path

awaitTxId blocks the entire dispatch call until Electric delivers the workspace row. If the Electric connection is lost or degraded after the server mutation succeeds, this promise can hang indefinitely, leaving the user stuck on the "creating" spinner with no escape. The cloudRow fallback that was removed specifically protected against this scenario — the server had confirmed the workspace, so the UI could proceed regardless of Electric's liveness. Consider wrapping awaitTxId with a Promise.race against a reasonable timeout so a slow-Electric situation degrades gracefully rather than silently stalling.

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/desktop/src/renderer/stores/workspace-creates/useWorkspaceCreates.ts
Line: 79-81

Comment:
**`awaitTxId` has no timeout or cancellation path**

`awaitTxId` blocks the entire `dispatch` call until Electric delivers the workspace row. If the Electric connection is lost or degraded after the server mutation succeeds, this promise can hang indefinitely, leaving the user stuck on the "creating" spinner with no escape. The `cloudRow` fallback that was removed specifically protected against this scenario — the server had confirmed the workspace, so the UI could proceed regardless of Electric's liveness. Consider wrapping `awaitTxId` with a `Promise.race` against a reasonable timeout so a slow-Electric situation degrades gracefully rather than silently stalling.

How can I resolve this? If you propose a fix, please make it concise.

@KyleAMathews KyleAMathews force-pushed the fix/electric-create-sync-txids branch from c7d9339 to ea7e08e Compare May 16, 2026 16:30
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
packages/trpc/src/router/v2-project/v2-project.test.ts (1)

749-749: 💤 Low value

Consider also asserting transactionMock.not.toHaveBeenCalled().

Since create mutations now run inside transactions, checking dbInsert.not.toHaveBeenCalled() confirms direct inserts didn't occur but doesn't verify that no transaction was started before the validation failure. Adding expect(transactionMock).not.toHaveBeenCalled() would strengthen the assertion that validation happens before any DB work begins.

Same applies to the similar assertion at line 762.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/trpc/src/router/v2-project/v2-project.test.ts` at line 749, Add
assertions to the failing-create tests to ensure no transaction was started by
asserting transactionMock.not.toHaveBeenCalled() in addition to the existing
expect(dbInsert).not.toHaveBeenCalled(); specifically, update the test cases
that currently assert dbInsert wasn't called (referenced as dbInsert) to also
assert transactionMock wasn't called (referenced as transactionMock) in both
places where this pattern appears so the tests confirm validation fails before
any transaction or DB work begins.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@packages/trpc/src/router/v2-project/v2-project.test.ts`:
- Line 749: Add assertions to the failing-create tests to ensure no transaction
was started by asserting transactionMock.not.toHaveBeenCalled() in addition to
the existing expect(dbInsert).not.toHaveBeenCalled(); specifically, update the
test cases that currently assert dbInsert wasn't called (referenced as dbInsert)
to also assert transactionMock wasn't called (referenced as transactionMock) in
both places where this pattern appears so the tests confirm validation fails
before any transaction or DB work begins.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 1a23750f-0eeb-4dc6-926c-8a64f752c2f1

📥 Commits

Reviewing files that changed from the base of the PR and between c7d9339 and ea7e08e.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (14)
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/hooks/useDashboardSidebarData/useDashboardSidebarData.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/TopBar/components/V2WorkspaceTitle/V2WorkspaceTitle.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/layout.tsx
  • apps/desktop/src/renderer/routes/_authenticated/providers/CollectionsProvider/collections.ts
  • apps/desktop/src/renderer/stores/workspace-creates/store.ts
  • apps/desktop/src/renderer/stores/workspace-creates/useWorkspaceCreates.ts
  • apps/electric-proxy/package.json
  • apps/electric-proxy/src/electric.ts
  • packages/host-service/src/trpc/router/workspace-creation/shared/adopt-existing-worktree.ts
  • packages/host-service/src/trpc/router/workspaces/workspaces.ts
  • packages/trpc/src/router/chat/chat.ts
  • packages/trpc/src/router/v2-project/v2-project.test.ts
  • packages/trpc/src/router/v2-project/v2-project.ts
  • packages/trpc/src/router/v2-workspace/v2-workspace.ts
💤 Files with no reviewable changes (1)
  • apps/desktop/src/renderer/stores/workspace-creates/store.ts
✅ Files skipped from review due to trivial changes (2)
  • packages/host-service/src/trpc/router/workspace-creation/shared/adopt-existing-worktree.ts
  • apps/electric-proxy/package.json
🚧 Files skipped from review as they are similar to previous changes (9)
  • apps/electric-proxy/src/electric.ts
  • packages/host-service/src/trpc/router/workspaces/workspaces.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/v2-workspace/layout.tsx
  • packages/trpc/src/router/chat/chat.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/TopBar/components/V2WorkspaceTitle/V2WorkspaceTitle.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/hooks/useDashboardSidebarData/useDashboardSidebarData.ts
  • apps/desktop/src/renderer/routes/_authenticated/providers/CollectionsProvider/collections.ts
  • packages/trpc/src/router/v2-workspace/v2-workspace.ts
  • packages/trpc/src/router/v2-project/v2-project.ts

@KyleAMathews KyleAMathews force-pushed the fix/electric-create-sync-txids branch from ea7e08e to 4ee5c9c Compare May 16, 2026 16:58
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.

1 participant