evOo-local/packages/adapters/src/create-project.ts
cynarAI 6c7eed7580 Initial clean evOo-local from f00577b
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.
2026-09-20 17:15:16 +02:00

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;
}
}