Fresh history cut from cynarAI/evoo antigravity-handoff/project-timeline (Voice First + project timeline). Brand docs/titles as evOo; keep @rakazo/* packages as tech debt. Excludes node_modules, caches, secrets, voice blobs.
65 lines
2.0 KiB
TypeScript
65 lines
2.0 KiB
TypeScript
import { appendEventInTransaction, type Prisma, type PrismaClient } from "@rakazo/db";
|
|
import { getLogger } from "@rakazo/logging";
|
|
|
|
type AppendEvent = typeof appendEventInTransaction;
|
|
|
|
/**
|
|
* Persist a bot row. When profile labels change, write `bot.updated` in the same
|
|
* transaction so clients never observe a successful rename without a durable event.
|
|
* Realtime notify stays best-effort after commit.
|
|
*/
|
|
export async function commitBotUpdate(
|
|
options: {
|
|
prisma: PrismaClient;
|
|
notify: (threadId: string, seq: number) => Promise<void>;
|
|
spaceId: string;
|
|
threadId: string;
|
|
botId: string;
|
|
data: Prisma.BotUncheckedUpdateInput;
|
|
emitBotUpdated: boolean;
|
|
},
|
|
appendEvent: AppendEvent = appendEventInTransaction,
|
|
): Promise<{ id: string; name: string; title: string; description: string }> {
|
|
if (!options.emitBotUpdated) {
|
|
return options.prisma.bot.update({
|
|
where: { id: options.botId },
|
|
data: options.data,
|
|
select: { id: true, name: true, title: true, description: true },
|
|
});
|
|
}
|
|
|
|
const committed = await options.prisma.$transaction(async (tx) => {
|
|
const updated = await tx.bot.update({
|
|
where: { id: options.botId },
|
|
data: options.data,
|
|
select: { id: true, name: true, title: true, description: true },
|
|
});
|
|
const event = await appendEvent(tx, {
|
|
spaceId: options.spaceId,
|
|
threadId: options.threadId,
|
|
botId: options.botId,
|
|
type: "bot.updated",
|
|
payload: {
|
|
botId: updated.id,
|
|
name: updated.name,
|
|
title: updated.title,
|
|
description: updated.description,
|
|
},
|
|
});
|
|
return { updated, seq: event.seq };
|
|
});
|
|
|
|
await options.notify(options.threadId, committed.seq).catch((error) => {
|
|
getLogger().error("bot.updated realtime notification", error);
|
|
});
|
|
return committed.updated;
|
|
}
|
|
|
|
export function botProfileLabelsChanged(input: {
|
|
name?: unknown;
|
|
title?: unknown;
|
|
description?: unknown;
|
|
}): boolean {
|
|
return input.name !== undefined || input.title !== undefined || input.description !== undefined;
|
|
}
|