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.
44 lines
1.3 KiB
TypeScript
44 lines
1.3 KiB
TypeScript
import type { Actor } from "@rakazo/contracts";
|
|
import { GROUP_MEMBER_MAX, GROUP_MEMBER_MIN } from "@rakazo/contracts";
|
|
import { createGroupRepos, IsolationError, type PrismaClient } from "@rakazo/db";
|
|
|
|
export async function createProject(
|
|
deps: { prisma: PrismaClient },
|
|
input: {
|
|
actor: Actor;
|
|
createdByBotId: string;
|
|
name: string;
|
|
botIds?: string[];
|
|
},
|
|
) {
|
|
const name = input.name.trim();
|
|
if (!name) return { error: "Project name is required." };
|
|
|
|
const botIds = [...new Set([input.createdByBotId, ...(input.botIds ?? [])])];
|
|
if (botIds.length < GROUP_MEMBER_MIN) {
|
|
return {
|
|
error: `At least ${GROUP_MEMBER_MIN} agents are required. Include bot_id values for other teammates.`,
|
|
};
|
|
}
|
|
if (botIds.length > GROUP_MEMBER_MAX) {
|
|
return { error: `At most ${GROUP_MEMBER_MAX} agents are allowed in one project.` };
|
|
}
|
|
|
|
const groupRepos = createGroupRepos(deps.prisma);
|
|
try {
|
|
const group = await groupRepos.createGroup(input.actor, { name, botIds });
|
|
return {
|
|
ok: true as const,
|
|
groupId: group.id,
|
|
name: group.name,
|
|
threadId: group.threadId,
|
|
memberCount: group.members.length,
|
|
};
|
|
} catch (error) {
|
|
if (error instanceof IsolationError) {
|
|
return { error: "One or more agents could not be added to the project." };
|
|
}
|
|
throw error;
|
|
}
|
|
}
|