From 2f4aea52eb24d3120a1be8e3b4d8dd6297ce382a Mon Sep 17 00:00:00 2001 From: Henry Date: Sat, 7 Feb 2026 22:00:55 +0000 Subject: [PATCH] feat: add repo funcs --- packages/db/src/repository/card.repo.ts | 1 + packages/db/src/repository/member.repo.ts | 30 ++++++ .../db/src/repository/notification.repo.ts | 98 +++++++++++++++++++ 3 files changed, 129 insertions(+) create mode 100644 packages/db/src/repository/notification.repo.ts diff --git a/packages/db/src/repository/card.repo.ts b/packages/db/src/repository/card.repo.ts index 805ddce0..e70d7d81 100644 --- a/packages/db/src/repository/card.repo.ts +++ b/packages/db/src/repository/card.repo.ts @@ -420,6 +420,7 @@ export const getWithListAndMembersByPublicId = async ( ) => { const card = await db.query.cards.findFirst({ columns: { + id: true, publicId: true, title: true, description: true, diff --git a/packages/db/src/repository/member.repo.ts b/packages/db/src/repository/member.repo.ts index 5aba6423..4035784e 100644 --- a/packages/db/src/repository/member.repo.ts +++ b/packages/db/src/repository/member.repo.ts @@ -63,6 +63,36 @@ export const getById = async (db: dbClient, memberId: number) => { }); }; +export const getByPublicIdsWithUsers = async ( + db: dbClient, + memberPublicIds: string[], + workspaceId?: number, +) => { + return db.query.workspaceMembers.findMany({ + where: (members, { inArray: inArrayFn, eq, and, isNull: isNullFn }) => { + const conditions = [inArrayFn(members.publicId, memberPublicIds)]; + + if (workspaceId) { + conditions.push(eq(members.workspaceId, workspaceId)); + } + + conditions.push(eq(members.status, "active")); + conditions.push(isNullFn(members.deletedAt)); + + return and(...conditions); + }, + with: { + user: { + columns: { + id: true, + name: true, + email: true, + }, + }, + }, + }); +}; + export const getByEmailAndStatus = async ( db: dbClient, email: string, diff --git a/packages/db/src/repository/notification.repo.ts b/packages/db/src/repository/notification.repo.ts new file mode 100644 index 00000000..67bd2b4c --- /dev/null +++ b/packages/db/src/repository/notification.repo.ts @@ -0,0 +1,98 @@ +import { and, count, eq, isNull } from "drizzle-orm"; + +import type { dbClient } from "@kan/db/client"; +import type { NotificationType } from "@kan/db/schema"; +import { notifications } from "@kan/db/schema"; +import { generateUID } from "@kan/shared/utils"; + +export const create = async ( + db: dbClient, + notificationInput: { + type: NotificationType; + userId: string; + cardId?: number; + commentId?: number; + workspaceId?: number; + metadata?: string; + }, +) => { + const [result] = await db + .insert(notifications) + .values({ + publicId: generateUID(), + type: notificationInput.type, + userId: notificationInput.userId, + cardId: notificationInput.cardId, + commentId: notificationInput.commentId, + workspaceId: notificationInput.workspaceId, + metadata: notificationInput.metadata, + }) + .returning(); + + return result; +}; + +export const exists = async ( + db: dbClient, + args: { + userId: string; + type: NotificationType; + cardId?: number; + workspaceId?: number; + commentId?: number; + }, +) => { + const result = await db.query.notifications.findFirst({ + where: (notifications, { eq, and, isNull: isNullFn }) => { + const conditions = [ + eq(notifications.userId, args.userId), + eq(notifications.type, args.type), + isNullFn(notifications.deletedAt), + ]; + + if (args.cardId) { + conditions.push(eq(notifications.cardId, args.cardId)); + } + + if (args.workspaceId) { + conditions.push(eq(notifications.workspaceId, args.workspaceId)); + } + + return and(...conditions); + }, + }); + + return !!result; +}; + +export const markAsRead = async ( + db: dbClient, + notificationId: number, +) => { + const [result] = await db + .update(notifications) + .set({ readAt: new Date() }) + .where(eq(notifications.id, notificationId)) + .returning(); + + return result; +}; + +export const getUnreadCount = async ( + db: dbClient, + userId: string, +) => { + const result = await db + .select({ count: count() }) + .from(notifications) + .where( + and( + eq(notifications.userId, userId), + isNull(notifications.readAt), + isNull(notifications.deletedAt), + ), + ); + + return result[0]?.count ?? 0; +}; +