From SQL to typed code
The app needs three functions: the menu grouped by category, placing an order safely (all items or none), and the best customers. Prisma turns your schema into a typed client, and $transaction gives you the same all-or-nothing guarantee you used in SQL.
Nested results for the website
The data layer is where everything from this project meets the app: the schema you designed, the reports you wrote and the transactions that keep orders consistent.
The website wants the menu as nested JSON: each category with its dishes inside. Prisma's include returns exactly that shape from one call, with types that match. Sort both levels — categories by name and dishes by name — so the menu looks the same on every visit.
const categories = await prisma.category.findMany({
orderBy: { name: "asc" },
include: { dishes: { orderBy: { name: "asc" }, select: { name: true, price: true } } },
});
return categories.map((c) => ({ category: c.name, dishes: c.dishes }));