import { BedarfsausweisWohnenClient, OptionalNullable, IDWithPrefix, ZodOverlap } from "#components/Ausweis/types.js"; import { VALID_UUID_PREFIXES } from "#lib/constants.js"; import { generateIDWithPrefix } from "#lib/db.js"; import { exclude } from "#lib/exclude.js"; import { authorizationHeaders, authorizationMiddleware } from "#lib/middleware/authorization.js"; import { sendAusweisGespeichertMail } from "#lib/server/mail/speichern-erfolgreich.js"; import { Enums, prisma } from "#lib/server/prisma.js"; import { APIError, defineApiRoute } from "astro-typesafe-api/server"; import { BedarfsausweisWohnenSchema } from "src/generated/zod/bedarfsausweiswohnen.js"; import { z } from "zod"; export const PATCH = defineApiRoute({ input: BedarfsausweisWohnenSchema.omit({ id: true, benutzer_id: true, aufnahme_id: true, rechnung_id: true, ausgestellt: true, bestellt: true, zurueckgestellt: true, created_at: true, updated_at: true, storniert: true, ausweisart: true }), output: z.void(), headers: { "Authorization": z.string() }, middleware: authorizationMiddleware, async fetch(input, ctx, user) { const objekt = await prisma.bedarfsausweisWohnen.findUnique({ where: { id: ctx.params.id } }) if (!objekt || (objekt.benutzer_id !== user.id && user.rolle !== Enums.BenutzerRolle.ADMIN)) { throw new APIError({ code: "NOT_FOUND", message: "Ausweis konnte nicht gefunden werden oder gehört einem anderen Benutzer." }) } await prisma.bedarfsausweisWohnen.update({ where: { id: ctx.params.id }, data: input }) if (user.rolle === Enums.BenutzerRolle.USER) { await sendAusweisGespeichertMail(user, ctx.params.id as string) } }, }) export const DELETE = defineApiRoute({ meta: { description: "Storniert einen Ausweis" }, headers: authorizationHeaders, middleware: authorizationMiddleware, async fetch(input, ctx, user) { const { id } = ctx.params; if (!IDWithPrefix.safeParse(id).success) { throw new APIError({ code: "BAD_REQUEST", message: "UID konnte nicht verifiziert werden." }) } // Wir holen uns den Bedarfsausweis // Dieser MUSS mit dem Nutzer verknüpft sein. const ausweis = await prisma.bedarfsausweisWohnen.findUnique({ where: { id, benutzer: { id: user.id } } }); if (!ausweis) { // Falls wir den Ausweis nicht finden können, werfen wir einen Fehler throw new APIError({ code: "NOT_FOUND", message: "Ausweis konnte nicht gefunden werden.", }); } // Wir dürfen den Ausweis nur stornieren, wenn er noch nicht ausgestellt wurde // Außerdem müssen wir schauen, ob wir Admin oder der Besitzer des Ausweises sind. if ((ausweis.benutzer_id !== user.id) && user.rolle !== "ADMIN") { // Falls der Ausweis nicht dem Nutzer gehört, werfen wir einen Fehler throw new APIError({ code: "FORBIDDEN", message: "Ausweis gehört nicht dem Nutzer.", }); } // if (ausweis.erledigt) { // // Falls der Ausweis bereits ausgestellt wurde, werfen wir einen Fehler // throw new TRPCError({ // code: "BAD_REQUEST", // message: "Ausweis wurde bereits ausgestellt.", // }); // } if (ausweis.storniert) { // Falls der Ausweis bereits storniert ist, werfen wir einen Fehler throw new APIError({ code: "BAD_REQUEST", message: "Ausweis wurde bereits storniert.", }); } await prisma.bedarfsausweisWohnen.update({ where: { id }, data: { storniert: true } }) const event_id = generateIDWithPrefix(9, VALID_UUID_PREFIXES.Ticket) // Wir erstellen ein Event, dass der Ausweis storniert wurde // Dann können wir das in der Historie anzeigen await prisma.event.create({ data: { id: event_id, title: "Ausweis storniert", description: ((user.rolle === "ADMIN") && (ausweis.benutzer_id !== user.id)) ? "Ausweis wurde von einem Administrator storniert." : "Ausweis wurde vom Besitzer storniert.", benutzer: { connect: { id: user.id } }, aufnahme: { connect: { id: ausweis.aufnahme_id } } } }) }, }) export const GET = defineApiRoute({ meta: { description: "Gibt ein spezifisches Gebäude des Benutzers zurück.", tags: ["Gebäude"], headers: { "Authorization": { description: "Ein gültiger Authentifizierungstoken", required: true, allowEmptyValue: false, examples: { Bearer: { value: "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." } } } } }, output: ZodOverlap>(BedarfsausweisWohnenSchema.merge(z.object({ aufnahme_id: IDWithPrefix, objekt_id: IDWithPrefix, benutzer_id: IDWithPrefix.optional() })).omit({ id: true, aufnahme_id: true, benutzer_id: true })), middleware: authorizationMiddleware, async fetch(input, context, user) { const { id } = context.params; if (!id) { throw new APIError({ code: "BAD_REQUEST", message: "Missing uid in request params" }) } const ausweis = await prisma.verbrauchsausweisWohnen.findUnique({ where: { id, benutzer_id: user.id }, include: { benutzer: { select: { id: true } }, aufnahme: { select: { id: true, objekt: { select: { id: true } } } } } }); if (!ausweis) { // Falls wir den Ausweis nicht finden können, werfen wir einen Fehler throw new APIError({ code: "NOT_FOUND", message: "Ausweis konnte nicht gefunden werden.", }); } return { aufnahme_id: ausweis.aufnahme.id, objekt_id: ausweis.aufnahme.objekt.id, benutzer_id: ausweis.benutzer?.id, ...exclude(ausweis, ["id", "aufnahme_id", "benutzer_id", "aufnahme"]) } }, });