Frontend an Backend angebunden mit API-Wrapper und Datenmapping

This commit is contained in:
root
2025-03-13 09:17:22 +01:00
parent b0d8d4f915
commit 9ffa70aad1
5 changed files with 398 additions and 150 deletions

View File

@@ -30,14 +30,47 @@ export async function createPrintJob(printJob: InferInsertModel<typeof printJobs
}
try {
const result = await db.insert(printJobs).values(printJob).returning({
jobId: printJobs.id,
// Bereite die Daten für das Backend vor
// In unserem Backend wird printerId als socketId bezeichnet
const backendJob = {
socketId: printJob.printerId, // Feldname ändern für Backend
userId: printJob.userId,
durationInMinutes: printJob.durationInMinutes,
comments: printJob.comments || ""
};
// Sende den Job ans Backend
const backendResponse = await fetch(`${process.env.BACKEND_URL || 'http://localhost:5000'}/api/jobs`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(backendJob)
});
return result[0].jobId;
if (!backendResponse.ok) {
throw new Error(`Backend-Fehler: ${backendResponse.status} ${backendResponse.statusText}`);
}
const backendResult = await backendResponse.json();
// Synchronisiere mit lokaler Datenbank
// Wir verwenden hier die Job-ID vom Backend, um Konsistenz zu gewährleisten
if (backendResult.id) {
const result = await db.insert(printJobs).values({
...printJob,
id: backendResult.id // Verwende die vom Backend erzeugte ID
}).returning({
jobId: printJobs.id,
});
return result[0].jobId;
} else {
return backendResult.id;
}
} catch (error) {
console.error("Fehler beim Erstellen des Druckauftrags:", error);
return {
error: "Druckauftrag konnte nicht hinzugefügt werden.",
error: error instanceof Error ? error.message : "Druckauftrag konnte nicht hinzugefügt werden.",
};
}
}
@@ -85,48 +118,47 @@ export async function abortPrintJob(jobId: string, reason: string) {
};
}
// Get the print job
const printJob = await db.query.printJobs.findFirst({
where: eq(printJobs.id, jobId),
});
try {
// Hole den Druckauftrag vom Backend
const backendResponse = await fetch(`${process.env.BACKEND_URL || 'http://localhost:5000'}/api/jobs/${jobId}/abort`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ reason })
});
if (!backendResponse.ok) {
const errorData = await backendResponse.json();
throw new Error(errorData.message || `Backend-Fehler: ${backendResponse.status}`);
}
// Hole den lokalen Druckauftrag für die Berechtigungsprüfung
const printJob = await db.query.printJobs.findFirst({
where: eq(printJobs.id, jobId),
});
if (!printJob) {
if (printJob) {
// Aktualisiere den lokalen Druckauftrag auch
// biome-ignore lint/style/noNonNullAssertion: guard already checks against null
await db
.update(printJobs)
.set({
aborted: true,
abortReason: reason,
comments: `${printJob.comments || ""}\n\n---${dbUser?.username}: Druckauftrag abgebrochen`,
})
.where(eq(printJobs.id, jobId));
}
revalidatePath("/");
return { success: true };
} catch (error) {
console.error("Fehler beim Abbrechen des Druckauftrags:", error);
return {
error: "Druckauftrag nicht gefunden",
error: error instanceof Error ? error.message : "Druckauftrag konnte nicht abgebrochen werden.",
};
}
// Check if the print job is already aborted or completed
if (printJob.aborted) {
return { error: "Druckauftrag wurde bereits abgebrochen" };
}
if (new Date(printJob.startAt).getTime() + printJob.durationInMinutes * 60 * 1000 < Date.now()) {
return { error: "Druckauftrag ist bereits abgeschlossen" };
}
// Check if user is the owner of the print job
// biome-ignore lint/style/noNonNullAssertion: guard already checks against null
if (printJob.userId !== dbUser!.id && dbUser!.role !== UserRole.ADMIN) {
return {
error: strings.ERROR.PERMISSION,
};
}
// Get duration in minutes since startAt
const duration = Math.floor((Date.now() - new Date(printJob.startAt).getTime()) / 1000 / 60);
await db
.update(printJobs)
.set({
aborted: true,
abortReason: reason,
durationInMinutes: duration,
comments: `${printJob.comments}\n\n---${dbUser?.username}: Druckauftrag abgebrochen`,
})
.where(eq(printJobs.id, jobId));
revalidatePath("/");
}
export async function earlyFinishPrintJob(jobId: string) {
@@ -149,44 +181,48 @@ export async function earlyFinishPrintJob(jobId: string) {
};
}
// Get the print job
const printJob = await db.query.printJobs.findFirst({
where: eq(printJobs.id, jobId),
});
try {
// Sende die Anfrage an das Backend
const backendResponse = await fetch(`${process.env.BACKEND_URL || 'http://localhost:5000'}/api/jobs/${jobId}/finish`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
}
});
if (!backendResponse.ok) {
const errorData = await backendResponse.json();
throw new Error(errorData.message || `Backend-Fehler: ${backendResponse.status}`);
}
// Hole den lokalen Druckauftrag für die Synchronisierung
const printJob = await db.query.printJobs.findFirst({
where: eq(printJobs.id, jobId),
});
if (!printJob) {
return { error: "Druckauftrag nicht gefunden" };
}
// Check if the print job is already aborted or completed
if (printJob.aborted) {
return { error: "Druckauftrag wurde bereits abgebrochen" };
}
if (new Date(printJob.startAt).getTime() + printJob.durationInMinutes * 60 * 1000 < Date.now()) {
return { error: "Druckauftrag ist bereits abgeschlossen" };
}
// Check if user is the owner of the print job
// biome-ignore lint/style/noNonNullAssertion: guard already checks against null
if (printJob.userId !== dbUser!.id && dbUser!.role !== UserRole.ADMIN) {
if (printJob) {
// Aktualisiere den lokalen Druckauftrag auch
// Hole die tatsächliche Dauer vom Backend
const backendData = await backendResponse.json();
const duration = backendData.durationInMinutes || Math.floor((Date.now() - new Date(printJob.startAt).getTime()) / 1000 / 60);
await db
.update(printJobs)
.set({
durationInMinutes: duration,
comments: `${printJob.comments || ""}\n\n---${dbUser?.username}: Druckauftrag vorzeitig abgeschlossen`,
})
.where(eq(printJobs.id, jobId));
}
revalidatePath("/");
return { success: true };
} catch (error) {
console.error("Fehler beim vorzeitigen Beenden des Druckauftrags:", error);
return {
error: strings.ERROR.PERMISSION,
error: error instanceof Error ? error.message : "Druckauftrag konnte nicht vorzeitig beendet werden.",
};
}
// Get duration in minutes since startAt
const duration = Math.floor((Date.now() - new Date(printJob.startAt).getTime()) / 1000 / 60);
await db
.update(printJobs)
.set({
durationInMinutes: duration,
comments: `${printJob.comments}\n\n---${dbUser?.username}: Druckauftrag vorzeitig abgeschlossen`,
})
.where(eq(printJobs.id, jobId));
revalidatePath("/");
}
export async function extendPrintJob(jobId: string, minutes: number, hours: number) {
@@ -209,43 +245,47 @@ export async function extendPrintJob(jobId: string, minutes: number, hours: numb
};
}
// Get the print job
const printJob = await db.query.printJobs.findFirst({
where: eq(printJobs.id, jobId),
});
try {
// Sende die Anfrage an das Backend
const backendResponse = await fetch(`${process.env.BACKEND_URL || 'http://localhost:5000'}/api/jobs/${jobId}/extend`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ minutes, hours })
});
if (!backendResponse.ok) {
const errorData = await backendResponse.json();
throw new Error(errorData.message || `Backend-Fehler: ${backendResponse.status}`);
}
// Hole den lokalen Druckauftrag für die Synchronisierung
const printJob = await db.query.printJobs.findFirst({
where: eq(printJobs.id, jobId),
});
if (!printJob) {
return { error: "Druckauftrag nicht gefunden" };
}
// Check if the print job is already aborted or completed
if (printJob.aborted) {
return { error: "Druckauftrag wurde bereits abgebrochen" };
}
if (new Date(printJob.startAt).getTime() + printJob.durationInMinutes * 60 * 1000 < Date.now()) {
return { error: "Druckauftrag ist bereits abgeschlossen" };
}
// Check if user is the owner of the print job
// biome-ignore lint/style/noNonNullAssertion: guard already checks against null
if (printJob.userId !== dbUser!.id && dbUser!.role !== UserRole.ADMIN) {
if (printJob) {
const duration = minutes + hours * 60;
// Aktualisiere den lokalen Druckauftrag auch
await db
.update(printJobs)
.set({
durationInMinutes: printJob.durationInMinutes + duration,
comments: `${printJob.comments || ""}\n\n---${dbUser?.username}: Verlängert um ${hours} Stunden und ${minutes} Minuten`,
})
.where(eq(printJobs.id, jobId));
}
revalidatePath("/");
return { success: true };
} catch (error) {
console.error("Fehler beim Verlängern des Druckauftrags:", error);
return {
error: strings.ERROR.PERMISSION,
error: error instanceof Error ? error.message : "Druckauftrag konnte nicht verlängert werden.",
};
}
const duration = minutes + hours * 60;
await db
.update(printJobs)
.set({
durationInMinutes: printJob.durationInMinutes + duration,
comments: `${printJob.comments}\n\n---${dbUser?.username}: Verlängert um ${hours} Stunden und ${minutes} Minuten`,
})
.where(eq(printJobs.id, jobId));
revalidatePath("/");
}
export async function updatePrintComments(jobId: string, comments: string) {
@@ -268,38 +308,41 @@ export async function updatePrintComments(jobId: string, comments: string) {
};
}
// Get the print job
const printJob = await db.query.printJobs.findFirst({
where: eq(printJobs.id, jobId),
});
try {
// Sende die Anfrage an das Backend
const backendResponse = await fetch(`${process.env.BACKEND_URL || 'http://localhost:5000'}/api/jobs/${jobId}/comments`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ comments })
});
if (!backendResponse.ok) {
const errorData = await backendResponse.json();
throw new Error(errorData.message || `Backend-Fehler: ${backendResponse.status}`);
}
if (!printJob) {
return { error: "Druckauftrag nicht gefunden" };
}
// Synchronisiere mit der lokalen Datenbank
const printJob = await db.query.printJobs.findFirst({
where: eq(printJobs.id, jobId),
});
// Check if the print job is already aborted or completed
if (printJob.aborted) {
return { error: "Druckauftrag wurde bereits abgebrochen" };
}
if (new Date(printJob.startAt).getTime() + printJob.durationInMinutes * 60 * 1000 < Date.now()) {
return { error: "Druckauftrag ist bereits abgeschlossen" };
}
// Check if user is the owner of the print job
// biome-ignore lint/style/noNonNullAssertion: guard already checks against null
if (printJob.userId !== dbUser!.id && dbUser!.role !== UserRole.ADMIN) {
if (printJob) {
await db
.update(printJobs)
.set({
comments,
})
.where(eq(printJobs.id, jobId));
}
revalidatePath("/");
return { success: true };
} catch (error) {
console.error("Fehler beim Aktualisieren der Kommentare:", error);
return {
error: strings.ERROR.PERMISSION,
error: error instanceof Error ? error.message : "Kommentare konnten nicht aktualisiert werden.",
};
}
await db
.update(printJobs)
.set({
comments,
})
.where(eq(printJobs.id, jobId));
revalidatePath("/");
}

