mirror of
https://github.com/lukevella/rallly.git
synced 2025-04-29 18:26:34 +02:00
Don’t delete polls with options in the future (#273)
This commit is contained in:
parent
dac1041361
commit
2648be9b0a
3 changed files with 90 additions and 9 deletions
|
@ -4,6 +4,8 @@ import { NextApiRequest, NextApiResponse } from "next";
|
||||||
|
|
||||||
import { prisma } from "~/prisma/db";
|
import { prisma } from "~/prisma/db";
|
||||||
|
|
||||||
|
import { parseValue } from "../../utils/date-time-utils";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DANGER: This endpoint will permanently delete polls.
|
* DANGER: This endpoint will permanently delete polls.
|
||||||
*/
|
*/
|
||||||
|
@ -24,12 +26,33 @@ export default async function handler(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// soft delete polls that have not been accessed for over 30 days
|
// get polls that have not been accessed for over 30 days
|
||||||
const inactivePolls = await prisma.poll.deleteMany({
|
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: {
|
where: {
|
||||||
deleted: false,
|
id: {
|
||||||
touchedAt: {
|
in: pollsToSoftDelete,
|
||||||
lte: dayjs().add(-30, "days").toDate(),
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -111,7 +134,7 @@ export default async function handler(
|
||||||
}
|
}
|
||||||
|
|
||||||
res.status(200).json({
|
res.status(200).json({
|
||||||
inactive: inactivePolls.count,
|
softDeleted: softDeletedPolls.count,
|
||||||
deleted: pollIdsToDelete.length,
|
deleted: pollIdsToDelete.length,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -155,3 +155,19 @@ export const expectTimeOption = (d: DateTimeOption): TimeOption => {
|
||||||
}
|
}
|
||||||
return d;
|
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,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
|
@ -75,10 +75,9 @@ test.beforeAll(async ({ request, baseURL }) => {
|
||||||
participantUrlId: "p6",
|
participantUrlId: "p6",
|
||||||
adminUrlId: "a6",
|
adminUrlId: "a6",
|
||||||
},
|
},
|
||||||
// Old demo poll
|
|
||||||
{
|
{
|
||||||
demo: true,
|
demo: true,
|
||||||
title: "Demo poll",
|
title: "Old demo poll",
|
||||||
id: "demo-poll-old",
|
id: "demo-poll-old",
|
||||||
type: "date",
|
type: "date",
|
||||||
userId: "user1",
|
userId: "user1",
|
||||||
|
@ -86,6 +85,15 @@ test.beforeAll(async ({ request, baseURL }) => {
|
||||||
participantUrlId: "p7",
|
participantUrlId: "p7",
|
||||||
adminUrlId: "a7",
|
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",
|
||||||
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -106,6 +114,21 @@ test.beforeAll(async ({ request, baseURL }) => {
|
||||||
value: "2022-02-24",
|
value: "2022-02-24",
|
||||||
pollId: "deleted-poll-7d",
|
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",
|
||||||
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -144,7 +167,7 @@ test.beforeAll(async ({ request, baseURL }) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(await res.json()).toMatchObject({
|
expect(await res.json()).toMatchObject({
|
||||||
inactive: 1,
|
softDeleted: 1,
|
||||||
deleted: 2,
|
deleted: 2,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -252,6 +275,16 @@ test("should delete old demo poll", async () => {
|
||||||
expect(oldDemoPoll).toBeNull();
|
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
|
// Teardown
|
||||||
test.afterAll(async () => {
|
test.afterAll(async () => {
|
||||||
await prisma.$executeRaw`DELETE FROM polls WHERE id IN (${Prisma.join([
|
await prisma.$executeRaw`DELETE FROM polls WHERE id IN (${Prisma.join([
|
||||||
|
@ -263,4 +296,13 @@ test.afterAll(async () => {
|
||||||
"demo-poll-new",
|
"demo-poll-new",
|
||||||
"demo-poll-old",
|
"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",
|
||||||
|
])})`;
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Reference in a new issue