System Design
Architecture overview, service boundaries, and request flow through The Care Nexus platform.
The Care Nexus is designed as a three-tier web application following a clean client-server separation. The frontend (Next.js) and backend (Express.js) are deployed independently, communicate via a versioned REST API, and share a Socket.IO connection for real-time features. This separation allows the frontend to be deployed on Vercel's global edge network while the backend runs on a persistent Node.js server on Render or Railway.
Architecture Layers
Client Layer
Three logical portals (Doctor, Patient, Clinic Admin) are all served from the same Next.js application using App Router route groups. Each portal has its own layout with role-protected routing. Pages use React Server Components where possible for SEO and fast initial load, with Client Components for interactive sections (dashboards, forms, real-time UI).
API Gateway Layer
The Express.js server acts as the single entry point for all client requests. It handles authentication via JWT middleware, routes requests to the appropriate controller, and manages the Socket.IO server on the same HTTP server instance. The API follows RESTful conventions with a /api/v1/ prefix structure. CORS is configured to accept requests only from the whitelisted frontend URL.
Service Layer
Business logic is organized into controller modules per domain: auth, doctor, patient, clinic, ai, chat, notification. Controllers call service modules (email, AI, notification) which abstract third-party API interactions. This keeps controllers thin and services testable.
Data Layer
MongoDB Atlas serves as the primary datastore via Mongoose ODM. Upstash Redis handles session storage (JWT refresh tokens), rate limiting state, and the last-50-messages chat cache. Redis is accessed via the official Upstash REST SDK which works in serverless and edge environments without persistent connections.
Real-Time Architecture
Socket.IO is initialized on the same HTTP server instance as Express. The socket server maintains in-memory maps of userId-to-socketId to enable direct user targeting (notifications, chat messages). When a user connects, their userId is extracted from the auth token sent during the handshake and stored in the map. On disconnect, the entry is removed.
| Concern | Solution |
|---|---|
| Horizontal scaling | Redis pub/sub adapter for Socket.IO (multi-instance support) |
| Chat history load | REST API initial load + Socket.IO live updates |
| Offline notifications | DB-persisted notifications fetched on reconnect |
| Rate limiting | Redis sliding window counter per userId |
Monorepo structure
The client/ and api/ directories exist in a single repository but are deployed independently. Vercel handles frontend deployment, while Render handles backend deployment. This keeps development simple while allowing scalable production separation.