import dayjs from "dayjs"; import { and, asc, between, count, eq, getOrderByFromSort, ilike, inArray, or, } from "@turbostarter/db"; import { account, customer, invitation, member, organization, user, } from "@turbostarter/db/schema"; import { db } from "@turbostarter/db/server"; import type { GetUserAccountsInput, GetUserInvitationsInput, GetUserMembershipsInput, GetUserPlansInput, GetUsersInput, } from "../../../schema"; export const getUsersCount = async () => db .select({ count: count() }) .from(user) .then((res) => res[0]?.count ?? 0); export const getUsers = async (input: GetUsersInput) => { const offset = (input.page - 1) * input.perPage; const where = and( input.q ? or(ilike(user.name, `%${input.q}%`), ilike(user.email, `%${input.q}%`)) : undefined, input.role ? inArray(user.role, input.role) : undefined, input.twoFactorEnabled ? inArray(user.twoFactorEnabled, input.twoFactorEnabled) : undefined, input.banned ? inArray(user.banned, input.banned) : undefined, input.createdAt ? between( user.createdAt, dayjs(input.createdAt[0]).startOf("day").toDate(), dayjs(input.createdAt[1]).endOf("day").toDate(), ) : undefined, ); const orderBy = input.sort ? getOrderByFromSort({ sort: input.sort, defaultSchema: user }) : [asc(user.name)]; return db.transaction(async (tx) => { const data = await tx .select() .from(user) .where(where) .limit(input.perPage) .offset(offset) .orderBy(...orderBy); const total = await tx .select({ count: count(), }) .from(user) .where(where) .execute() .then((res) => res[0]?.count ?? 0); return { data, total, }; }); }; export const getUserAccounts = async ({ userId, ...input }: GetUserAccountsInput & { userId: string }) => { const offset = (input.page - 1) * input.perPage; const where = and( input.providerId ? inArray(account.providerId, input.providerId) : undefined, input.createdAt ? between( account.createdAt, dayjs(input.createdAt[0]).startOf("day").toDate(), dayjs(input.createdAt[1]).endOf("day").toDate(), ) : undefined, input.updatedAt ? between( account.updatedAt, dayjs(input.updatedAt[0]).startOf("day").toDate(), dayjs(input.updatedAt[1]).endOf("day").toDate(), ) : undefined, eq(account.userId, userId), ); const orderBy = input.sort ? getOrderByFromSort({ sort: input.sort, defaultSchema: account }) : [asc(account.providerId)]; return db.transaction(async (tx) => { const data = await tx .select() .from(account) .where(where) .limit(input.perPage) .offset(offset) .orderBy(...orderBy); const total = await tx .select({ count: count(), }) .from(account) .where(where) .execute() .then((res) => res[0]?.count ?? 0); return { data, total, }; }); }; export const getUserPlans = async ({ userId, ...input }: GetUserPlansInput & { userId: string }) => { const offset = (input.page - 1) * input.perPage; const where = and( input.plan ? inArray(customer.plan, input.plan) : undefined, input.status ? inArray(customer.status, input.status) : undefined, input.createdAt ? between( customer.createdAt, dayjs(input.createdAt[0]).startOf("day").toDate(), dayjs(input.createdAt[1]).endOf("day").toDate(), ) : undefined, eq(customer.userId, userId), ); const orderBy = input.sort ? getOrderByFromSort({ sort: input.sort, defaultSchema: customer }) : [asc(customer.plan)]; return db.transaction(async (tx) => { const data = await tx .select({ id: customer.id, userId: customer.userId, customerId: customer.customerId, plan: customer.plan, status: customer.status, credits: customer.credits, createdAt: customer.createdAt, updatedAt: customer.updatedAt, user: { name: user.name, }, }) .from(customer) .leftJoin(user, eq(customer.userId, user.id)) .where(where) .limit(input.perPage) .offset(offset) .orderBy(...orderBy); const total = await tx .select({ count: count() }) .from(customer) .where(where) .execute() .then((res) => res[0]?.count ?? 0); return { data, total, }; }); }; export const getUserMemberships = async ({ userId, ...input }: GetUserMembershipsInput & { userId: string }) => { const offset = (input.page - 1) * input.perPage; const where = and( input.role ? inArray(member.role, input.role) : undefined, input.createdAt ? between( member.createdAt, dayjs(input.createdAt[0]).startOf("day").toDate(), dayjs(input.createdAt[1]).endOf("day").toDate(), ) : undefined, eq(member.userId, userId), ); const orderBy = input.sort ? getOrderByFromSort({ sort: input.sort, defaultSchema: member }) : [asc(organization.name)]; return db.transaction(async (tx) => { const data = await tx .select({ id: member.id, organizationId: member.organizationId, role: member.role, createdAt: member.createdAt, userId: member.userId, organization: { id: organization.id, name: organization.name, slug: organization.slug, logo: organization.logo, }, user: { id: user.id, name: user.name, email: user.email, image: user.image, }, }) .from(member) .leftJoin(organization, eq(member.organizationId, organization.id)) .leftJoin(user, eq(member.userId, user.id)) .where(where) .limit(input.perPage) .offset(offset) .orderBy(...orderBy); const total = await tx .select({ count: count(), }) .from(member) .leftJoin(organization, eq(member.organizationId, organization.id)) .where(where) .execute() .then((res) => res[0]?.count ?? 0); return { data, total, }; }); }; export const getUserInvitations = async ({ userId, ...input }: GetUserInvitationsInput & { userId: string }) => { const offset = (input.page - 1) * input.perPage; const where = and( input.status ? inArray(invitation.status, input.status) : undefined, input.role ? inArray(invitation.role, input.role) : undefined, input.expiresAt ? between( invitation.expiresAt, dayjs(input.expiresAt[0]).startOf("day").toDate(), dayjs(input.expiresAt[1]).endOf("day").toDate(), ) : undefined, eq(user.id, userId), ); const orderBy = input.sort ? getOrderByFromSort({ sort: input.sort, defaultSchema: invitation }) : [asc(organization.name)]; return db.transaction(async (tx) => { const data = await tx .select({ id: invitation.id, email: invitation.email, role: invitation.role, status: invitation.status, expiresAt: invitation.expiresAt, inviterId: invitation.inviterId, organizationId: invitation.organizationId, organization: { id: organization.id, name: organization.name, logo: organization.logo, }, }) .from(invitation) .leftJoin(organization, eq(invitation.organizationId, organization.id)) .leftJoin(user, eq(invitation.email, user.email)) .where(where) .limit(input.perPage) .offset(offset) .orderBy(...orderBy); const total = await tx .select({ count: count() }) .from(invitation) .leftJoin(organization, eq(invitation.organizationId, organization.id)) .leftJoin(user, eq(invitation.email, user.email)) .where(where) .execute() .then((res) => res[0]?.count ?? 0); return { data, total, }; }); };