Complete technical specification for building a modern bakery website with online payments, real-time delivery tracking, and comprehensive admin tools.
Modern, scalable, and production-ready
/api/auth/register
Create account
/api/auth/login
Login, returns JWT
/api/auth/refresh
Refresh token
/api/products
List with filters
/api/products/:slug
Product detail
/api/admin/products
Create product 🔒
/api/admin/products/:id
Update product 🔒
/api/orders
Create order
/api/orders/:id
Order details
/api/orders/:id/track
Live tracking
/api/checkout/session
Create Stripe session
Project setup, database design, authentication system
Categories, products, variations, image handling
Shopping cart, Stripe integration, order creation
Real-time status updates, driver location, ETA
Admin panel, testing, performance, deployment
export const getProducts = async (req, res) => {
const { category, search, page = 1, limit = 12 } = req.query;
const where = {
isActive: true,
...(category && { category: { slug: category } }),
...(search && {
OR: [
{ name: { contains: search, mode: 'insensitive' } },
{ description: { contains: search, mode: 'insensitive' } }
]
})
};
const [products, total] = await Promise.all([
prisma.product.findMany({
where,
include: {
category: true,
variations: true,
images: { orderBy: { order: 'asc' } }
},
skip: (page - 1) * limit,
take: limit,
orderBy: { createdAt: 'desc' }
}),
prisma.product.count({ where })
]);
return res.json({
products,
pagination: {
page: Number(page),
limit: Number(limit),
total,
pages: Math.ceil(total / limit)
}
});
};
export const createCheckoutSession = async (req, res) => {
const { items, deliveryAddress } = req.body;
const lineItems = items.map(item => ({
price_data: {
currency: 'usd',
product_data: {
name: item.name,
images: [item.image],
metadata: { productId: item.id }
},
unit_amount: Math.round(item.price * 100)
},
quantity: item.quantity
}));
const session = await stripe.checkout.sessions.create({
mode: 'payment',
payment_method_types: ['card'],
line_items: lineItems,
success_url: `${process.env.FRONTEND_URL}/order/success?session_id={CHECKOUT_SESSION_ID}`,
cancel_url: `${process.env.FRONTEND_URL}/cart`,
metadata: {
userId: req.user?.id,
deliveryAddress: JSON.stringify(deliveryAddress)
}
});
return res.json({ sessionId: session.id, url: session.url });
};
// Server-side Socket.io handler
io.on('connection', (socket) => {
socket.on('subscribe:order', async (orderId) => {
socket.join(`order:${orderId}`);
const delivery = await prisma.delivery.findFirst({
where: { orderId },
include: { order: true }
});
socket.emit('delivery:status', {
status: delivery?.status || 'pending',
eta: delivery?.eta,
driverName: delivery?.driverName,
currentLocation: delivery?.currentLocation
});
});
socket.on('driver:location', async ({ orderId, location }) => {
await prisma.delivery.update({
where: { orderId },
data: { currentLocation: location, updatedAt: new Date() }
});
io.to(`order:${orderId}`).emit('delivery:location', location);
});
});
// Client-side React hook
const useDeliveryTracking = (orderId: string) => {
const [status, setStatus] = useState<DeliveryStatus>(null);
useEffect(() => {
const socket = io(process.env.NEXT_PUBLIC_WS_URL);
socket.emit('subscribe:order', orderId);
socket.on('delivery:status', setStatus);
socket.on('delivery:location', (loc) => setStatus(prev => ({ ...prev, currentLocation: loc })));
return () => socket.disconnect();
}, [orderId]);
return status;
};