Share one crew across the install, keep user memory per user
Bots, workspaces and computers now belong to the install. Users reach workers only through bot_users (assigned by a super admin or admin) and workspace_users; the coordinator and main computer are one per install, and only the super admin sees the coordinator. Conversations are per user (bot_sessions.user_id), jobs run for the session's user, and live updates go only to who should see them. A bot's core memory is now general knowledge shared by every user it works for; what it learns about a user lives in bot_user_memories. One-off scripts move existing installs over: move-bot-memory-to-owners (run first), then share-crew. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
@@ -1,7 +1,5 @@
|
||||
import BunSQLite from "@moduletrace/bun-sqlite";
|
||||
import type { BUN_SQLITE_COBBLE_CONTAINERS } from "@/db/types/db";
|
||||
import deleteMedia from "@/src/functions/backend/db/media/delete-media";
|
||||
import removeDockerContainer from "@/src/functions/backend/docker/remove-docker-container";
|
||||
import AppError from "@/src/utils/app-error";
|
||||
import type { BUN_SQLITE_COBBLE_USER_TYPES } from "@/db/types/db";
|
||||
import parseUserTypes from "@/src/utils/parse-user-types";
|
||||
@@ -21,11 +19,12 @@ type Params = {
|
||||
};
|
||||
|
||||
/**
|
||||
* Deletes a user with everything that's theirs (bots, workspaces,
|
||||
* conversations, computers, user types, password, media and its files):
|
||||
* their computers' containers are removed first, their home directories
|
||||
* stay on disk. Their audit log entries stay too. The super admin can't be
|
||||
* deleted, and nobody deletes themselves.
|
||||
* Deletes a user with everything that's theirs (their conversations,
|
||||
* routines, access, what bots remember about them, user types, password,
|
||||
* media and its files). Bots, workspaces and computers belong to the
|
||||
* install and stay, pictures they uploaded for them too. Their audit log
|
||||
* entries stay as well. The super admin can't be deleted, and nobody
|
||||
* deletes themselves.
|
||||
*/
|
||||
export default async function deleteUser({ actor_user_id, actor_user_types, user_id }: Params) {
|
||||
if (String(actor_user_id) == String(user_id)) {
|
||||
@@ -48,24 +47,12 @@ export default async function deleteUser({ actor_user_id, actor_user_types, user
|
||||
throw new AppError(`You can't delete ${user.first_name || "this user"}.`);
|
||||
}
|
||||
|
||||
const containers =
|
||||
(
|
||||
await BunSQLite.sql<BUN_SQLITE_COBBLE_CONTAINERS>({
|
||||
sql: `SELECT co.* FROM containers co JOIN computers c ON c.container_id = co.id WHERE c.user_id = ?`,
|
||||
values: [user.id],
|
||||
})
|
||||
).payload || [];
|
||||
|
||||
for (const container of containers) {
|
||||
if (container.docker_id || container.name) {
|
||||
await removeDockerContainer({ container: container.docker_id || container.name! });
|
||||
}
|
||||
}
|
||||
|
||||
const media_ids =
|
||||
(
|
||||
await BunSQLite.sql<{ id: number }>({
|
||||
sql: `SELECT id FROM media WHERE user_id = ?`,
|
||||
sql: `SELECT id FROM media WHERE user_id = ?
|
||||
AND id NOT IN (SELECT image_media_id FROM bots WHERE image_media_id IS NOT NULL)
|
||||
AND id NOT IN (SELECT image_media_id FROM workspaces WHERE image_media_id IS NOT NULL)`,
|
||||
values: [user.id],
|
||||
})
|
||||
).payload?.map((media) => media.id) || [];
|
||||
@@ -87,12 +74,5 @@ export default async function deleteUser({ actor_user_id, actor_user_types, user
|
||||
await BunSQLite.sql({ sql: `DELETE FROM ${table} WHERE user_id = ?`, values: [user.id] });
|
||||
}
|
||||
|
||||
if (containers.length) {
|
||||
await BunSQLite.sql({
|
||||
sql: `DELETE FROM containers WHERE id IN (${containers.map(() => "?").join(", ")})`,
|
||||
values: containers.map((container) => container.id!),
|
||||
});
|
||||
}
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
@@ -29,6 +29,8 @@ export default async function grabUsers(
|
||||
sql += `SELECT\n`;
|
||||
sql += ` u.*,\n`;
|
||||
sql += ` ut_agg.user_types,\n`;
|
||||
sql += ` (SELECT GROUP_CONCAT(bot_id) FROM bot_users WHERE user_id = u.id) AS bot_ids,\n`;
|
||||
sql += ` (SELECT GROUP_CONCAT(workspace_id) FROM workspace_users WHERE user_id = u.id) AS workspace_ids,\n`;
|
||||
/**
|
||||
* Their profile photo only: other primary media (a bot's picture)
|
||||
* must not stand in for it.
|
||||
|
||||
Reference in New Issue
Block a user