ProjectsSeptember 29, 2026

Bookstore: catalogue, cart and orders

Built with
  • React
  • Node.js
  • MongoDB
  • JavaScript
Bookstore: catalogue, cart and orders: illustrated cover

System architecture

Component and data flow diagramReact storefront to Express API: HTTP requests. Express API to MongoDB: Mongoose query. Checkout screen to Order controller: POST order. Order controller to Orders collection: Save order. MongoDB to Orders collection: Book references.REQUEST / STORAGE BOUNDARYHTTP requestsMongoose queryPOST orderSave orderBook referencesReact storefrontRouter + cart contextExpress APIRoutes / controllersMongoDBBooks + usersCheckout screenBook IDs + quantitiesOrder controllerLook up prices / totalOrders collectionPrice snapshots
Swipe horizontally to inspect the diagram.The order controller reads current book prices from MongoDB before saving line-item snapshots. Authentication is unfinished; payment selection is data, not a payment integration.
A storefront needs more than a list of books. Browsing, cart state, customer details and the order stored by the server must agree. This project explores that boundary through separate frontend and backend repositories. The Vite/React frontend uses React Router for Home, Shop, Auth and Order screens. User and cart contexts share state across those routes. The order screen sends book IDs, quantities, a delivery address and a payment-method selection to Express. The backend separates routes, controllers and Mongoose models. Its entry point mounts auth, books and orders routes and starts listening after connecting to MongoDB. The catalogue controller paginates book queries. The order controller retrieves current book prices from the database, calculates the total and saves the order with its line items. Order totals are calculated on the server rather than accepted from the browser. Each order line also stores the price at order time, alongside a reference to the book. That gives the order its own price record when catalogue prices change later. React Context keeps the small storefront straightforward, but the cart lives in component state and is lost on refresh. Separate repositories make the API boundary explicit while requiring coordinated configuration for deployment. This is a prototype, not a production checkout. The inspected user model has password hashing and verification commented out, and the order routes do not attach authentication middleware. A selected payment method is stored as data; it is not a payment-provider integration. Before deployment I would complete authentication, derive order ownership from the authenticated user, validate quantities and unknown book IDs, add inventory transactions, and replace the hardcoded local API address. Those changes are prerequisites for trusting an order, not optional polish.

Related projects

Let’s talk about the engineering

I’m open to software engineering roles across backend, platform, and data teams. Get in touch to discuss the architecture, trade-offs, or how this experience could help your team.
Get in touch