mirror of
https://github.com/Mintplex-Labs/vector-admin.git
synced 2026-08-27 02:21:18 -04:00
43a04d29df
resolves #21
212 lines
5.8 KiB
JavaScript
212 lines
5.8 KiB
JavaScript
const prisma = require("../utils/prisma");
|
|
const uuidAPIKey = require("uuid-apikey");
|
|
const slugify = require("slugify");
|
|
const { WorkspaceDocument } = require("./workspaceDocument");
|
|
const { selectConnector } = require("../utils/vectordatabases/providers");
|
|
|
|
const OrganizationWorkspace = {
|
|
makeKey: () => {
|
|
return `ws-${uuidAPIKey.create().apiKey}`;
|
|
},
|
|
// Will check the relevant connector to make sure the slug and namespace/collection map
|
|
safeCreate: async function (
|
|
workspaceName = "",
|
|
organizationId = 0,
|
|
dbConnectorRecord
|
|
) {
|
|
try {
|
|
if (!workspaceName)
|
|
return { workspace: null, message: "No Workspace name provided." };
|
|
const connector = selectConnector(dbConnectorRecord);
|
|
|
|
var slug = slugify(workspaceName, { lower: true });
|
|
const existingDbBySlug = await this.get({ slug });
|
|
const existingConnectorNamespace = await connector.namespace(slug);
|
|
|
|
// If there was a name collision in the DB or the vectorstore collection - make a unique slug.
|
|
// as the namespace/collection will always be the slug.
|
|
if (!!existingDbBySlug || !!existingConnectorNamespace) {
|
|
const slugSeed = Math.floor(10000000 + Math.random() * 90000000);
|
|
slug = slugify(`${workspaceName}-${slugSeed}`, { lower: true });
|
|
}
|
|
|
|
const workspace = await prisma.organization_workspaces.create({
|
|
data: {
|
|
name: workspaceName,
|
|
slug,
|
|
fname: slug,
|
|
uuid: this.makeKey(),
|
|
organization_id: Number(organizationId),
|
|
},
|
|
});
|
|
|
|
if (!workspace) {
|
|
await db.close();
|
|
console.error("FAILED TO CREATE WORKSPACE.");
|
|
return { workspace: null, message: "Could not create workspace" };
|
|
}
|
|
|
|
return { workspace, message: null };
|
|
} catch (e) {
|
|
console.error(e.message);
|
|
return null;
|
|
}
|
|
},
|
|
|
|
create: async function (
|
|
workspaceName = "",
|
|
organizationId = 0,
|
|
presetFName = null
|
|
) {
|
|
try {
|
|
if (!workspaceName)
|
|
return { workspace: null, message: "No Workspace name provided." };
|
|
var slug = slugify(workspaceName, { lower: true });
|
|
|
|
const existingBySlug = await this.get({ slug });
|
|
if (!!existingBySlug) {
|
|
const slugSeed = Math.floor(10000000 + Math.random() * 90000000);
|
|
slug = slugify(`${workspaceName}-${slugSeed}`, { lower: true });
|
|
}
|
|
|
|
const workspace = await prisma.organization_workspaces.create({
|
|
data: {
|
|
name: workspaceName,
|
|
slug,
|
|
fname: presetFName ?? workspaceName,
|
|
uuid: this.makeKey(),
|
|
organization_id: Number(organizationId),
|
|
},
|
|
});
|
|
|
|
if (!workspace) {
|
|
await db.close();
|
|
console.error("FAILED TO CREATE WORKSPACE.");
|
|
return { workspace: null, message: "Could not create workspace" };
|
|
}
|
|
|
|
return { workspace, message: null };
|
|
} catch (e) {
|
|
console.error(e.message);
|
|
return null;
|
|
}
|
|
},
|
|
|
|
get: async function (clause = {}) {
|
|
try {
|
|
const workspace = await prisma.organization_workspaces.findFirst({
|
|
where: clause,
|
|
});
|
|
return workspace ? { ...workspace } : null;
|
|
} catch (e) {
|
|
console.error(e.message);
|
|
return null;
|
|
}
|
|
},
|
|
|
|
forOrganization: async function (
|
|
organizationId,
|
|
page = 1,
|
|
pageSize = 10,
|
|
includeSlugs = [],
|
|
searchTerm = ""
|
|
) {
|
|
try {
|
|
const offset = (page - 1) * pageSize;
|
|
const orgWorkspaces = [
|
|
...(includeSlugs?.length > 0
|
|
? await this.where({
|
|
organization_id: Number(organizationId),
|
|
...(includeSlugs.length > 0
|
|
? { slug: { in: includeSlugs } }
|
|
: {}),
|
|
})
|
|
: []),
|
|
...(await this.likeWhere(organizationId, searchTerm, pageSize, offset)),
|
|
];
|
|
|
|
const slugs = new Set();
|
|
const workspaces = [];
|
|
for (const workspace of orgWorkspaces) {
|
|
if (slugs.has(workspace.slug)) continue;
|
|
workspaces.push({
|
|
...workspace,
|
|
documentCount: await WorkspaceDocument.count({
|
|
workspace_id: Number(workspace.id),
|
|
}),
|
|
});
|
|
slugs.add(workspace.slug);
|
|
}
|
|
|
|
return workspaces;
|
|
} catch (e) {
|
|
console.error(e.message);
|
|
return [];
|
|
}
|
|
},
|
|
|
|
bySlugAndOrg: async function (wsSlug, organizationId = null) {
|
|
return await this.get({
|
|
slug: wsSlug,
|
|
organization_id: Number(organizationId),
|
|
});
|
|
},
|
|
|
|
where: async function (
|
|
clause = {},
|
|
limit = null,
|
|
offset = null,
|
|
orderBy = null
|
|
) {
|
|
try {
|
|
const workspaces = await prisma.organization_workspaces.findMany({
|
|
where: clause,
|
|
...(limit !== null ? { take: limit } : {}),
|
|
...(offset !== null ? { skip: offset } : {}),
|
|
...(orderBy !== null ? { orderBy } : {}),
|
|
});
|
|
return workspaces;
|
|
} catch (e) {
|
|
console.error(e.message);
|
|
return 0;
|
|
}
|
|
},
|
|
|
|
// We have to break this out separately so Prisma can find it as it does not
|
|
// support % searching.
|
|
likeWhere: async function (
|
|
organization_id = 0,
|
|
searchTerm = "",
|
|
limit = 1,
|
|
offset = 0
|
|
) {
|
|
return await prisma.$queryRaw`SELECT * FROM organization_workspaces WHERE organization_id = ${organization_id} AND name LIKE ${
|
|
"%" + searchTerm + "%"
|
|
} LIMIT ${limit} OFFSET ${offset}`;
|
|
},
|
|
|
|
count: async function (clause = {}) {
|
|
try {
|
|
const count = await prisma.organization_workspaces.count({
|
|
where: clause,
|
|
});
|
|
return count;
|
|
} catch (e) {
|
|
console.error(e.message);
|
|
return 0;
|
|
}
|
|
},
|
|
|
|
delete: async function (clause = {}) {
|
|
try {
|
|
await prisma.organization_workspaces.deleteMany({ where: clause });
|
|
return true;
|
|
} catch (e) {
|
|
console.error(e.message);
|
|
return false;
|
|
}
|
|
},
|
|
};
|
|
|
|
module.exports.OrganizationWorkspace = OrganizationWorkspace;
|