Files
documenso/packages/lib/server-only/admin/get-signing-volume.ts
Ephraim Atta-Duncan 70a3f7b3e9 chore: wip
2025-02-25 09:44:10 +00:00

169 lines
4.3 KiB
TypeScript

import { prisma } from '@documenso/prisma';
import { DocumentStatus, SubscriptionStatus } from '@documenso/prisma/client';
type GetSigningVolumeOptions = {
search?: string;
page?: number;
perPage?: number;
sortBy?: 'name' | 'createdAt' | 'signingVolume';
sortOrder?: 'asc' | 'desc';
};
export const getSigningVolume = async ({
search = '',
page = 1,
perPage = 10,
sortBy = 'signingVolume',
sortOrder = 'desc',
}: GetSigningVolumeOptions) => {
const validPage = Math.max(1, page);
const validPerPage = Math.max(1, perPage);
const skip = (validPage - 1) * validPerPage;
const activeSubscriptions = await prisma.subscription.findMany({
where: {
status: SubscriptionStatus.ACTIVE,
},
select: {
id: true,
planId: true,
userId: true,
teamId: true,
createdAt: true,
user: {
select: {
id: true,
name: true,
email: true,
createdAt: true,
},
},
team: {
select: {
id: true,
name: true,
teamEmail: {
select: {
email: true,
},
},
createdAt: true,
},
},
},
});
const subscriptionData = activeSubscriptions.map((subscription) => {
const isTeam = !!subscription.teamId;
return {
id: subscription.id,
planId: subscription.planId,
userId: subscription.userId,
teamId: subscription.teamId,
name: isTeam ? subscription.team?.name : subscription.user?.name || '',
email: isTeam
? subscription.team?.teamEmail?.email || `Team ${subscription.team?.id}`
: subscription.user?.email || '',
createdAt: isTeam ? subscription.team?.createdAt : subscription.user?.createdAt,
isTeam,
};
});
const filteredSubscriptions = search
? subscriptionData.filter((sub) => {
const searchLower = search.toLowerCase();
return (
sub.name?.toLowerCase().includes(searchLower) ||
sub.email?.toLowerCase().includes(searchLower)
);
})
: subscriptionData;
const leaderboardWithVolume = await Promise.all(
filteredSubscriptions.map(async (subscription) => {
let signingVolume = 0;
if (subscription.userId) {
const personalCount = await prisma.document.count({
where: {
userId: subscription.userId,
status: DocumentStatus.COMPLETED,
},
});
signingVolume += personalCount;
const userTeams = await prisma.teamMember.findMany({
where: {
userId: subscription.userId,
},
select: {
teamId: true,
},
});
if (userTeams.length > 0) {
const teamIds = userTeams.map((team) => team.teamId);
const teamCount = await prisma.document.count({
where: {
teamId: {
in: teamIds,
},
status: DocumentStatus.COMPLETED,
},
});
signingVolume += teamCount;
}
}
if (subscription.teamId) {
const teamCount = await prisma.document.count({
where: {
teamId: subscription.teamId,
status: DocumentStatus.COMPLETED,
},
});
signingVolume += teamCount;
}
return {
...subscription,
signingVolume,
};
}),
);
// Sort the results
const sortedResults = [...leaderboardWithVolume].sort((a, b) => {
if (sortBy === 'name') {
return sortOrder === 'asc'
? (a.name || '').localeCompare(b.name || '')
: (b.name || '').localeCompare(a.name || '');
}
if (sortBy === 'createdAt') {
const dateA = a.createdAt ? new Date(a.createdAt).getTime() : 0;
const dateB = b.createdAt ? new Date(b.createdAt).getTime() : 0;
return sortOrder === 'asc' ? dateA - dateB : dateB - dateA;
}
// Default: sort by signingVolume
return sortOrder === 'asc'
? a.signingVolume - b.signingVolume
: b.signingVolume - a.signingVolume;
});
// Apply pagination
const paginatedResults = sortedResults.slice(skip, skip + validPerPage);
// Calculate total pages
const totalPages = Math.ceil(sortedResults.length / validPerPage);
return {
leaderboard: paginatedResults,
totalPages,
};
};