feat: Wabenhain Honig-Shop Anwendung

Vollstaendige Next.js/Prisma-E-Commerce-Anwendung fuer eine Imkerei:
Shop, Warenkorb, Stripe-Checkout, Kundenkonto mit 2FA, Admin-Bereich
(Produkte, Ernten, Chargen, Bestellungen, Gutscheine, admin-editierbare
Website-Inhalte), i18n (DE/EN), Rate-Limiting/CSP/Audit-Log-Haertung,
PostgreSQL- und MySQL-Unterstuetzung ueber austauschbare Prisma-
Treiber-Adapter, Unit-/Komponenten-/E2E-Tests.
This commit is contained in:
Nick Szaunig committed 2026-08-17 14:30:28 +02:00
1 parent 5c76fcc266
commit c7927f2883
240 files changed
+26096 -137

No files matched your search

+69
View File
@@ -0,0 +1,69 @@
import { prisma } from "@/lib/prisma";
import { insensitiveEquals } from "@/lib/prisma-search";
import type { Order, OrderItem, Shipment, Pickup, Invoice, Address, ReturnRequest } from "@/generated/prisma/client";
export type OrderWithDetails = Order & {
items: (OrderItem & { product: { slug: string } })[];
shipment: Shipment | null;
pickup: Pickup | null;
invoice: Invoice | null;
returnRequest: ReturnRequest | null;
};
export async function getOrdersForCustomer(customerId: string): Promise<OrderWithDetails[]> {
return prisma.order.findMany({
where: { customerId },
include: {
items: { include: { product: { select: { slug: true } } } },
shipment: true,
pickup: true,
invoice: true,
returnRequest: true,
},
orderBy: { createdAt: "desc" },
});
}
/**
* Oeffentliche Bestellverfolgung ohne Login (auch fuer Gastbestellungen):
* Bestellnummer allein reicht nicht — die E-Mail-Adresse muss zusaetzlich
* uebereinstimmen, damit eine Bestellnummer (kryptografisch zufaellig, aber
* theoretisch in URLs/E-Mails sichtbar) allein keinen Zugriff gewaehrt.
*/
export async function getOrderForTracking(
orderNumber: string,
email: string
): Promise<OrderWithDetails | null> {
return prisma.order.findFirst({
where: { orderNumber, email: insensitiveEquals(email) },
include: {
items: { include: { product: { select: { slug: true } } } },
shipment: true,
pickup: true,
invoice: true,
returnRequest: true,
},
});
}
export async function getAddressesForCustomer(customerId: string): Promise<Address[]> {
return prisma.address.findMany({
where: { customerId },
orderBy: [{ isDefault: "desc" }, { createdAt: "desc" }],
});
}
export async function getInvoiceForCustomer(invoiceNumber: string, customerId: string) {
return prisma.invoice.findFirst({
where: { invoiceNumber, order: { customerId } },
include: { order: { include: { items: true, discountCode: { select: { code: true } } } } },
});
}
/** Ohne Besitzpruefung — nur fuer bereits als ADMIN verifizierte Aufrufer. */
export async function getInvoiceByNumber(invoiceNumber: string) {
return prisma.invoice.findUnique({
where: { invoiceNumber },
include: { order: { include: { items: true, discountCode: { select: { code: true } } } } },
});
}