Repository layout
The root
package.json contains scripts to run both apps concurrently with npm run dev.Backend structure
The backend follows a layered architecture with clear separation between routing, business logic, and data access.Directory tree
Architectural layers
Routes layer
Routes layer
Route files define Express endpoints and apply middleware:Routes delegate business logic to controllers and never directly access models.
Controllers layer
Controllers layer
Controllers handle HTTP requests and responses:Controllers are located at
backend/src/controllers/.Services layer
Services layer
Reusable business logic extracted from controllers:
- emailService.js: Send verification and reset emails
- otpService.js: Generate 6-digit OTPs with expiry
- paymentService.js: Create UPI deep links
- notificationService.js: Manage SSE connections for real-time updates
req or res objects.Models layer
Models layer
Mongoose schemas define data structure and validation:Models expose Mongoose query methods used by controllers.
Entry point
The server bootstraps in backend/src/index.js:- Load environment variables (dotenv)
- Initialize Express app
- Apply security middleware (helmet, CORS)
- Configure rate limiters (global, auth, orders)
- Register routes
- Start database connection
- Listen on configured port
startServer() function.
The SSE notification route is registered before rate limiters to allow persistent connections (backend/src/index.js:72).
Frontend structure
The frontend follows a component-based architecture with React hooks and context for state management.Directory tree
Component patterns
UI components (components/ui/)
UI components (components/ui/)
Reusable, unstyled primitives built with Radix UI:
- Fully accessible (ARIA compliant)
- Composable APIs
- No business logic
- Styled with Tailwind CSS and
class-variance-authorityfor variants
Layout components (components/layout/)
Layout components (components/layout/)
Structural components used across all pages:
- Navbar: Top navigation with user menu and cart button
- Layout: Wraps page content with navbar and responsive container
Shared components (components/shared/)
Shared components (components/shared/)
State management
AuthContext
User authentication state and login/logout actions
CartContext
Shopping cart items and add/remove operations
NotificationContext
Toast notifications using Sonner library
Routing structure
React Router defines protected and public routes in frontend/src/App.jsx:Configuration files
Backend configuration
.env
Environment variables (gitignored)
.env.example
Template with all required variables
package.json
Dependencies and scripts
Frontend configuration
vite.config.js
Vite build settings and dev server proxy
tailwind.config.js
Tailwind theme and plugin configuration
package.json
Dependencies and build scripts
Key architectural decisions
ES modules everywhere
Both frontend and backend use ES modules (import/export) instead of CommonJS:
- Backend:
"type": "module"in package.json - Frontend: Vite defaults to ES modules
- All files use
.jsextension (JSX in frontend via Vite plugin)
No centralized state management library
The frontend uses React Context instead of Redux/Zustand because:- Application state is simple (auth, cart, notifications)
- Most data is fetched per-page and doesn’t need global caching
- Reduces bundle size and complexity
MongoDB over PostgreSQL
The codebase was originally designed for PostgreSQL but was migrated to MongoDB:- Mongoose provides schema validation similar to SQL
- Flexible schema for rapid iteration
- Easy deployment with MongoDB Atlas
The README mentions PostgreSQL because the original design used it. The current implementation uses MongoDB exclusively (see backend/src/config/db.js).
Manual payment confirmation
No payment gateway integration—UPI payments are confirmed manually by store employees:- Reduces complexity and third-party dependencies
- Suitable for small campus environment with trusted users
- Stores verify payment in their UPI app before accepting orders
Development workflow
Running the application
Directory conventions
Backend conventions
Backend conventions
- Controllers: Named
<entity>Controller.js(e.g.,orderController.js) - Routes: Named
<entity>Routes.js(e.g.,orderRoutes.js) - Models: Capitalized entity names (e.g.,
Order.js) - Services: Named
<feature>Service.js(e.g.,emailService.js)
Frontend conventions
Frontend conventions
- Pages: Named
<Name>Page.jsx(e.g.,DashboardPage.jsx) - Components: PascalCase names (e.g.,
Button.jsx,OrderTimeline.jsx) - Hooks: Prefixed with
use(e.g.,usePolling.js) - Utils: camelCase names (e.g.,
api.js,validators.js)
Next steps
Architecture overview
Learn about system design and data flow
Tech stack
Explore technologies and dependencies