A workspace's task now carries the bot that has it there (bot_id with workspace_id), or none while it's shared. A bot reaches its own list and, in its workspaces, its own tasks plus the shared ones; a workspace admin every task there. Bots create workspace tasks for themselves by default, take a shared one by starting it, and hand-overs record the new bot. Removing or deleting a bot makes its workspace tasks shared again. The conversation's Tasks modal shows that bot's tasks in the workspace. Co-Authored-By: Claude Opus 5.5 <[email protected]>
28 lines
948 B
TypeScript
28 lines
948 B
TypeScript
import BunSQLite from "@moduletrace/bun-sqlite";
|
|
import AppError from "@/src/utils/app-error";
|
|
|
|
type Params = {
|
|
bot_id: number | string;
|
|
workspace_id: number | string;
|
|
};
|
|
|
|
/**
|
|
* A workspace's task can only be had by a bot working there: a member
|
|
* (`workspace_bots`) or the coordinator, which is in every workspace.
|
|
*/
|
|
export default async function assertBotWorksThere({ bot_id, workspace_id }: Params) {
|
|
const res = await BunSQLite.sql<{ id: number }>({
|
|
sql: `SELECT b.id FROM bots b
|
|
WHERE b.id = ? AND (
|
|
b.kind = 'coordinator'
|
|
OR EXISTS (SELECT 1 FROM workspace_bots wb WHERE wb.bot_id = b.id AND wb.workspace_id = ?)
|
|
)
|
|
LIMIT 1`,
|
|
values: [Number(bot_id), Number(workspace_id)],
|
|
});
|
|
|
|
if (!res.payload?.[0]?.id) {
|
|
throw new AppError(`Bot ${bot_id} doesn't work in workspace ${workspace_id}, so it can't have a task there.`);
|
|
}
|
|
}
|