Skip to content

Commit 204e5f1

Browse files
committed
fix(projects): keep repair reads compatible with expansion schema
1 parent 0a199ba commit 204e5f1

4 files changed

Lines changed: 17 additions & 4 deletions

File tree

‎apps/sim/app/api/webhooks/agentmail/thread-scope.integration.ts‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { deleteWorkspaceFixture, insertWorkspaceFixture } from '@sim/db/testing/workspace-fixtures'
12
/**
23
* An inbox reply continues its parent task's chat, and the parent is found by the
34
* `In-Reply-To` header — a value every recipient of the agent's reply holds. Against
@@ -97,7 +98,7 @@ async function seedWorkspace(ws: InboxWorkspace): Promise<void> {
9798
createdAt: now,
9899
updatedAt: now,
99100
})
100-
await db.insert(workspace).values({
101+
await insertWorkspaceFixture(db, {
101102
id: ws.id,
102103
name: 'Inbox thread scope fixture',
103104
ownerId: ws.ownerId,
@@ -224,7 +225,7 @@ describe('inbox reply threading stays inside the receiving workspace', () => {
224225
afterAll(async () => {
225226
const ownerIds = [victim.ownerId, attacker.ownerId]
226227
await db.delete(permissions).where(inArray(permissions.userId, ownerIds))
227-
await db.delete(workspace).where(inArray(workspace.id, [victim.id, attacker.id]))
228+
await deleteWorkspaceFixture(db, inArray(workspace.id, [victim.id, attacker.id]))
228229
await db.delete(user).where(inArray(user.id, ownerIds))
229230
})
230231

‎apps/sim/lib/projects/membership.ts‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,14 @@ export async function lockWorkspaceProject(tx: DbTransaction, workspaceId: strin
143143
throw new ProjectConflictError('Project membership needs reconciliation')
144144
await acquireAdvisoryXactLock(tx, 'project', projectLockKey(membership.projectId))
145145
const [current] = await tx
146-
.select({ project })
146+
.select({
147+
project: {
148+
id: project.id,
149+
ownerId: project.ownerId,
150+
organizationId: project.organizationId,
151+
archivedAt: project.archivedAt,
152+
},
153+
})
147154
.from(workspace)
148155
.innerJoin(project, eq(project.id, workspace.projectId))
149156
.where(eq(workspace.id, workspaceId))

‎packages/db/maintenance/project-membership.sql‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
-- Installed by the registered Project migration after bounded backfill and verification.
22
COMMIT;
33
--> statement-breakpoint
4+
-- Validation scans and concurrent index builds have a separate 60-second budget.
45
SET statement_timeout = '60s';
56
--> statement-breakpoint
67
DO $$ BEGIN
@@ -115,6 +116,8 @@ ALTER TABLE workspace ADD COLUMN IF NOT EXISTS organization_scope_key text
115116
GENERATED ALWAYS AS (CASE WHEN organization_id IS NULL THEN 'personal' ELSE 'organization:' || organization_id END) STORED;
116117
COMMIT;
117118
--> statement-breakpoint
119+
SET statement_timeout = '5s';
120+
--> statement-breakpoint
118121
-- Only invalid, unreferenced indexes from interrupted builds are removed. Valid indexes survive
119122
-- replay, including when the final foreign keys already depend on them.
120123
DO $$ DECLARE target_name text; BEGIN
@@ -134,6 +137,7 @@ CREATE UNIQUE INDEX CONCURRENTLY IF NOT EXISTS project_id_organization_scope_uni
134137
CREATE UNIQUE INDEX CONCURRENTLY IF NOT EXISTS workspace_id_project_unique ON workspace(id, project_id);
135138
--> statement-breakpoint
136139
SET lock_timeout = '1s';
140+
SET statement_timeout = '5s';
137141
--> statement-breakpoint
138142
DO $$ BEGIN
139143
IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conrelid = 'project'::regclass

‎packages/db/scripts/project-contract.integration.ts‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1313,7 +1313,8 @@ describe('Project expand/backfill/contract against PostgreSQL', () => {
13131313
if (statement.includes('LOCK TABLE workspace,')) {
13141314
const before = await locks();
13151315
await sleep(6500);
1316-
process.stdout.write(JSON.stringify({ before, after: await locks() }));
1316+
const result = JSON.stringify({ before, after: await locks() });
1317+
await new Promise((resolve, reject) => process.stdout.write(result, (error) => error ? reject(error) : resolve()));
13171318
process.exit(0);
13181319
}
13191320
}

0 commit comments

Comments
 (0)