252 lines
5.7 KiB
TypeScript
252 lines
5.7 KiB
TypeScript
import { and, eq, inArray, isNull } from "drizzle-orm";
|
|
|
|
import type { dbClient } from "@kan/db/client";
|
|
import { boards, workspaceMembers, workspaces } from "@kan/db/schema";
|
|
import { generateUID } from "@kan/shared/utils";
|
|
|
|
export const create = async (
|
|
db: dbClient,
|
|
workspaceInput: {
|
|
publicId?: string;
|
|
name: string;
|
|
slug: string;
|
|
createdBy: string;
|
|
createdByEmail: string;
|
|
},
|
|
) => {
|
|
const [workspace] = await db
|
|
.insert(workspaces)
|
|
.values({
|
|
publicId: workspaceInput.publicId ?? generateUID(),
|
|
name: workspaceInput.name,
|
|
slug: workspaceInput.slug,
|
|
createdBy: workspaceInput.createdBy,
|
|
})
|
|
.returning({
|
|
id: workspaces.id,
|
|
publicId: workspaces.publicId,
|
|
name: workspaces.name,
|
|
slug: workspaces.slug,
|
|
description: workspaces.description,
|
|
plan: workspaces.plan,
|
|
});
|
|
|
|
if (workspace) {
|
|
await db.insert(workspaceMembers).values({
|
|
publicId: generateUID(),
|
|
userId: workspaceInput.createdBy,
|
|
email: workspaceInput.createdByEmail,
|
|
workspaceId: workspace.id,
|
|
createdBy: workspaceInput.createdBy,
|
|
role: "admin",
|
|
status: "active",
|
|
});
|
|
}
|
|
|
|
const newWorkspace = { ...workspace };
|
|
delete newWorkspace.id;
|
|
|
|
return newWorkspace;
|
|
};
|
|
|
|
export const update = async (
|
|
db: dbClient,
|
|
workspacePublicId: string,
|
|
workspaceInput: {
|
|
name?: string;
|
|
slug?: string;
|
|
plan?: "free" | "pro" | "enterprise";
|
|
description?: string;
|
|
},
|
|
) => {
|
|
const [result] = await db
|
|
.update(workspaces)
|
|
.set({
|
|
name: workspaceInput.name,
|
|
slug: workspaceInput.slug,
|
|
plan: workspaceInput.plan,
|
|
description: workspaceInput.description,
|
|
})
|
|
.where(eq(workspaces.publicId, workspacePublicId))
|
|
.returning({
|
|
id: workspaces.id,
|
|
publicId: workspaces.publicId,
|
|
name: workspaces.name,
|
|
slug: workspaces.slug,
|
|
description: workspaces.description,
|
|
plan: workspaces.plan,
|
|
});
|
|
|
|
return result;
|
|
};
|
|
|
|
export const getByPublicId = (db: dbClient, workspacePublicId: string) => {
|
|
return db.query.workspaces.findFirst({
|
|
columns: {
|
|
id: true,
|
|
publicId: true,
|
|
name: true,
|
|
plan: true,
|
|
},
|
|
where: eq(workspaces.publicId, workspacePublicId),
|
|
});
|
|
};
|
|
|
|
export const getByPublicIdWithMembers = (
|
|
db: dbClient,
|
|
workspacePublicId: string,
|
|
) => {
|
|
return db.query.workspaces.findFirst({
|
|
columns: {
|
|
id: true,
|
|
publicId: true,
|
|
},
|
|
with: {
|
|
members: {
|
|
columns: {
|
|
publicId: true,
|
|
email: true,
|
|
role: true,
|
|
status: true,
|
|
},
|
|
where: isNull(workspaceMembers.deletedAt),
|
|
with: {
|
|
user: {
|
|
columns: {
|
|
id: true,
|
|
name: true,
|
|
email: true,
|
|
image: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
where: and(
|
|
eq(workspaces.publicId, workspacePublicId),
|
|
isNull(workspaces.deletedAt),
|
|
),
|
|
});
|
|
};
|
|
|
|
export const getBySlugWithBoards = (db: dbClient, workspaceSlug: string) => {
|
|
return db.query.workspaces.findFirst({
|
|
columns: {
|
|
id: true,
|
|
publicId: true,
|
|
name: true,
|
|
description: true,
|
|
slug: true,
|
|
},
|
|
with: {
|
|
boards: {
|
|
columns: {
|
|
publicId: true,
|
|
slug: true,
|
|
name: true,
|
|
},
|
|
where: and(isNull(boards.deletedAt), eq(boards.visibility, "public")),
|
|
},
|
|
},
|
|
where: and(
|
|
eq(workspaces.slug, workspaceSlug),
|
|
isNull(workspaces.deletedAt),
|
|
),
|
|
});
|
|
};
|
|
|
|
export const getAllByUserId = async (db: dbClient, userId: string) => {
|
|
const result = await db.query.workspaceMembers.findMany({
|
|
columns: {
|
|
role: true,
|
|
},
|
|
with: {
|
|
workspace: {
|
|
columns: {
|
|
publicId: true,
|
|
name: true,
|
|
description: true,
|
|
slug: true,
|
|
plan: true,
|
|
deletedAt: true,
|
|
},
|
|
// https://github.com/drizzle-team/drizzle-orm/issues/2903
|
|
// where: isNull(workspaces.deletedAt),
|
|
},
|
|
},
|
|
where: and(
|
|
eq(workspaceMembers.userId, userId),
|
|
eq(workspaceMembers.status, "active"),
|
|
isNull(workspaceMembers.deletedAt),
|
|
),
|
|
});
|
|
|
|
return result.filter((member) => !member.workspace.deletedAt);
|
|
};
|
|
|
|
export const getMemberByPublicId = (db: dbClient, memberPublicId: string) => {
|
|
return db.query.workspaceMembers.findFirst({
|
|
columns: {
|
|
id: true,
|
|
},
|
|
where: eq(workspaceMembers.publicId, memberPublicId),
|
|
});
|
|
};
|
|
|
|
export const getAllMembersByPublicIds = (
|
|
db: dbClient,
|
|
memberPublicIds: string[],
|
|
) => {
|
|
return db.query.workspaceMembers.findMany({
|
|
columns: {
|
|
id: true,
|
|
},
|
|
where: inArray(workspaceMembers.publicId, memberPublicIds),
|
|
});
|
|
};
|
|
|
|
export const hardDelete = (db: dbClient, workspacePublicId: string) => {
|
|
return db
|
|
.delete(workspaces)
|
|
.where(eq(workspaces.publicId, workspacePublicId));
|
|
};
|
|
|
|
export const isWorkspaceSlugAvailable = async (
|
|
db: dbClient,
|
|
workspaceSlug: string,
|
|
) => {
|
|
const result = await db.query.workspaces.findFirst({
|
|
columns: {
|
|
id: true,
|
|
},
|
|
where: and(
|
|
eq(workspaces.slug, workspaceSlug),
|
|
isNull(workspaces.deletedAt),
|
|
),
|
|
});
|
|
|
|
return result === undefined;
|
|
};
|
|
|
|
export const isUserInWorkspace = async (
|
|
db: dbClient,
|
|
userId: string,
|
|
workspaceId: number,
|
|
role?: "admin" | "member",
|
|
) => {
|
|
const result = await db.query.workspaceMembers.findFirst({
|
|
columns: {
|
|
id: true,
|
|
},
|
|
where: and(
|
|
eq(workspaceMembers.userId, userId),
|
|
eq(workspaceMembers.workspaceId, workspaceId),
|
|
eq(workspaceMembers.status, "active"),
|
|
isNull(workspaceMembers.deletedAt),
|
|
role ? eq(workspaceMembers.role, role) : undefined,
|
|
),
|
|
});
|
|
|
|
return result?.id !== undefined;
|
|
};
|