API größtenteils umgezogen und Funktionen angepasst
This commit is contained in:
@@ -1,9 +1,41 @@
|
||||
import { authorizationMiddleware } from "#lib/middleware/authorization.js";
|
||||
import { prisma } from "@ibcornelsen/database/server";
|
||||
import { AufnahmeSchema, prisma } from "@ibcornelsen/database/server";
|
||||
import { APIError, defineApiRoute } from "astro-typesafe-api/server";
|
||||
import { z } from "zod";
|
||||
|
||||
export const PATCH = defineApiRoute({
|
||||
fetch(input, context) {},
|
||||
input: AufnahmeSchema.omit({
|
||||
id: true,
|
||||
uid: true,
|
||||
benutzer_id: true,
|
||||
objekt_id: true,
|
||||
}),
|
||||
output: z.void(),
|
||||
middleware: authorizationMiddleware,
|
||||
async fetch(input, ctx, user) {
|
||||
const { uid } = ctx.params
|
||||
|
||||
const aufnahme = await prisma.aufnahme.findUnique({
|
||||
where: {
|
||||
uid,
|
||||
benutzer_id: user.id
|
||||
},
|
||||
});
|
||||
|
||||
if (!aufnahme) {
|
||||
throw new APIError({
|
||||
code: "NOT_FOUND",
|
||||
message: "Aufnahme mit dieser UID existiert nicht oder gehört nicht dem aktuellen Benutzer."
|
||||
})
|
||||
}
|
||||
|
||||
await prisma.aufnahme.update({
|
||||
where: {
|
||||
uid
|
||||
},
|
||||
data: input
|
||||
})
|
||||
},
|
||||
});
|
||||
|
||||
export const GET = defineApiRoute({
|
||||
@@ -0,0 +1,59 @@
|
||||
import { authorizationMiddleware } from "#lib/middleware/authorization.js"
|
||||
import { AufnahmeSchema, ObjektSchema, prisma } from "@ibcornelsen/database/server"
|
||||
import { APIError, defineApiRoute } from "astro-typesafe-api/server"
|
||||
import { z } from "zod"
|
||||
|
||||
export const PUT = defineApiRoute({
|
||||
input: z.object({
|
||||
aufnahme: AufnahmeSchema.omit({
|
||||
id: true,
|
||||
uid: true,
|
||||
benutzer_id: true,
|
||||
objekt_id: true,
|
||||
}).merge(z.object({
|
||||
baujahr_klima: z.array(z.number().int().positive()).optional()
|
||||
})),
|
||||
uid_objekt: z.string().uuid()
|
||||
}),
|
||||
output: z.object({
|
||||
uid: z.string().uuid()
|
||||
}),
|
||||
middleware: authorizationMiddleware,
|
||||
async fetch(input, context, user) {
|
||||
const objekt = await prisma.objekt.findUnique({
|
||||
where: {
|
||||
uid: input.uid_objekt,
|
||||
benutzer: {
|
||||
id: user.id
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
if (!objekt) {
|
||||
throw new APIError({
|
||||
code: "NOT_FOUND",
|
||||
message: "Objekt konnte nicht gefunden werden oder gehört nicht diesem Benutzer."
|
||||
})
|
||||
}
|
||||
|
||||
const aufnahme = await prisma.aufnahme.create({
|
||||
data: {
|
||||
...input.aufnahme,
|
||||
benutzer: {
|
||||
connect: {
|
||||
id: user.id
|
||||
}
|
||||
},
|
||||
objekt: {
|
||||
connect: {
|
||||
uid: input.uid_objekt
|
||||
}
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
return {
|
||||
uid: aufnahme.uid
|
||||
}
|
||||
},
|
||||
})
|
||||
@@ -5,7 +5,7 @@ import { TokenType, encodeToken } from "../../../lib/auth/token.js";
|
||||
import { TRPCError } from "@trpc/server";
|
||||
import { defineApiRoute } from "astro-typesafe-api/server";
|
||||
|
||||
export const tRPC_V1_BenutzerGetAccessTokenProcedure = defineApiRoute({
|
||||
export const GET = defineApiRoute({
|
||||
meta: {
|
||||
description:
|
||||
"Erstellt, basierend auf einem existierenden und gültigen Refresh Tokens, einen neuen Access Token, welcher zur Authentifizierung genutzt werden kann. Der resultierende Access Token ist nur 2 Tage gültig und muss danach neu generiert werden. Diese Funktion gibt ebenfalls einen neuen Refresh Token zurück, der alte wird dadurch invalidiert.",
|
||||
|
||||
77
src/pages/api/klimafaktoren.ts
Normal file
77
src/pages/api/klimafaktoren.ts
Normal file
@@ -0,0 +1,77 @@
|
||||
import { z } from "zod";
|
||||
import moment from "moment";
|
||||
import { prisma } from "@ibcornelsen/database/server";
|
||||
import { APIError, defineApiRoute } from "astro-typesafe-api/server";
|
||||
|
||||
export const GET = defineApiRoute({
|
||||
input: z.object({
|
||||
plz: z.string().min(4).max(5),
|
||||
startdatum: z.coerce.date(),
|
||||
enddatum: z.coerce.date(),
|
||||
genauigkeit: z.enum(["months", "years"]),
|
||||
}),
|
||||
|
||||
output: z.array(
|
||||
z.object({
|
||||
month: z.number(),
|
||||
year: z.number(),
|
||||
klimafaktor: z.number(),
|
||||
})
|
||||
),
|
||||
|
||||
async fetch(input, ctx) {
|
||||
const start = moment(input.startdatum);
|
||||
const end = moment(input.enddatum);
|
||||
|
||||
if (start.isSameOrAfter(end)) {
|
||||
throw new APIError({
|
||||
code: "PRECONDITION_FAILED",
|
||||
message: "Das Startdatum kann nicht vor dem Enddatum liegen.",
|
||||
});
|
||||
}
|
||||
|
||||
const intervals = [];
|
||||
|
||||
let currentDate = start.clone();
|
||||
while (currentDate.isSameOrBefore(end)) {
|
||||
let copy = currentDate.clone();
|
||||
intervals.push(copy);
|
||||
currentDate.add(1, input.genauigkeit);
|
||||
}
|
||||
|
||||
let klimafaktoren = await prisma.klimafaktoren.findMany({
|
||||
where: {
|
||||
plz: input.plz,
|
||||
month: intervals[0].month(),
|
||||
OR: intervals.map((date) => {
|
||||
return {
|
||||
year: date.year(),
|
||||
};
|
||||
}),
|
||||
},
|
||||
});
|
||||
|
||||
if (!klimafaktoren) {
|
||||
throw new APIError({
|
||||
code: "NOT_FOUND",
|
||||
message:
|
||||
"Die Klimafaktoren konnten nicht geladen werden. Das kann daran liegen, dass sie für diesen Zeitraum oder Ort nicht verfügbar sind.",
|
||||
});
|
||||
}
|
||||
|
||||
// NOTE: Sollten wir hier lieber den Output padden und trotzdem die gefundenen zurückgeben?
|
||||
if (klimafaktoren.length !== intervals.length) {
|
||||
throw new APIError({
|
||||
code: "NOT_FOUND",
|
||||
message:
|
||||
"Für diesen Zeitraum konnten nicht alle Klimafaktoren gefunden werden.",
|
||||
});
|
||||
}
|
||||
|
||||
return klimafaktoren.map((klimafaktor) => ({
|
||||
month: klimafaktor.month,
|
||||
year: klimafaktor.year,
|
||||
klimafaktor: klimafaktor.klimafaktor,
|
||||
}));
|
||||
},
|
||||
});
|
||||
122
src/pages/api/objekt/[uid]/bilder.ts
Normal file
122
src/pages/api/objekt/[uid]/bilder.ts
Normal file
@@ -0,0 +1,122 @@
|
||||
import { authorizationMiddleware } from "#lib/middleware/authorization.js";
|
||||
import { GebaeudeBilderSchema, prisma } from "@ibcornelsen/database/server";
|
||||
import { APIError, defineApiRoute } from "astro-typesafe-api/server";
|
||||
import { z } from "astro:content";
|
||||
import isBase64 from "is-base64";
|
||||
|
||||
export const PUT = defineApiRoute({
|
||||
input: GebaeudeBilderSchema.pick({
|
||||
kategorie: true,
|
||||
}).merge(z.object({
|
||||
base64: z.string()
|
||||
})),
|
||||
output: z.object({
|
||||
uid: z.string({ description: "Die UID des Bildes." })
|
||||
}),
|
||||
middleware: authorizationMiddleware,
|
||||
async fetch(input, ctx, user) {
|
||||
const base64 = input.base64;
|
||||
|
||||
if (!isBase64(base64, { mimeRequired: true })) {
|
||||
throw new APIError({
|
||||
code: "BAD_REQUEST",
|
||||
message: "Das Bild ist nicht base64 kodiert.",
|
||||
});
|
||||
}
|
||||
|
||||
let objekt = await prisma.objekt.findUnique({
|
||||
where: {
|
||||
uid: ctx.params.uid,
|
||||
benutzer_id: user.id
|
||||
},
|
||||
});
|
||||
|
||||
if (!objekt) {
|
||||
throw new APIError({
|
||||
code: "NOT_FOUND",
|
||||
message: "Objekt nicht gefunden oder gehört einem anderen Benutzer.",
|
||||
});
|
||||
}
|
||||
|
||||
const dataWithoutPrefix = base64.replace(
|
||||
/^data:image\/\w+;base64,/,
|
||||
""
|
||||
);
|
||||
const buffer = Buffer.from(dataWithoutPrefix, "base64");
|
||||
|
||||
const bild = await prisma.gebaeudeBilder.create({
|
||||
data: {
|
||||
kategorie: input.kategorie,
|
||||
objekt: {
|
||||
connect: {
|
||||
id: objekt.id,
|
||||
},
|
||||
},
|
||||
},
|
||||
select: {
|
||||
uid: true,
|
||||
},
|
||||
});
|
||||
|
||||
const filePath = `/persistent/images/${bild.uid}.webp`;
|
||||
|
||||
try {
|
||||
// Wir optimieren das Bild und konvertieren es in WebP
|
||||
// TODO: Sharp scheint nicht zu funktionieren, wir müssen das nochmal testen
|
||||
// const optimizedBuffer = await sharp(buffer).webp({ quality: 80 }).toArray();
|
||||
|
||||
await Bun.write(filePath, buffer)
|
||||
} catch(e) {
|
||||
// Bild wurde nicht gespeichert, wir löschen den Eintrag wieder
|
||||
await prisma.gebaeudeBilder.delete({
|
||||
where: {
|
||||
uid: bild.uid
|
||||
}
|
||||
})
|
||||
// Und geben einen Fehler zurück
|
||||
throw new APIError({
|
||||
code: "INTERNAL_SERVER_ERROR",
|
||||
message: "Bild konnte nicht gespeichert werden.",
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
uid: bild.uid
|
||||
};
|
||||
},
|
||||
})
|
||||
|
||||
export const GET = defineApiRoute({
|
||||
middleware: authorizationMiddleware,
|
||||
output: z.array(GebaeudeBilderSchema.pick({
|
||||
kategorie: true,
|
||||
uid: true
|
||||
})),
|
||||
async fetch(input, ctx, user) {
|
||||
const { uid } = ctx.params;
|
||||
|
||||
const objekt = await prisma.objekt.findUnique({
|
||||
where: {
|
||||
uid
|
||||
},
|
||||
select: {
|
||||
benutzer_id: true,
|
||||
gebaeude_bilder: {
|
||||
select: {
|
||||
kategorie: true,
|
||||
uid: true
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
if (!objekt || objekt.benutzer_id !== user.id) {
|
||||
throw new APIError({
|
||||
code: "FORBIDDEN",
|
||||
message: "Objekt existiert nicht oder gehört einem anderen Benutzer."
|
||||
})
|
||||
}
|
||||
|
||||
return objekt.gebaeude_bilder
|
||||
},
|
||||
})
|
||||
@@ -1,10 +1,44 @@
|
||||
import { authorizationMiddleware } from "#lib/middleware/authorization.js";
|
||||
import { prisma } from "@ibcornelsen/database/server";
|
||||
import { ObjektSchema, prisma } from "@ibcornelsen/database/server";
|
||||
import { APIError, defineApiRoute } from "astro-typesafe-api/server";
|
||||
import { z } from "zod";
|
||||
|
||||
export const PATCH = defineApiRoute({
|
||||
fetch(input, context) {},
|
||||
});
|
||||
input: ObjektSchema.omit({
|
||||
uid: true,
|
||||
id: true,
|
||||
benutzer_id: true
|
||||
}),
|
||||
output: z.void(),
|
||||
headers: {
|
||||
"Authorization": z.string()
|
||||
},
|
||||
middleware: authorizationMiddleware,
|
||||
async fetch(input, ctx, user) {
|
||||
const objekt = await prisma.objekt.findUnique({
|
||||
where: {
|
||||
uid: ctx.params.uid,
|
||||
benutzer: {
|
||||
id: user.id
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
if (!objekt) {
|
||||
throw new APIError({
|
||||
code: "NOT_FOUND",
|
||||
message: "Objekt konnte nicht gefunden werden."
|
||||
})
|
||||
}
|
||||
|
||||
await prisma.objekt.update({
|
||||
where: {
|
||||
uid: ctx.params.uid
|
||||
},
|
||||
data: input
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
export const GET = defineApiRoute({
|
||||
meta: {
|
||||
@@ -24,8 +58,8 @@ export const GET = defineApiRoute({
|
||||
}
|
||||
},
|
||||
middleware: authorizationMiddleware,
|
||||
async fetch(input, context, user) {
|
||||
const { uid } = context.params;
|
||||
async fetch(input, ctx, user) {
|
||||
const { uid } = ctx.params;
|
||||
|
||||
const objekt = await prisma.objekt.findUnique({
|
||||
where: {
|
||||
@@ -3,9 +3,31 @@ import { ObjektSchema, prisma } from "@ibcornelsen/database/server";
|
||||
import { defineApiRoute } from "astro-typesafe-api/server";
|
||||
import { z } from "zod";
|
||||
|
||||
export const POST = defineApiRoute({
|
||||
fetch(input, context) {
|
||||
|
||||
export const PUT = defineApiRoute({
|
||||
input: ObjektSchema.omit({
|
||||
id: true,
|
||||
uid: true,
|
||||
benutzer_id: true
|
||||
}),
|
||||
output: z.object({
|
||||
uid: z.string().uuid()
|
||||
}),
|
||||
middleware: authorizationMiddleware,
|
||||
async fetch(input, context, user) {
|
||||
const objekt = await prisma.objekt.create({
|
||||
data: {
|
||||
...input,
|
||||
benutzer: {
|
||||
connect: {
|
||||
id: user.id
|
||||
}
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
return {
|
||||
uid: objekt.uid
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
49
src/pages/api/postleitzahlen.ts
Normal file
49
src/pages/api/postleitzahlen.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
import { z } from "zod";
|
||||
import { prisma } from "@ibcornelsen/database/server";
|
||||
import { APIError, defineApiRoute } from "astro-typesafe-api/server";
|
||||
|
||||
export const GET = defineApiRoute({
|
||||
input: z.object({
|
||||
plz: z.string().min(1).max(5),
|
||||
limit: z.number().int().max(50).min(1).default(10).optional(),
|
||||
}),
|
||||
output: z.array(
|
||||
z.object({
|
||||
plz: z.string().min(4).max(5),
|
||||
stadt: z.string(),
|
||||
bundesland: z.string(),
|
||||
landkreis: z.string(),
|
||||
lat: z.number(),
|
||||
lon: z.number(),
|
||||
})
|
||||
),
|
||||
async fetch(input, context) {
|
||||
const plz = input.plz;
|
||||
|
||||
const postleitzahlen = await prisma.postleitzahlen.findMany({
|
||||
where: {
|
||||
plz: {
|
||||
startsWith: plz,
|
||||
},
|
||||
},
|
||||
take: input.limit,
|
||||
select: {
|
||||
plz: true,
|
||||
stadt: true,
|
||||
bundesland: true,
|
||||
landkreis: true,
|
||||
lat: true,
|
||||
lon: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (postleitzahlen.length === 0) {
|
||||
throw new APIError({
|
||||
code: "NOT_FOUND",
|
||||
message: "Postleitzahl nicht gefunden",
|
||||
});
|
||||
}
|
||||
|
||||
return postleitzahlen;
|
||||
},
|
||||
});
|
||||
73
src/pages/api/ticket.ts
Normal file
73
src/pages/api/ticket.ts
Normal file
@@ -0,0 +1,73 @@
|
||||
import { z } from "zod";
|
||||
import { TicketsSchema, prisma } from "@ibcornelsen/database/server";
|
||||
import { defineApiRoute } from "astro-typesafe-api/server";
|
||||
import { maybeAuthorizationMiddleware } from "#lib/middleware/authorization.js";
|
||||
|
||||
export const PUT = defineApiRoute({
|
||||
meta: {
|
||||
contentTypes: ["application/json"],
|
||||
description:
|
||||
"Erstellt ein neues Support Ticket und weist den Ersteller diesem zu, falls ein Authorization Header mitgegeben wurde.",
|
||||
summary: "Erstellt ein neues Support Ticket.",
|
||||
tags: ["Tickets"],
|
||||
},
|
||||
input: TicketsSchema.omit({
|
||||
bearbeiter_id: true,
|
||||
benutzer_id: true,
|
||||
created_at: true,
|
||||
deleted_at: true,
|
||||
id: true,
|
||||
prioritaet: true,
|
||||
status: true,
|
||||
uid: true,
|
||||
updated_at: true,
|
||||
}),
|
||||
output: z.object({
|
||||
uid: z.string().uuid(),
|
||||
}),
|
||||
middleware: maybeAuthorizationMiddleware,
|
||||
async fetch(input, ctx, user) {
|
||||
if (user === null) {
|
||||
// Der Benutzer ist nicht authentifiziert.
|
||||
// Wir erstellen das Ticket anonym.
|
||||
const ticket = await prisma.tickets.create({
|
||||
data: {
|
||||
beschreibung: input.beschreibung,
|
||||
email: input.email,
|
||||
titel: input.titel,
|
||||
metadata: input.metadata,
|
||||
},
|
||||
select: {
|
||||
uid: true,
|
||||
},
|
||||
});
|
||||
|
||||
return {
|
||||
uid: ticket.uid,
|
||||
};
|
||||
}
|
||||
|
||||
// Der Benutzer ist authentifiziert.
|
||||
// Wir verlinken den Benutzer und das Ticket.
|
||||
const ticket = await prisma.tickets.create({
|
||||
data: {
|
||||
benutzer: {
|
||||
connect: {
|
||||
id: user.id,
|
||||
},
|
||||
},
|
||||
beschreibung: input.beschreibung,
|
||||
email: input.email,
|
||||
titel: input.titel,
|
||||
metadata: input.metadata,
|
||||
},
|
||||
select: {
|
||||
uid: true,
|
||||
},
|
||||
});
|
||||
|
||||
return {
|
||||
uid: ticket.uid,
|
||||
};
|
||||
},
|
||||
});
|
||||
@@ -1,71 +0,0 @@
|
||||
import { authorizationMiddleware } from "#lib/middleware/authorization.js";
|
||||
import { prisma } from "@ibcornelsen/database/server";
|
||||
import { APIError, defineApiRoute } from "astro-typesafe-api/server";
|
||||
|
||||
export const PATCH = defineApiRoute({
|
||||
fetch(input, context) {},
|
||||
});
|
||||
|
||||
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..."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
middleware: authorizationMiddleware,
|
||||
async fetch(input, context, user) {
|
||||
const { uid } = context.params;
|
||||
|
||||
const ausweis = await prisma.verbrauchsausweisWohnen.findUnique({
|
||||
where: {
|
||||
uid: input.uid,
|
||||
},
|
||||
include: {
|
||||
benutzer: true,
|
||||
aufnahme: {
|
||||
include: {
|
||||
objekt: {
|
||||
include: {
|
||||
gebaeude_bilder: true
|
||||
},
|
||||
},
|
||||
rechnungen: true,
|
||||
events: {
|
||||
include: {
|
||||
benutzer: {
|
||||
select: {
|
||||
uid: true
|
||||
}
|
||||
}
|
||||
},
|
||||
orderBy: {
|
||||
date: "asc"
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
if (!ausweis || (ausweis.benutzer_id !== null && ausweis.benutzer_id !== user.id)) {
|
||||
// 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 ausweis
|
||||
},
|
||||
});
|
||||
117
src/pages/api/verbrauchsausweis-wohnen/[uid].ts
Normal file
117
src/pages/api/verbrauchsausweis-wohnen/[uid].ts
Normal file
@@ -0,0 +1,117 @@
|
||||
import { exclude } from "#lib/exclude.js";
|
||||
import { authorizationMiddleware } from "#lib/middleware/authorization.js";
|
||||
import { prisma, VerbrauchsausweisWohnenSchema } from "@ibcornelsen/database/server";
|
||||
import { APIError, defineApiRoute } from "astro-typesafe-api/server";
|
||||
import { z } from "zod";
|
||||
|
||||
export const PATCH = defineApiRoute({
|
||||
input: VerbrauchsausweisWohnenSchema.omit({
|
||||
uid: true,
|
||||
id: true,
|
||||
benutzer_id: true,
|
||||
aufnahme_id: true,
|
||||
}),
|
||||
output: z.void(),
|
||||
headers: {
|
||||
"Authorization": z.string()
|
||||
},
|
||||
middleware: authorizationMiddleware,
|
||||
async fetch(input, ctx, user) {
|
||||
const objekt = await prisma.verbrauchsausweisWohnen.findUnique({
|
||||
where: {
|
||||
uid: ctx.params.uid,
|
||||
benutzer: {
|
||||
id: user.id
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
if (!objekt) {
|
||||
throw new APIError({
|
||||
code: "NOT_FOUND",
|
||||
message: "Ausweis konnte nicht gefunden werden oder gehört einem anderen Benutzer."
|
||||
})
|
||||
}
|
||||
|
||||
await prisma.verbrauchsausweisWohnen.update({
|
||||
where: {
|
||||
uid: ctx.params.uid
|
||||
},
|
||||
data: input
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
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: VerbrauchsausweisWohnenSchema.merge(z.object({
|
||||
uid_aufnahme: z.string().uuid(),
|
||||
uid_objekt: z.string().uuid(),
|
||||
uid_benutzer: z.string().uuid().optional()
|
||||
})).omit({
|
||||
id: true,
|
||||
aufnahme_id: true,
|
||||
benutzer_id: true,
|
||||
}),
|
||||
middleware: authorizationMiddleware,
|
||||
async fetch(input, context, user) {
|
||||
const { uid } = context.params;
|
||||
|
||||
console.log(uid);
|
||||
|
||||
|
||||
const ausweis = await prisma.verbrauchsausweisWohnen.findUnique({
|
||||
where: {
|
||||
uid,
|
||||
benutzer_id: user.id
|
||||
},
|
||||
include: {
|
||||
benutzer: {
|
||||
select: {
|
||||
uid: true
|
||||
}
|
||||
},
|
||||
aufnahme: {
|
||||
select: {
|
||||
uid: true,
|
||||
objekt: {
|
||||
select: {
|
||||
uid: 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 {
|
||||
uid_aufnahme: ausweis.aufnahme.uid,
|
||||
uid_objekt: ausweis.aufnahme.objekt.uid,
|
||||
uid_benutzer: ausweis.benutzer?.uid,
|
||||
...exclude(ausweis, ["id", "aufnahme_id", "benutzer_id", "aufnahme"])
|
||||
}
|
||||
},
|
||||
});
|
||||
@@ -1,27 +1,101 @@
|
||||
import { authorizationMiddleware } from "#lib/middleware/authorization.js";
|
||||
import { prisma } from "@ibcornelsen/database/server";
|
||||
import { prisma, VerbrauchsausweisWohnenSchema } from "@ibcornelsen/database/server";
|
||||
import { APIError, defineApiRoute } from "astro-typesafe-api/server";
|
||||
import { z } from "zod";
|
||||
|
||||
export const PATCH = defineApiRoute({
|
||||
fetch(input, context) {},
|
||||
});
|
||||
|
||||
export const PUT = defineApiRoute({
|
||||
meta: {
|
||||
contentTypes: ["application/json"],
|
||||
description:
|
||||
"Erstellt einen neuen Verbrauchsausweis für Wohngebäude nach dem Schema der EnEV von 2016. Als Input wird ein bestehendes Gebäude benötigt. Falls keine UID einer bestehenden Gebäudeaufnahme mitgegeben wird, wird automatisch eine erstellt.",
|
||||
tags: ["Verbrauchsausweis Wohnen"],
|
||||
},
|
||||
input: z.object({
|
||||
ausweis: VerbrauchsausweisWohnenSchema.omit({
|
||||
id: true,
|
||||
benutzer_id: true,
|
||||
uid: true,
|
||||
aufnahme_id: true
|
||||
}),
|
||||
uid_aufnahme: z.string().uuid()
|
||||
}),
|
||||
output: z.object({
|
||||
uid: z.string().uuid(),
|
||||
objekt_uid: z.string().uuid(),
|
||||
aufnahme_uid: z.string().uuid(),
|
||||
}),
|
||||
middleware: authorizationMiddleware,
|
||||
async fetch(input, ctx, user) {
|
||||
const aufnahme = await prisma.aufnahme.findUnique({
|
||||
where: {
|
||||
uid: input.uid_aufnahme
|
||||
}
|
||||
})
|
||||
|
||||
if (!aufnahme || aufnahme.benutzer_id !== user.id) {
|
||||
throw new APIError({
|
||||
code: "FORBIDDEN",
|
||||
message: "Aufnahme konnte nicht gefunden werden oder gehört nicht zu diesem Benutzer."
|
||||
})
|
||||
}
|
||||
|
||||
const createdAusweis = await prisma.verbrauchsausweisWohnen.create({
|
||||
data: {
|
||||
...input.ausweis,
|
||||
benutzer: {
|
||||
connect: {
|
||||
id: user.id,
|
||||
},
|
||||
},
|
||||
aufnahme: {
|
||||
connect: {
|
||||
uid: aufnahme.uid,
|
||||
},
|
||||
},
|
||||
},
|
||||
select: {
|
||||
uid: true,
|
||||
aufnahme: {
|
||||
select: {
|
||||
uid: true,
|
||||
objekt: {
|
||||
select: {
|
||||
uid: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
return {
|
||||
uid: createdAusweis.uid,
|
||||
objekt_uid: createdAusweis.aufnahme.objekt.uid,
|
||||
aufnahme_uid: createdAusweis.aufnahme.uid,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export const GET = defineApiRoute({
|
||||
meta: {
|
||||
description: "Gibt ein spezifisches Gebäude des Benutzers zurück.",
|
||||
tags: ["Gebäude"],
|
||||
headers: {
|
||||
"Authorization": {
|
||||
Authorization: {
|
||||
description: "Ein gültiger Authentifizierungstoken",
|
||||
required: true,
|
||||
allowEmptyValue: false,
|
||||
examples: {
|
||||
Bearer: {
|
||||
value: "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
value: "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
middleware: authorizationMiddleware,
|
||||
async fetch(input, context, user) {
|
||||
@@ -37,7 +111,7 @@ export const GET = defineApiRoute({
|
||||
include: {
|
||||
objekt: {
|
||||
include: {
|
||||
gebaeude_bilder: true
|
||||
gebaeude_bilder: true,
|
||||
},
|
||||
},
|
||||
rechnungen: true,
|
||||
@@ -45,20 +119,23 @@ export const GET = defineApiRoute({
|
||||
include: {
|
||||
benutzer: {
|
||||
select: {
|
||||
uid: true
|
||||
}
|
||||
}
|
||||
uid: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
orderBy: {
|
||||
date: "asc"
|
||||
}
|
||||
}
|
||||
date: "asc",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
if (!ausweis || (ausweis.benutzer_id !== null && ausweis.benutzer_id !== user.id)) {
|
||||
if (
|
||||
!ausweis ||
|
||||
(ausweis.benutzer_id !== null && ausweis.benutzer_id !== user.id)
|
||||
) {
|
||||
// Falls wir den Ausweis nicht finden können, werfen wir einen Fehler
|
||||
throw new APIError({
|
||||
code: "NOT_FOUND",
|
||||
@@ -66,6 +143,6 @@ export const GET = defineApiRoute({
|
||||
});
|
||||
}
|
||||
|
||||
return ausweis
|
||||
return ausweis;
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user