This document provides a detailed overview of the system architecture, component dependencies, network flows, and design patterns utilized in CartBuddy.
CartBuddy is designed using a decoupled client-server architecture. The frontend is a single-page application (SPA) built with React and Vite. The backend is a Node.js/Express.js application that handles business logic, real-time communication via Socket.io, asynchronous email queue processing via BullMQ, and data storage using MongoDB.
graph TD
%% Client Tier
subgraph Client ["Client Tier (React & Vite)"]
SPA["React SPA"]
SocketClient["Socket.io Client"]
Leaflet["Leaflet Map Engine"]
SPA --- SocketClient
SPA --- Leaflet
end
%% Network Gateway
HTTP["HTTPS (REST API)"]
WS["WebSockets (ws://)"]
%% Application Server Tier
subgraph AppServer ["Application Tier (Node.js & Express)"]
Express["Express App"]
SocketServer["Socket.io Server"]
EventBus["Node EventBus"]
Express --- EventBus
SocketServer --- EventBus
end
%% Caching & Queues
subgraph QueueCache ["Cache & Queue Tier (Redis)"]
Redis["Redis Cache"]
BullMQ["BullMQ Queue"]
end
%% Storage & External Services
subgraph Persistence ["Data & Services Tier"]
MongoDB[("MongoDB")]
Cloudinary["Cloudinary CDN"]
BrevoSMTP["Brevo SMTP Service"]
end
%% Connections
SPA ==>|HTTP Requests| HTTP
SocketClient ==>|Real-Time Connection| WS
HTTP ==> Express
WS ==> SocketServer
Express ==>|Geo/User Query Caching| Redis
Express ==>|Mongoose ODM| MongoDB
Express ==>|Uploads| Cloudinary
EventBus ==>|Enqueue Jobs| BullMQ
BullMQ ==>|Redis Connection| Redis
BullMQ ==>|Dispatch Mail| BrevoSMTP
CronScheduler["Cron Schedulers"] -.->|Interval Tasks| MongoDB
| Tier | Technology | Purpose |
|---|---|---|
| Frontend | React 19, Tailwind CSS 4, Vite 8 | User Interface, responsive design, fast bundling |
| Mapping & Motion | Leaflet, GSAP, Framer Motion | Geographic mapping, complex micro-animations |
| Backend Framework | Node.js (>=18), Express.js 4 | API Server router, logic controllers |
| Real-Time Layer | Socket.io 4 | Live chat, location sharing, typing indicators, presence |
| Database | MongoDB & Mongoose 8 | Core document database & ODM mapping |
| Cache & Queue | Redis, BullMQ 5 | Cache layer, async background queue processing |
| Email Dispatch | Brevo API / Nodemailer | Dispatch verification OTPs, notifications |
| File Storage | Cloudinary | Profile image uploads and CDN serving |
| Validation & Auth | Zod 3, JSON Web Tokens (JWT), BcryptJS | Schema validation, secure session access, password hashing |
- User Sign Up: Client posts credentials to
/api/v1/auth/register. - OTP Generation: Backend generates a 6-digit OTP code, stores it in a TTL-indexed MongoDB collection, and enqueues a dispatch job inside
BullMQ. - Queue Execution: The
emailQueueworker retrieves the job, formats it, and transmits it via Brevo/Gmail SMTP. - Verification: User enters the code via
/api/v1/auth/verify-otp. Upon validation, their account status is updated toisVerified: trueand averificationTierofEMAIL_VERIFIEDis granted. - Login Session: Client posts to
/api/v1/auth/login. On validation, the server signs an Access Token (expires in 15m) and a Refresh Token (expires in 7d). The refresh token is saved securely in the database and returned inside ahttpOnlysecure cookie.
To decouple the HTTP API execution path from the real-time event pipeline, CartBuddy uses a local Event Bus bridge:
- Trigger: A user joins or leaves a group through an HTTP action (e.g.
/api/v1/groups/:id/join). - Event Dispatch: The HTTP controller triggers a Mongoose query, completes the database mutation, and emits a local event:
eventBus.emit('group:member-joined', { groupId, memberRecord }). - Socket Bridge: A dedicated socket bridge listener captures the event and multicasts it over Socket.io:
io.to('group:' + groupId).emit('group:member-joined', memberRecord). - Subscribers: All active connected group members receive the live update instantly, updating their UI without page refreshes.
- Nearby Groups: Users search for local shopping groups. The backend queries MongoDB using a
$nearSpherequery referencing a2dsphereindex onmeetingPoint.coordinates. - Live Location Sharing: When active in a shopping group, the React app uses the Geolocation API to monitor client coordinates. Socket.io client sends coordinates updates which are forwarded to other members of the group for visualization on a custom styled Leaflet dark-mode map.
CartBuddy features a Buddy Score algorithm to incentivize good behavior (e.g. paying on time, being responsive, showing up for delivery handover):
- Every user starts with a base score of
100. - Upon group completion, members can rate each other.
- Ratings alter a user's
buddyScorevia a background cron scheduler (jobs/cron/buddyScoreRecompute.cron.js) running daily. - Trust scores are calculated using configured strategies (
rule-basedormock-ml-inference), providing modularity for developers to plug in complex scoring algorithms in the future.
- Helmet Security Headers: Applied to all Express routes to secure cookies, referrers, and restrict cross-site execution.
- API Rate Limiting: Employs
express-rate-limitto restrict requests to a maximum of 300 per 15-minute window for standard APIs, and strict limits on authentication routes (/api/v1/auth/*) to prevent brute-force attacks. - Input Sanitization: Prevents NoSQL Injection attacks by stripping query operator keys (e.g.
$,.) from parameters using custom middleware. - Strict Validation: All incoming requests (body, params, query) are validated against strict Zod schemas before hitting the controllers.
- Environment Integrity: Strict loading and parsing of environment variables using
Zodvalidation on server initialization (backend/src/config/env.config.js). Any missing crucial configuration terminates the boot sequence early with detailed logs.
- Redis Caching: Geolocation queries and public user profiles are cached with flexible TTL windows.
- MongoDB Indexes: Essential fields like
User.currentLocation(2dsphere geospatial index),BuddyScoreLog.userId,RefreshToken.token, andGroup.statusare indexed for fast read times. - Queue Processing: Slow external operations (such as sending emails, uploading profile photos, or syncing cloud CDNs) are handled out-of-band by asynchronous worker threads (
BullMQ) backed by Redis.