feat: deleted documents bin

This commit is contained in:
Ephraim Atta-Duncan
2025-03-13 19:45:11 +00:00
parent 63a4bab0fe
commit 27cd8f9c25
10 changed files with 173 additions and 29 deletions

View File

@ -15,6 +15,7 @@ export const getDocumentStats = async () => {
[ExtendedDocumentStatus.COMPLETED]: 0,
[ExtendedDocumentStatus.REJECTED]: 0,
[ExtendedDocumentStatus.ALL]: 0,
[ExtendedDocumentStatus.DELETED]: 0,
};
counts.forEach((stat) => {

View File

@ -136,18 +136,26 @@ export const findDocuments = async ({
};
}
const deletedDateRange =
status === ExtendedDocumentStatus.DELETED
? {
gte: DateTime.now().minus({ days: 30 }).toJSDate(),
lte: DateTime.now().toJSDate(),
}
: null;
let deletedFilter: Prisma.DocumentWhereInput = {
AND: {
OR: [
{
userId: user.id,
deletedAt: null,
deletedAt: deletedDateRange,
},
{
recipients: {
some: {
email: user.email,
documentDeletedAt: null,
documentDeletedAt: deletedDateRange,
},
},
},
@ -162,19 +170,19 @@ export const findDocuments = async ({
? [
{
teamId: team.id,
deletedAt: null,
deletedAt: deletedDateRange,
},
{
user: {
email: team.teamEmail.email,
},
deletedAt: null,
deletedAt: deletedDateRange,
},
{
recipients: {
some: {
email: team.teamEmail.email,
documentDeletedAt: null,
documentDeletedAt: deletedDateRange,
},
},
},
@ -182,7 +190,7 @@ export const findDocuments = async ({
: [
{
teamId: team.id,
deletedAt: null,
deletedAt: deletedDateRange,
},
],
},
@ -297,6 +305,14 @@ const findDocumentsFilter = (status: ExtendedDocumentStatus, user: User) => {
},
},
},
{
status: ExtendedDocumentStatus.REJECTED,
recipients: {
some: {
email: user.email,
},
},
},
],
}))
.with(ExtendedDocumentStatus.INBOX, () => ({
@ -368,7 +384,24 @@ const findDocumentsFilter = (status: ExtendedDocumentStatus, user: User) => {
recipients: {
some: {
email: user.email,
signingStatus: SigningStatus.REJECTED,
},
},
},
],
}))
.with(ExtendedDocumentStatus.DELETED, () => ({
OR: [
{
userId: user.id,
deletedAt: {
gte: DateTime.now().minus({ days: 30 }).toJSDate(),
not: null,
},
},
{
recipients: {
some: {
email: user.email,
},
},
},
@ -410,7 +443,7 @@ const findTeamDocumentsFilter = (
status: ExtendedDocumentStatus,
team: Team & { teamEmail: TeamEmail | null },
visibilityFilters: Prisma.DocumentWhereInput[],
) => {
): Prisma.DocumentWhereInput | null => {
const teamEmail = team.teamEmail?.email ?? null;
return match<ExtendedDocumentStatus, Prisma.DocumentWhereInput | null>(status)
@ -599,5 +632,32 @@ const findTeamDocumentsFilter = (
return filter;
})
.with(ExtendedDocumentStatus.DELETED, () => {
return {
OR: teamEmail
? [
{
teamId: team.id,
},
{
user: {
email: teamEmail,
},
},
{
recipients: {
some: {
email: teamEmail,
},
},
},
]
: [
{
teamId: team.id,
},
],
};
})
.exhaustive();
};

View File

@ -1,7 +1,5 @@
import { TeamMemberRole } from '@prisma/client';
import type { Prisma, User } from '@prisma/client';
import { SigningStatus } from '@prisma/client';
import { DocumentVisibility } from '@prisma/client';
import { DocumentVisibility, SigningStatus, TeamMemberRole } from '@prisma/client';
import { DateTime } from 'luxon';
import { match } from 'ts-pattern';
@ -17,7 +15,7 @@ export type GetStatsInput = {
search?: string;
};
export const getStats = async ({ user, period, search = '', ...options }: GetStatsInput) => {
export const getStats = async ({ user, period, search, ...options }: GetStatsInput) => {
let createdAt: Prisma.DocumentWhereInput['createdAt'];
if (period) {
@ -30,7 +28,7 @@ export const getStats = async ({ user, period, search = '', ...options }: GetSta
};
}
const [ownerCounts, notSignedCounts, hasSignedCounts] = await (options.team
const [ownerCounts, notSignedCounts, hasSignedCounts, deletedCounts] = await (options.team
? getTeamCounts({
...options.team,
createdAt,
@ -45,6 +43,7 @@ export const getStats = async ({ user, period, search = '', ...options }: GetSta
[ExtendedDocumentStatus.PENDING]: 0,
[ExtendedDocumentStatus.COMPLETED]: 0,
[ExtendedDocumentStatus.REJECTED]: 0,
[ExtendedDocumentStatus.DELETED]: 0,
[ExtendedDocumentStatus.INBOX]: 0,
[ExtendedDocumentStatus.ALL]: 0,
};
@ -71,6 +70,8 @@ export const getStats = async ({ user, period, search = '', ...options }: GetSta
}
});
stats[ExtendedDocumentStatus.DELETED] = deletedCounts || 0;
Object.keys(stats).forEach((key) => {
if (key !== ExtendedDocumentStatus.ALL && isExtendedDocumentStatus(key)) {
stats[ExtendedDocumentStatus.ALL] += stats[key];
@ -167,6 +168,32 @@ const getCounts = async ({ user, createdAt, search }: GetCountsOption) => {
AND: [searchFilter],
},
}),
// Deleted count
prisma.document.count({
where: {
OR: [
{
userId: user.id,
deletedAt: {
gte: DateTime.now().minus({ days: 30 }).toJSDate(),
not: null,
},
},
{
recipients: {
some: {
email: user.email,
documentDeletedAt: {
gte: DateTime.now().minus({ days: 30 }).toJSDate(),
not: null,
},
},
},
},
],
AND: [searchFilter],
},
}),
]);
};
@ -336,5 +363,40 @@ const getTeamCounts = async (options: GetTeamCountsOption) => {
}),
notSignedCountsGroupByArgs ? prisma.document.groupBy(notSignedCountsGroupByArgs) : [],
hasSignedCountsGroupByArgs ? prisma.document.groupBy(hasSignedCountsGroupByArgs) : [],
prisma.document.count({
where: {
OR: [
{
teamId,
userId: userIdWhereClause,
deletedAt: {
gte: DateTime.now().minus({ days: 30 }).toJSDate(),
not: null,
},
},
{
user: {
email: teamEmail,
},
deletedAt: {
gte: DateTime.now().minus({ days: 30 }).toJSDate(),
not: null,
},
},
{
recipients: {
some: {
email: teamEmail,
documentDeletedAt: {
gte: DateTime.now().minus({ days: 30 }).toJSDate(),
not: null,
},
},
},
},
],
AND: [searchFilter],
},
}),
]);
};

View File

@ -4,6 +4,7 @@ export const ExtendedDocumentStatus = {
...DocumentStatus,
INBOX: 'INBOX',
ALL: 'ALL',
DELETED: 'DELETED',
} as const;
export type ExtendedDocumentStatus =

View File

@ -145,6 +145,7 @@ export const ZFindDocumentsInternalResponseSchema = ZFindResultResponse.extend({
[ExtendedDocumentStatus.PENDING]: z.number(),
[ExtendedDocumentStatus.COMPLETED]: z.number(),
[ExtendedDocumentStatus.REJECTED]: z.number(),
[ExtendedDocumentStatus.DELETED]: z.number(),
[ExtendedDocumentStatus.INBOX]: z.number(),
[ExtendedDocumentStatus.ALL]: z.number(),
}),