Skip to content

Commit

Permalink
Don’t delete polls with options in the future (lukevella#273)
Browse files Browse the repository at this point in the history
  • Loading branch information
lukevella authored Aug 5, 2022
1 parent dac1041 commit 2648be9
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 9 deletions.
35 changes: 29 additions & 6 deletions src/pages/api/house-keeping.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { NextApiRequest, NextApiResponse } from "next";

import { prisma } from "~/prisma/db";

import { parseValue } from "../../utils/date-time-utils";

/**
* DANGER: This endpoint will permanently delete polls.
*/
Expand All @@ -24,12 +26,33 @@ export default async function handler(
return;
}

// soft delete polls that have not been accessed for over 30 days
const inactivePolls = await prisma.poll.deleteMany({
// get polls that have not been accessed for over 30 days
const inactivePolls = await prisma.$queryRaw<
Array<{ id: string; max: string }>
>`
SELECT polls.id, MAX(options.value) FROM polls
JOIN options ON options.poll_id = polls.id
WHERE touched_at <= ${dayjs().add(-30, "days").toDate()} AND deleted = false
GROUP BY polls.id;
`;

const pollsToSoftDelete: string[] = [];

// keep polls that have options that are in the future
inactivePolls.forEach(({ id, max: value }) => {
const parsedValue = parseValue(value);
const date =
parsedValue.type === "date" ? parsedValue.date : parsedValue.end;

if (dayjs(date).isBefore(dayjs())) {
pollsToSoftDelete.push(id);
}
});

const softDeletedPolls = await prisma.poll.deleteMany({
where: {
deleted: false,
touchedAt: {
lte: dayjs().add(-30, "days").toDate(),
id: {
in: pollsToSoftDelete,
},
},
});
Expand Down Expand Up @@ -111,7 +134,7 @@ export default async function handler(
}

res.status(200).json({
inactive: inactivePolls.count,
softDeleted: softDeletedPolls.count,
deleted: pollIdsToDelete.length,
});
}
16 changes: 16 additions & 0 deletions src/utils/date-time-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,3 +155,19 @@ export const expectTimeOption = (d: DateTimeOption): TimeOption => {
}
return d;
};

export const parseValue = (value: string): DateTimeOption => {
if (isTimeSlot(value)) {
const [start, end] = value.split("/");
return {
type: "timeSlot",
start,
end,
};
} else {
return {
type: "date",
date: value,
};
}
};
48 changes: 45 additions & 3 deletions tests/house-keeping.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,17 +75,25 @@ test.beforeAll(async ({ request, baseURL }) => {
participantUrlId: "p6",
adminUrlId: "a6",
},
// Old demo poll
{
demo: true,
title: "Demo poll",
title: "Old demo poll",
id: "demo-poll-old",
type: "date",
userId: "user1",
createdAt: dayjs().add(-2, "days").toDate(),
participantUrlId: "p7",
adminUrlId: "a7",
},
{
title: "Inactive poll with future option",
id: "inactive-poll-future-option",
type: "date",
userId: "user1",
touchedAt: dayjs().add(-30, "days").toDate(),
participantUrlId: "p8",
adminUrlId: "a8",
},
],
});

Expand All @@ -106,6 +114,21 @@ test.beforeAll(async ({ request, baseURL }) => {
value: "2022-02-24",
pollId: "deleted-poll-7d",
},
{
id: "option-4",
value: `${dayjs()
.add(10, "days")
.format("YYYY-MM-DDTHH:mm:ss")}/${dayjs()
.add(10, "days")
.add(1, "hour")
.format("YYYY-MM-DDTHH:mm:ss")}`,
pollId: "inactive-poll-future-option",
},
{
id: "option-5",
value: dayjs().add(-1, "days").format("YYYY-MM-DD"),
pollId: "inactive-poll",
},
],
});

Expand Down Expand Up @@ -144,7 +167,7 @@ test.beforeAll(async ({ request, baseURL }) => {
});

expect(await res.json()).toMatchObject({
inactive: 1,
softDeleted: 1,
deleted: 2,
});
});
Expand Down Expand Up @@ -252,6 +275,16 @@ test("should delete old demo poll", async () => {
expect(oldDemoPoll).toBeNull();
});

test("should not delete poll that has options in the future", async () => {
const futureOptionPoll = await prisma.poll.findFirst({
where: {
id: "inactive-poll-future-option",
},
});

expect(futureOptionPoll).not.toBeNull();
});

// Teardown
test.afterAll(async () => {
await prisma.$executeRaw`DELETE FROM polls WHERE id IN (${Prisma.join([
Expand All @@ -263,4 +296,13 @@ test.afterAll(async () => {
"demo-poll-new",
"demo-poll-old",
])})`;
await prisma.$executeRaw`DELETE FROM options WHERE id IN (${Prisma.join([
"active-poll",
"deleted-poll-6d",
"deleted-poll-7d",
"still-active-poll",
"inactive-poll",
"demo-poll-new",
"demo-poll-old",
])})`;
});

0 comments on commit 2648be9

Please sign in to comment.