View File

@@ -7,6 +7,8 @@ import { IS_NOT, guard } from "@/utils/guard";
import strings from "@/utils/strings";
import { type InferInsertModel, eq } from "drizzle-orm";
import { revalidatePath } from "next/cache";
import { backendApi } from "@/utils/fetch";
import { mapBackendPrinterToFrontend, mapFrontendPrinterToBackend } from "@/utils/backend-types";
export async function createPrinter(printer: InferInsertModel<typeof printers>) {
const { user } = await validateRequest();
@@ -35,8 +37,16 @@ export async function createPrinter(printer: InferInsertModel<typeof printers>)
}
try {
// Transformiere die Daten ins Backend-Format
const backendPrinter = mapFrontendPrinterToBackend(printer);
// Rufe das Backend API auf
await backendApi.printers.create(backendPrinter);
// Lokale Datenbank bleibt synchronisiert (optional, wenn du weiterhin lokale Daten brauchst)
await db.insert(printers).values(printer);
} catch (error) {
console.error("Fehler beim Erstellen des Druckers:", error);
return {
error: "Drucker konnte nicht hinzugefügt werden.",
};
@@ -72,10 +82,18 @@ export async function updatePrinter(id: string, data: InferInsertModel<typeof pr
}
try {
// Transformiere die Daten ins Backend-Format
const backendPrinter = mapFrontendPrinterToBackend(data);
// Rufe das Backend API auf
await backendApi.printers.update(id, backendPrinter);
// Lokale Datenbank bleibt synchronisiert (optional)
await db.update(printers).set(data).where(eq(printers.id, id));
} catch (error) {
console.error("Fehler beim Aktualisieren des Druckers:", error);
return {
error: "Druckerdaten sind erforderlich.",
error: "Drucker konnte nicht aktualisiert werden.",
};
}
@@ -103,8 +121,13 @@ export async function deletePrinter(id: string) {
}
try {
// Rufe das Backend API auf
await backendApi.printers.delete(id);
// Lokale Datenbank bleibt synchronisiert (optional)
await db.delete(printers).where(eq(printers.id, id));
} catch (error) {
console.error("Fehler beim Löschen des Druckers:", error);
if (error instanceof Error) {
return {
error: error.message,
@@ -119,12 +142,23 @@ export async function deletePrinter(id: string) {
}
export async function getPrinters() {
return await db.query.printers.findMany({
with: {
printJobs: {
limit: 1,
orderBy: (printJobs, { desc }) => [desc(printJobs.startAt)],
try {
// Rufe die Drucker vom Backend ab
const backendPrinters = await backendApi.printers.getAll();
// Transformiere die Backend-Daten ins Frontend-Format
return backendPrinters.map(mapBackendPrinterToFrontend);
} catch (error) {
console.error("Fehler beim Abrufen der Drucker:", error);
// Fallback zur lokalen Datenbank, falls das Backend nicht erreichbar ist
return await db.query.printers.findMany({
with: {
printJobs: {
limit: 1,
orderBy: (printJobs, { desc }) => [desc(printJobs.startAt)],
},
},
},
});
});
}
}