diff --git a/server/src/__tests__/smoke-lab.test.ts b/server/src/__tests__/smoke-lab.test.ts index 3a9eb4c2581..297f5843ad5 100644 --- a/server/src/__tests__/smoke-lab.test.ts +++ b/server/src/__tests__/smoke-lab.test.ts @@ -6,6 +6,7 @@ import { activityLog, agents, authUsers, + connectionGrants, companies, companyMemberships, createDb, @@ -354,10 +355,13 @@ describeEmbeddedPostgres("smoke lab service pack and results API", () => { const applications = await db.select().from(toolApplications).where(eq(toolApplications.companyId, company.id)); const connections = await db.select().from(toolConnections).where(eq(toolConnections.companyId, company.id)); + const grants = await db.select().from(connectionGrants).where(eq(connectionGrants.companyId, company.id)); const catalog = await db.select().from(toolCatalogEntries).where(eq(toolCatalogEntries.companyId, company.id)); const profiles = await db.select().from(toolProfiles).where(eq(toolProfiles.companyId, company.id)); expect(applications).toHaveLength(2); expect(connections).toHaveLength(2); + expect(grants).toHaveLength(2); + expect(grants.every((grant) => grant.kind === "organization" && grant.isDefault)).toBe(true); expect(catalog.some((entry) => entry.toolName === "todo.add" && entry.riskLevel === "write")).toBe(true); expect(catalog.some((entry) => entry.toolName === "time.now" && entry.riskLevel === "read")).toBe(true); expect(profiles).toHaveLength(1); diff --git a/server/src/services/smoke-lab.ts b/server/src/services/smoke-lab.ts index 5c308ce2618..931021f54dc 100644 --- a/server/src/services/smoke-lab.ts +++ b/server/src/services/smoke-lab.ts @@ -7,6 +7,7 @@ import { fileURLToPath } from "node:url"; import { and, desc, eq, inArray } from "drizzle-orm"; import type { Db } from "@paperclipai/db"; import { + connectionGrants, smokeRuns, smokeRunSteps, toolApplications, @@ -741,8 +742,28 @@ export function smokeLabService(db: Db, options: { lastHealthAt: now, updatedAt: now, }; + const ensureDefaultOrganizationGrant = async (connectionId: string) => { + const [existingGrant] = await db.select({ id: connectionGrants.id }).from(connectionGrants).where(and( + eq(connectionGrants.companyId, input.companyId), + eq(connectionGrants.connectionId, connectionId), + eq(connectionGrants.kind, "organization"), + eq(connectionGrants.isDefault, true), + )); + if (existingGrant) return; + await db.insert(connectionGrants).values({ + companyId: input.companyId, + connectionId, + kind: "organization", + status: "active", + isDefault: true, + credentialSecretRefs: [], + createdAt: now, + updatedAt: now, + }); + }; if (existing) { const [updated] = await db.update(toolConnections).set(values).where(eq(toolConnections.id, existing.id)).returning(); + await ensureDefaultOrganizationGrant(existing.id); return { row: updated ?? existing, created: false }; } const [created] = await db.insert(toolConnections).values({ @@ -754,6 +775,7 @@ export function smokeLabService(db: Db, options: { createdByUserId: input.actor?.actorType === "user" ? input.actor.actorId : null, createdAt: now, }).returning(); + await ensureDefaultOrganizationGrant(created.id); return { row: created, created: true }; }