From 73cf733c5f464e5bf295f1da856fa7b9e30db30e Mon Sep 17 00:00:00 2001 From: elpatron Date: Thu, 2 Oct 2025 10:01:01 +0200 Subject: [PATCH] Fix E-Mail-Versand und verbessere Fehlerbehandlung MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Behebe Port-Konfiguration für interne RPC-Verbindungen (5173 -> 3000) - Verbessere oRPC-Fehlerbehandlung: ursprüngliche Fehlermeldungen werden beibehalten - Erweitere Frontend-Fehlerbehandlung für bessere oRPC-Integration - Deaktiviere Duplikat-Prüfung in Development-Modus (NODE_ENV=development) - Lokale Entwicklung ermöglicht mehrere Buchungen pro E-Mail-Adresse - Produktion behält Duplikat-Schutz bei --- .gitignore | 1 + docker-compose.yml | 2 +- scripts/rebuild-dev.cmd | 2 +- src/client/components/booking-form.tsx | 17 ++++++++++++++++- src/server/routes/rpc.ts | 7 ++++++- src/server/rpc/bookings.ts | 22 +++++++++++++--------- 6 files changed, 38 insertions(+), 13 deletions(-) diff --git a/.gitignore b/.gitignore index f10f349..cacceca 100644 --- a/.gitignore +++ b/.gitignore @@ -22,6 +22,7 @@ Thumbs.db *.njsproj *.sln *.sw? +.notes.txt # Turbo .turbo diff --git a/docker-compose.yml b/docker-compose.yml index 8ed22c0..da08c71 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -15,4 +15,4 @@ services: retries: 3 start_period: 40s environment: - - NODE_ENV=production + - NODE_ENV=development diff --git a/scripts/rebuild-dev.cmd b/scripts/rebuild-dev.cmd index e58c2d2..77cf5d5 100644 --- a/scripts/rebuild-dev.cmd +++ b/scripts/rebuild-dev.cmd @@ -1,6 +1,6 @@ @echo off docker compose -f docker-compose.yml down git pull -docker compose -f docker-compose.yml build --no-cache +docker compose -f docker-compose.yml build docker compose -f docker-compose.yml up -d docker compose -f docker-compose.yml logs -f stargirlnails diff --git a/src/client/components/booking-form.tsx b/src/client/components/booking-form.tsx index 098553d..7567835 100644 --- a/src/client/components/booking-form.tsx +++ b/src/client/components/booking-form.tsx @@ -205,7 +205,22 @@ export function BookingForm() { }, onError: (error: any) => { console.error("Booking error:", error); - const errorText = error?.message || error?.toString() || "Ein unbekannter Fehler ist aufgetreten."; + + // Extract error message from oRPC error structure + let errorText = "Ein unbekannter Fehler ist aufgetreten."; + + if (error?.message) { + errorText = error.message; + } else if (error?.data?.message) { + errorText = error.data.message; + } else if (error?.data?.error) { + errorText = error.data.error; + } else if (typeof error === 'string') { + errorText = error; + } else if (error?.toString) { + errorText = error.toString(); + } + setErrorMessage(errorText); }, } diff --git a/src/server/routes/rpc.ts b/src/server/routes/rpc.ts index e6b8ba2..fc7495c 100644 --- a/src/server/routes/rpc.ts +++ b/src/server/routes/rpc.ts @@ -20,6 +20,11 @@ rpcApp.all("/*", async (c) => { return c.json({ error: "Not found" }, 404); } catch (error) { console.error("RPC Handler error:", error); - return c.json({ error: "Internal server error" }, 500); + + // Preserve the original error message if it's a known error + const errorMessage = error instanceof Error ? error.message : "Internal server error"; + const statusCode = error instanceof Error && error.message.includes("bereits eine Buchung") ? 400 : 500; + + return c.json({ error: errorMessage }, statusCode); } }); diff --git a/src/server/rpc/bookings.ts b/src/server/rpc/bookings.ts index ae0e749..10b6de2 100644 --- a/src/server/rpc/bookings.ts +++ b/src/server/rpc/bookings.ts @@ -12,7 +12,8 @@ import { checkBookingRateLimit, getClientIP } from "../lib/rate-limiter.js"; import { validateEmail } from "../lib/email-validator.js"; // Create a server-side client to call other RPC endpoints -const link = new RPCLink({ url: "http://localhost:5173/rpc" }); +const serverPort = process.env.PORT ? parseInt(process.env.PORT) : 3000; +const link = new RPCLink({ url: `http://localhost:${serverPort}/rpc` }); // Typisierung über any, um Build-Inkompatibilität mit NestedClient zu vermeiden (nur für interne Server-Calls) const queryClient = createORPCClient(link); @@ -117,14 +118,17 @@ const create = os } // Prevent double booking: same customer email with pending/confirmed on same date - const existing = await kv.getAllItems(); - const hasConflict = existing.some(b => - b.customerEmail.toLowerCase() === input.customerEmail.toLowerCase() && - b.appointmentDate === input.appointmentDate && - (b.status === "pending" || b.status === "confirmed") - ); - if (hasConflict) { - throw new Error("Du hast bereits eine Buchung für dieses Datum. Bitte wähle einen anderen Tag oder storniere zuerst."); + // Skip duplicate check in development mode + if (process.env.NODE_ENV !== 'development') { + const existing = await kv.getAllItems(); + const hasConflict = existing.some(b => + b.customerEmail.toLowerCase() === input.customerEmail.toLowerCase() && + b.appointmentDate === input.appointmentDate && + (b.status === "pending" || b.status === "confirmed") + ); + if (hasConflict) { + throw new Error("Du hast bereits eine Buchung für dieses Datum. Bitte wähle einen anderen Tag oder storniere zuerst."); + } } const id = randomUUID(); const booking = {