Make managed resource binding upsert atomic

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
DottaandPaperclip committed 2026-07-09 20:50:34 +00:00
1 parent ed39a0c504
commit c47806d6cc
2 files changed
+53 -19

No files matched your search

@@ -509,6 +509,44 @@ describeEmbeddedPostgres("built-in agents", () => {
expect(coachGrantKeys).not.toContain("skills:create");
});
it("recreates missing managed resource bindings idempotently during concurrent reconcile", async () => {
const companyId = await seedCompany({ requireApproval: false });
await agentService(db).create(companyId, {
name: "CEO",
role: "ceo",
status: "idle",
adapterType: "codex_local",
adapterConfig: { model: "gpt-5.4" },
runtimeConfig: {},
permissions: {},
});
const builtIns = builtInAgentService(db);
await builtIns.ensure(companyId, "reflection-coach");
await db.delete(builtInManagedResources).where(eq(builtInManagedResources.companyId, companyId));
const states = await Promise.all([
builtIns.ensure(companyId, "reflection-coach"),
builtIns.ensure(companyId, "reflection-coach"),
]);
expect(states).toHaveLength(2);
for (const state of states) {
expect(state.resources.map((resource) => [resource.resourceKind, resource.stockStatus])).toEqual([
["instructions", "stock_current"],
["skill", "stock_current"],
["routine", "stock_current"],
]);
}
const bindings = await db
.select()
.from(builtInManagedResources)
.where(eq(builtInManagedResources.companyId, companyId));
expect(bindings).toHaveLength(3);
expect(new Set(bindings.map((binding) =>
`${binding.bundleKey}:${binding.resourceKind}:${binding.resourceKey}`
)).size).toBe(3);
});
it("preserves new-agent approval gates during automatic Reflection Coach provisioning", async () => {
const companyId = await seedCompany({ requireApproval: true });
const mutationPolicy = {
+15 -19
View File
@@ -662,29 +662,25 @@ export function builtInAgentService(db: Db) {
stockHash: string;
defaultsJson: Record<string, unknown>;
}) {
const existing = await getManagedResourceBinding(
input.companyId,
input.bundleKey,
input.resourceKind,
input.resourceKey,
);
if (existing) {
return db
.update(builtInManagedResources)
.set({
const now = new Date();
return db
.insert(builtInManagedResources)
.values(input)
.onConflictDoUpdate({
target: [
builtInManagedResources.companyId,
builtInManagedResources.bundleKey,
builtInManagedResources.resourceKind,
builtInManagedResources.resourceKey,
],
set: {
resourceId: input.resourceId,
stockVersion: input.stockVersion,
stockHash: input.stockHash,
defaultsJson: input.defaultsJson,
updatedAt: new Date(),
})
.where(eq(builtInManagedResources.id, existing.id))
.returning()
.then((rows) => rows[0] ?? null);
}
return db
.insert(builtInManagedResources)
.values(input)
updatedAt: now,
},
})
.returning()
.then((rows) => rows[0] ?? null);
}