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]>
35 lines
1.3 KiB
TypeScript
35 lines
1.3 KiB
TypeScript
import BunSQLite from "@moduletrace/bun-sqlite";
|
|
import type { BUN_SQLITE_COBBLE_TASK_MEDIA } from "@/db/types/db";
|
|
|
|
type Params = {
|
|
/**
|
|
* A bot's own list (not what it has in workspaces), or a workspace's.
|
|
*/
|
|
bot_id?: number | string | null;
|
|
workspace_id?: number | string | null;
|
|
};
|
|
|
|
/**
|
|
* The bytes a bot's or workspace's tasks filed that no folder owns (a chat
|
|
* upload linked to a task). Read before the bot or workspace is deleted:
|
|
* the tasks and their links cascade, and nothing else would ever clean
|
|
* those files up. A bot file is left alone: its folder is its home.
|
|
*/
|
|
export async function grabTaskMediaIds({ bot_id, workspace_id }: Params): Promise<number[]> {
|
|
const column = workspace_id ? "workspace_id" : "bot_id";
|
|
const owner = workspace_id || bot_id;
|
|
|
|
if (!owner) return [];
|
|
|
|
const links = (
|
|
await BunSQLite.sql<BUN_SQLITE_COBBLE_TASK_MEDIA>({
|
|
sql: `SELECT tm.media_id FROM task_media tm
|
|
JOIN tasks t ON t.id = tm.task_id
|
|
WHERE t.${column} = ? ${workspace_id ? "" : "AND t.workspace_id IS NULL"} AND tm.bot_file_id IS NULL`,
|
|
values: [Number(owner)],
|
|
})
|
|
).payload || [];
|
|
|
|
return links.map((link) => Number(link.media_id)).filter(Boolean);
|
|
}
|