backend, frontend, and admin. Each sub-project has its own package.json and must be started independently. This page explains the purpose of every significant directory and file so you can navigate and extend the codebase with confidence.
Directory Tree
Backend
Thebackend sub-project is a Node.js application written entirely with ES Module syntax ("type": "module" in package.json). It is started with npm run server, which invokes nodemon so the process restarts automatically on file changes.
server.js — Entry Point
server.js is the single entry point for the entire API. It is responsible for:
- Creating the Express
appinstance. - Applying global middleware —
express.json()for JSON body parsing andcors()to allow cross-origin requests from the React dev servers. - Calling
connectDB()to open the Mongoose connection to MongoDB. - Mounting each router at its URL prefix.
- Serving the static
uploads/directory at/images. - Starting the HTTP server on
process.env.PORT(defaults to4000).
API Route Prefixes
config/db.js
Exports the connectDB function, which uses the MONGODB_URI environment variable to open a Mongoose connection. Called once at startup from server.js.
controllers/
Each file maps to one route group and contains the business logic that reads from and writes to MongoDB:
foodController.js— Handles add, list, and remove operations for food documents. The add handler receives the Multer-processed file and persists the filename alongside the food metadata.userController.js— Registers new users (hashing passwords with bcrypt) and authenticates returning users, returning a signed JWT on success.cartController.js— Reads and mutates thecartfield on the user document stored in MongoDB.orderController.js— Creates Stripe Checkout sessions, handles Stripe webhook verification, and manages order lifecycle status updates.
middleware/auth.js
A single Express middleware function (authMiddleware) that reads the token header from the incoming request, verifies it with jsonwebtoken, and attaches the decoded userId to req.body. Routes that need authentication import and use this middleware directly.
The JWT is expected in a custom HTTP header named
token (not the standard Authorization: Bearer header). Both the frontend and admin apps pass it this way when making authenticated requests via Axios.models/
Three Mongoose schemas define the MongoDB document shapes:
foodModel.js— Name, description, price, image filename, and category.userModel.js— Name, email, hashed password, and acartDatamap for persisting cart state.orderModel.js— Reference to userId, array of items, amount, address, payment status, and delivery status string.
uploads/
Food images uploaded through the admin dashboard are stored here as timestamped files (e.g., 1713578089412food_1.png). They are served back to clients via the /images static route.
Frontend
Thefrontend sub-project is the customer-facing React 18 SPA scaffolded with Vite 5. It uses React Router v6 for client-side navigation and Axios for all API calls.
src/context/StoreContext.jsx — Global State
StoreContext is the central nervous system of the customer app. It is provided at the application root in main.jsx so every component can consume it. The context exposes:
On component mount,
StoreContext fetches the full food list and, if a token is found in localStorage, also rehydrates the cart from the backend. This means a user’s cart survives a page refresh.src/pages/
src/components/
Admin
Theadmin sub-project is a separate React 18 + Vite app that gives restaurant operators control over the food catalog and live order management. It uses react-toastify for non-blocking success/error notifications.
src/pages/
Add (/add)
The form page for adding a new food item to the catalog. Operators fill in the name, description, price, and category, and upload a cover image. On submission it sends a multipart/form-data POST request to /api/food/add. A toast notification confirms success or reports an error.
List (/list)
Fetches all food items from GET /api/food/list and renders them in a table. Each row has a Delete button that calls POST /api/food/remove and refreshes the list in place. Useful for auditing the catalog and removing discontinued items.
Orders (/orders)
Fetches all orders from GET /api/order/list and displays them with current status. Operators can change the delivery status (e.g., “Food Processing”, “Out for Delivery”, “Delivered”) via a dropdown, which fires POST /api/order/status to persist the change.
src/components/
The admin app does not implement its own authentication layer — it is intended to run as a trusted internal tool on a private network or behind a reverse proxy with access controls. Do not expose port 5174 publicly in production.