From 6536fc784bd6fcabfa63424302f32347d26fff8e Mon Sep 17 00:00:00 2001 From: JohannaPeanut <76495099+JohannaPeanut@users.noreply.github.com> Date: Wed, 30 Oct 2024 12:36:31 +0100 Subject: [PATCH] Admin: delete survey test data --- .../test/_components/DeleteButton.tsx | 40 ++++++++++++++ .../[surveyId]/responses/test/page.tsx | 53 +++++++++++++++++++ src/app/admin/surveys/page.tsx | 3 ++ .../mutations/deleteTestSurveyResponses.ts | 20 +++++++ .../queries/getTestSurveyResponses.ts | 43 +++++++++++++++ 5 files changed, 159 insertions(+) create mode 100644 src/app/admin/surveys/[surveyId]/responses/test/_components/DeleteButton.tsx create mode 100644 src/app/admin/surveys/[surveyId]/responses/test/page.tsx create mode 100644 src/survey-responses/mutations/deleteTestSurveyResponses.ts create mode 100644 src/survey-responses/queries/getTestSurveyResponses.ts diff --git a/src/app/admin/surveys/[surveyId]/responses/test/_components/DeleteButton.tsx b/src/app/admin/surveys/[surveyId]/responses/test/_components/DeleteButton.tsx new file mode 100644 index 00000000..22186f74 --- /dev/null +++ b/src/app/admin/surveys/[surveyId]/responses/test/_components/DeleteButton.tsx @@ -0,0 +1,40 @@ +"use client" +import { blueButtonStyles } from "@/src/core/components/links" +import { AllowedSurveySlugs } from "@/src/survey-public/utils/allowedSurveySlugs" +import deleteTestSurveyResponses from "@/src/survey-responses/mutations/deleteTestSurveyResponses" +import { useMutation } from "@blitzjs/rpc" +import clsx from "clsx" +import { useRouter } from "next/navigation" + +type DeleteButtonProps = { + testSurveyResponseIds: number[] + surveySlug: AllowedSurveySlugs +} + +export const DeleteButton = ({ testSurveyResponseIds, surveySlug }: DeleteButtonProps) => { + const [deleteTestSurveyMutation] = useMutation(deleteTestSurveyResponses) + const router = useRouter() + const handleDelete = async () => { + if ( + window.confirm( + `Diese ${testSurveyResponseIds.length} Beteiligungsbeiträge unwiderruflich löschen?`, + ) + ) { + try { + await deleteTestSurveyMutation({ slug: surveySlug, deleteIds: testSurveyResponseIds }) + } catch (error) { + alert("Beim Löschen ist ein Fehler aufgetreten.") + } + router.push("/admin/surveys") + } + } + + return ( + <> +
+ + + ) +} diff --git a/src/app/admin/surveys/[surveyId]/responses/test/page.tsx b/src/app/admin/surveys/[surveyId]/responses/test/page.tsx new file mode 100644 index 00000000..ce7d0d3b --- /dev/null +++ b/src/app/admin/surveys/[surveyId]/responses/test/page.tsx @@ -0,0 +1,53 @@ +import { Breadcrumb } from "@/src/app/admin/_components/Breadcrumb" +import { HeaderWrapper } from "@/src/app/admin/_components/HeaderWrapper" +import { invoke } from "@/src/blitz-server" +import { H2 } from "@/src/core/components/text" +import getTestSurveyResponses from "@/src/survey-responses/queries/getTestSurveyResponses" +import getAdminSurvey from "@/src/surveys/queries/getAdminSurvey" +import { Metadata } from "next" +import "server-only" +import { DeleteButton } from "./_components/DeleteButton" + +export const metadata: Metadata = { title: "Beteiligung bearbeiten erstellen" } + +export default async function AdminSurveyEditPage({ + params: { surveyId: surveyIdString }, +}: { + params: { surveyId: string } +}) { + const survey = await invoke(getAdminSurvey, { id: Number(surveyIdString) }) + const testSurveyResponses = await invoke(getTestSurveyResponses, { + slug: survey.slug, + }) + + return ( + <> + + + +

Testeinträge

+

+ Dies sind alle Einträge, deren Hinweistext (ersten 20 Zeichen) 'test' enthält (plus + die jeweils dazugehörige Umfrageteil) + {survey.slug === "radnetz-brandenburg" && " / die Institution 'FixMyCity' ist"} +

+ {!testSurveyResponses.length + ? "keine Testeinträge gefunden" + : testSurveyResponses.map((response) => ( +
{JSON.stringify(response, undefined, 2)}
+ ))} + {!!testSurveyResponses.length && ( + r.id)} + /> + )} + + ) +} diff --git a/src/app/admin/surveys/page.tsx b/src/app/admin/surveys/page.tsx index b7110b7c..69da6484 100644 --- a/src/app/admin/surveys/page.tsx +++ b/src/app/admin/surveys/page.tsx @@ -38,6 +38,9 @@ export default async function AdminSurveysPage() { Antworten + + Testeinträge prüfen und löschen +
{JSON.stringify(survey, undefined, 2)}
diff --git a/src/survey-responses/mutations/deleteTestSurveyResponses.ts b/src/survey-responses/mutations/deleteTestSurveyResponses.ts new file mode 100644 index 00000000..4ecf1be8 --- /dev/null +++ b/src/survey-responses/mutations/deleteTestSurveyResponses.ts @@ -0,0 +1,20 @@ +import db from "@/db" +import { AllowedSurveySlugsSchema } from "@/src/survey-public/utils/allowedSurveySlugs" +import { resolver } from "@blitzjs/rpc" +import { z } from "zod" + +const Schema = AllowedSurveySlugsSchema.merge(z.object({ deleteIds: z.array(z.number()) })) + +export default resolver.pipe( + resolver.zod(Schema), + resolver.authorize("ADMIN"), + async ({ deleteIds, slug }) => { + await db.surveyResponseTopicsOnSurveyResponses.deleteMany({ + where: { surveyResponse: { id: { in: deleteIds } } }, + }) + await db.surveyResponse.deleteMany({ where: { id: { in: deleteIds } } }) + await db.surveySession.deleteMany({ + where: { responses: { some: { id: { in: deleteIds } } } }, + }) + }, +) diff --git a/src/survey-responses/queries/getTestSurveyResponses.ts b/src/survey-responses/queries/getTestSurveyResponses.ts new file mode 100644 index 00000000..6706cd09 --- /dev/null +++ b/src/survey-responses/queries/getTestSurveyResponses.ts @@ -0,0 +1,43 @@ +import db from "@/db" +import { AllowedSurveySlugsSchema } from "@/src/survey-public/utils/allowedSurveySlugs" +import { getResponseConfigBySurveySlug } from "@/src/survey-public/utils/getConfigBySurveySlug" +import { resolver } from "@blitzjs/rpc" + +const Schema = AllowedSurveySlugsSchema + +export default resolver.pipe( + resolver.zod(Schema), + resolver.authorize("ADMIN"), + async ({ slug }) => { + const { evaluationRefs } = getResponseConfigBySurveySlug(slug) + const userText1Id = evaluationRefs["feedback-usertext-1"] + + const surveySessions = await db.surveySession.findMany({ + where: { survey: { slug: slug } }, + include: { responses: true }, + }) + + let filteredSurveyResponses: (typeof surveySessions)[number]["responses"] = [] + + surveySessions.forEach(({ responses }) => { + if ( + // if either of the conditions is met, add the responses of the sesseion to the filteredSurveyResponses + responses.some((response) => { + const data = JSON.parse(response.data) + return ( + // survey part 2 / "Hinweis" and contains "test" in the first 20 characters of the user text + (response.surveyPart === 2 && + // @ts-expect-error data is of type unknown + data[userText1Id]?.substring(0, 20).toLowerCase().includes("test")) || + // survey is BB and survey part 1 / "Umfrage" and institution is "FixMyCity" + // @ts-expect-error data is of type unknown + (response.surveyPart === 1 && slug === "radnetz-brandenburg" && data[5] === "FixMyCity") + ) + }) + ) + filteredSurveyResponses = [...filteredSurveyResponses, ...responses] + }) + + return filteredSurveyResponses + }, +)