GroceryApp — Online Grocery Ordering Platform
A full-stack grocery application with a React client and an Express/TypeScript backend, covering product data, identity, addresses, orders, delivery workflows, media uploads and payment integration.
Project overview
GroceryApp is a full-stack application split into a React/Vite frontend and an Express 5 TypeScript backend. The backend uses Prisma with PostgreSQL and models users, addresses, products, orders and delivery partners. Its route surface includes authentication, product, upload, order, address, admin and delivery endpoints, plus an Inngest endpoint and Stripe webhook handling. The dependency set shows integrations for payment processing, image storage, email and background functions. The details below describe the repository structure and schema rather than assuming behaviour not visible in those sources.
Capabilities and scope
Architecture at a glance
The following sequence summarises the principal components and boundaries described in the project material.
- 1React 19 + TypeScript frontend built with Vite
- 2HTTP client communicates with the Express 5 TypeScript backend
- 3Express route modules separate authentication, products, orders, addresses, admin and delivery concerns
- 4Controllers coordinate application operations and middleware checks request identity/role context
- 5Prisma Client maps application operations to the PostgreSQL data model
- 6Cloudinary stores media assets; Stripe handles payment-provider interactions
- 7Inngest exposes functions for background/event-driven workflows
1. Product context and application boundary
An online grocery workflow has several related actors and records: customers, products, addresses, orders and delivery partners. The repository is split into frontend and backend directories. The frontend uses React, TypeScript and Vite. The backend is a separate Express 5 TypeScript application. Keeping the frontend and API as separate deployable applications creates a clear HTTP boundary: the browser handles presentation and interaction, while the backend remains responsible for authoritative data changes and protected operations.
2. Backend structure: routes, controllers, middleware and configuration
The backend has separate route modules for authentication, products, uploads, orders, addresses, administration and delivery partners. Controllers hold endpoint handling, while middleware modules include authentication, administrator and delivery authentication checks. Configuration modules initialise Prisma, Cloudinary and Nodemailer. This division helps make the HTTP entry points, access checks and external integrations discoverable instead of concentrating them in one server file.
3. Data model and relationships
The Prisma schema defines User, Address, Product, Order and DeliveryPartner models. A user can have multiple addresses and orders. An order belongs to a user and can optionally be assigned to a delivery partner. The order stores its items and shipping address as JSON snapshots, along with subtotal, delivery fee, tax, total, payment method, status, status history, delivery OTP, live location and payment state. A product stores catalogue information such as name, description, price, image, category, unit, stock and organic/rating fields. This model provides a concrete basis for exploring relational modelling and the deliberate use of JSON for order snapshots.
User 1 -------- N Address
User 1 -------- N Order
DeliveryPartner 1 -- N Order (optional assignment)
Product: catalogue entity referenced by order item snapshotsThe Prisma schema stores Order.items as JSON rather than declaring a separate relational OrderItem model in the schema shown.
4. Authentication and role-oriented request handling
The dependency list includes JSON Web Tokens and bcrypt, while middleware modules are present for general authentication, administrator access and delivery-partner access. This indicates distinct request-access paths for customer, administrator and delivery workflows. A useful engineering review should trace where tokens are created and verified, how password hashes are produced and checked, and how middleware attaches the authenticated identity to each request. Do not infer that client-side role checks provide security; the API must enforce access rules itself.
5. Order lifecycle and delivery context
The Order schema includes a status field, statusHistory, deliveryPartnerId, delivery OTP and optional liveLocation. These fields indicate that the order model is designed to represent more than a simple purchase record: it can retain a status progression and delivery assignment context. The backend exposes order and delivery route groups. When documenting the actual workflow, link each status transition to the responsible actor and endpoint, and define which transitions are permitted rather than treating status as arbitrary text.
6. Payment, media and asynchronous integrations
The backend dependencies include Stripe, Cloudinary, Multer, Nodemailer and Inngest. The server registers a raw-body Stripe webhook route before applying the general JSON middleware, which is an important integration detail because webhook signature verification typically depends on the original request body bytes. Cloudinary and Multer support media-upload workflows. Nodemailer provides email capability. Inngest functions are served from a dedicated endpoint, allowing event-driven or background work to be separated from the synchronous API request path.
7. Frontend responsibilities and user experience
The frontend package uses React, TypeScript and Vite, with React Router, Axios, Tailwind CSS, Lucide icons, toast notifications and React Leaflet dependencies. These choices support client-side route handling, API communication, utility feedback and map-oriented views. The UI should treat server responses as authoritative for order state, prices, stock and access decisions. If the interface displays delivery or address coordinates, validate and handle unavailable location data gracefully.
8. Engineering topics worth documenting next
The repository structure provides natural learning topics: transaction boundaries for order placement, inventory consistency, webhook idempotency, payment state transitions, delivery assignment, background retries, image-upload validation, API error handling and address privacy. These are useful areas to explain with actual controller and service flows. Before claiming a particular guarantee—such as exactly-once payment processing or atomic stock reservation—verify that the corresponding code implements it.
What this project teaches
- ✓Organise a full-stack application into frontend, API, route, controller, middleware and configuration boundaries.
- ✓Model customer, address, product, order and delivery-partner data with Prisma.
- ✓Understand JWT/bcrypt authentication dependencies and role-oriented middleware boundaries.
- ✓Integrate payment webhooks, cloud media, email and background-function infrastructure.
- ✓Identify where order lifecycle, inventory and payment consistency need explicit guarantees.