fix: deaktivierte Produkte sind nicht mehr bestellbar
Ein Produkt, das im Admin-Bereich auf "Inaktiv" gesetzt wird, verschwand zwar aus der Shop-Uebersicht und aus der Sitemap — seine Detailseite blieb aber vollstaendig bestellbar. Erreichbar war sie weiterhin ueber Direktlink, Lesezeichen, alte Newsletter, "Zuletzt angesehen" und den Google-Index. getProductBySlug filtert isActive nicht, und die Seite pruefte es nicht nach. Auch der Checkout selbst pruefte es nicht: getProductsByIds filtert bewusst nicht danach (es wird auch fuer bereits bestellte, inzwischen deaktivierte Produkte genutzt, siehe lib/data.ts), und die Route verliess sich allein auf den Abgleich der Anzahl gefundener Produkte. Die Warenkorb-Oberflaeche zeigt ein deaktiviertes Produkt ueber /api/shop/cart-stock zwar mit Bestand 0 an — aber das ist nur der Client. Ein Warenkorb, der im Browser lag, bevor das Produkt deaktiviert wurde, kam ungeprueft durch: die Bestellung wurde angelegt und tatsaechlich bezahlt, obwohl die Imkerei den Artikel gerade aus dem Verkauf genommen hatte. Behoben an beiden Stellen: - Produktseite: isPurchasable = isActive && Bestand > 0 steuert jetzt Bestellbutton, Sticky-Leiste und die schema.org-Verfuegbarkeit. Die Seite bleibt bewusst erreichbar statt 404 zu liefern — Bestellhistorie und Sendungsverfolgung verlinken hierher zum Bewerten, und wer eine ausgelaufene Saisonernte gekauft hat, soll sie weiter bewerten koennen. Stattdessen "robots: noindex", damit sie nicht ueber Google als vermeintlich bestellbares Produkt gefunden wird. - Die "Benachrichtige mich"-Anmeldung erscheint nur noch bei einem aktiven, aber ausverkauften Produkt. Die Benachrichtigung haengt am Lagerbestand (lib/stock-notifications.ts) — bei einem dauerhaft eingestellten Produkt waere sie ein Versprechen, das nie eingeloest wird. - Checkout-Route: lehnt Bestellungen mit deaktivierten Produkten serverseitig ab, ueber dieselbe Fehlermeldung wie ein nicht mehr vorhandenes Produkt. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
This commit is contained in:
1 parent
746c12ae68
commit
91aee0d609
2 files changed
+67
-32
No files matched your search
@@ -84,6 +84,24 @@ export async function POST(request: Request) {
|
||||
);
|
||||
}
|
||||
|
||||
// Ein im Admin deaktiviertes Produkt (isActive = false) darf nicht mehr
|
||||
// verkauft werden. getProductsByIds filtert bewusst nicht danach, weil es
|
||||
// auch fuer bereits bestellte, inzwischen deaktivierte Produkte genutzt
|
||||
// wird (siehe lib/data.ts) — die Pruefung gehoert deshalb hierher.
|
||||
//
|
||||
// Die Warenkorb-Oberflaeche zeigt ein solches Produkt ueber
|
||||
// /api/shop/cart-stock zwar bereits mit Bestand 0 an, aber das ist nur der
|
||||
// Client. Ein Warenkorb, der im Browser lag, bevor das Produkt deaktiviert
|
||||
// wurde, kam bis hierher ungeprueft durch: die Bestellung wurde angelegt
|
||||
// und tatsaechlich bezahlt, obwohl die Imkerei den Artikel gerade aus dem
|
||||
// Verkauf genommen hatte.
|
||||
if (products.some((product) => !product.isActive)) {
|
||||
return NextResponse.json(
|
||||
{ error: "Ein Produkt im Warenkorb ist nicht mehr verfügbar." },
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
|
||||
const orderItemsData = input.items.map((cartItem) => {
|
||||
const product = products.find((p) => p.id === cartItem.productId)!;
|
||||
return {
|
||||
|
||||
Reference in new issue
Block a user