Skip to content

Commit 9f343b6

Browse files
Copilottikazyq
andcommitted
Update spec 14 status to complete with implementation summary
Co-authored-by: tikazyq <[email protected]>
1 parent 57b6a7b commit 9f343b6

File tree

1 file changed

+70
-7
lines changed
  • specs/014-workspace-upsert-backfill-bug

1 file changed

+70
-7
lines changed

specs/014-workspace-upsert-backfill-bug/README.md

Lines changed: 70 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
status: planned
2+
status: complete
33
created: '2025-11-11'
44
tags:
55
- bug
@@ -8,11 +8,12 @@ tags:
88
- database
99
priority: high
1010
created_at: '2025-11-11T15:06:38.494Z'
11+
completed_at: '2025-11-11T15:20:00.000Z'
1112
---
1213

1314
# Fix Workspace Upsert Bug Blocking Backfill
1415

15-
> **Status**: 📅 Planned · **Priority**: High · **Created**: 2025-11-11
16+
> **Status**: ✅ Complete · **Priority**: High · **Created**: 2025-11-11
1617
1718
## Overview
1819

@@ -135,9 +136,71 @@ Failed to send batch (attempt 1/4): unexpected status 500:
135136
"Unique constraint failed on the fields: (`workspace_id`)"
136137
```
137138

138-
### Next Steps
139+
## Implementation Summary (2025-11-11)
139140

140-
1. Find the batch insert API endpoint code
141-
2. Examine the Prisma upsert query
142-
3. Fix the upsert logic
143-
4. Re-test backfill
141+
### Changes Made
142+
143+
**File: `/packages/web/app/api/events/batch/route.ts`**
144+
145+
Fixed the workspace upsert logic to use the correct unique constraint:
146+
147+
**Before:**
148+
149+
```typescript
150+
await prisma.workspace.upsert({
151+
where: {
152+
projectId_machineId_workspaceId: {
153+
projectId: workspaceData.projectId,
154+
machineId: workspaceData.machineDbId,
155+
workspaceId: workspaceData.workspaceId,
156+
},
157+
},
158+
create: {
159+
/* ... */
160+
},
161+
update: {},
162+
});
163+
```
164+
165+
**After:**
166+
167+
```typescript
168+
await prisma.workspace.upsert({
169+
where: {
170+
workspaceId: workspaceData.workspaceId,
171+
},
172+
create: {
173+
/* ... */
174+
},
175+
update: {
176+
workspacePath: workspaceData.workspacePath,
177+
lastSeenAt: new Date(),
178+
},
179+
});
180+
```
181+
182+
### Why This Fix Works
183+
184+
1. **Correct Unique Constraint**: The Prisma schema has `@unique` on `workspaceId` field, which creates a single-column unique constraint. The composite constraint `@@unique([projectId, machineId, workspaceId])` is secondary.
185+
186+
2. **Proper Update**: When a workspace already exists, we now update the `workspacePath` and `lastSeenAt` fields instead of leaving the update empty.
187+
188+
3. **Idempotent**: The fix makes the endpoint idempotent - multiple batches with the same workspace will succeed, with the workspace being updated on subsequent calls.
189+
190+
### Testing
191+
192+
- Added integration test case `should handle batch events with existing workspace (upsert)` in `hierarchy-api.test.ts`
193+
- Test verifies that:
194+
- First batch creates workspace successfully
195+
- Second batch with same workspaceId but updated path succeeds
196+
- Workspace is updated with new path
197+
- Build passes successfully
198+
- CodeQL security check shows no vulnerabilities
199+
200+
### Impact
201+
202+
This fix unblocks:
203+
204+
- Backfill feature for importing historical Copilot chat sessions
205+
- Batch event processing when workspaces already exist
206+
- Collector auto-creation of workspaces during event ingestion

0 commit comments

Comments
 (0)