Architecture Overview
Relevant source files
The following files were used as context for generating this wiki page:
This document provides a technical overview of the CDIO4 project's architecture. The project is a full-stack web application built using the REMN stack: ReactJS, Express.js, MongoDB, and Node.js. It is structured as a monorepo with distinct frontend and backend directories, facilitating parallel development and clear separation of concerns.
The architecture is designed for scalability and maintainability, with the frontend acting as a client-side Single Page Application (SPA) that communicates with a backend REST API. The backend handles business logic, data persistence, and authentication, while the frontend is responsible for user interface and experience.
High-Level Architecture
The project is organized into two primary components: a React-based frontend and an Express.js backend. A root package.json uses the concurrently library to run both the client and server development environments simultaneously with a single command.
Sources: README.md:12-29, package.json:7-9
The following diagram illustrates the high-level interaction between the system's components.
Project Scripts
The root package.json defines scripts to manage the entire application lifecycle.
| Script | Description |
|---|---|
dev | Runs both the backend and frontend servers in development mode using concurrently. |
server | Navigates to the backend directory and runs its dev script (nodemon src/server.js). |
client | Navigates to the frontend directory and runs its start script (react-scripts start). |
install-all | Installs dependencies for the root, backend, and frontend projects. |
Sources: package.json:6-12
Backend Architecture
The backend is a Node.js application using the Express.js framework. It serves as a REST API for the frontend, handling data processing, business logic, and communication with the MongoDB database.
Sources: backend/src/server.js, backend/package.json
Server Entry Point (server.js)
The main entry point for the backend is backend/src/server.js. Its responsibilities include:
- Initialization: Sets up the Express application.
- Database Connection: Connects to a MongoDB instance using Mongoose, configured via environment variables (
MONGODB_URI). - Middleware Configuration:
cors: Enables Cross-Origin Resource Sharing for requests from the frontend URL.express.json: Parses incoming JSON payloads.express.urlencoded: Parses URL-encoded payloads.
- API Route Registration: Mounts various API route handlers under specific paths like
/api/auth,/api/taikhoan, and/api/thietbi. - Server Start: Listens for incoming connections on the configured port (
BACKEND_PORTor default 5000).
Sources: backend/src/server.js:5-88
The diagram below shows the request flow within the backend.
Sources: backend/src/server.js:40-54, 82-84
API Endpoints
The server exposes several API endpoints. The main routes are registered in server.js.
| Path | Description | Source File |
|---|---|---|
/users | GET and POST endpoints for retrieving and creating users (defined directly in server.js). | backend/src/server.js:57-79 |
/api/auth | Handles authentication-related logic (e.g., login, registration). | backend/src/server.js:82 |
/api/taikhoan | Manages user accounts. | backend/src/server.js:83 |
/api/thietbi | Manages IoT devices. | backend/src/server.js:84 |
Database Model (User.js)
Data structures are defined using Mongoose schemas. The User model is a key example, defining the schema for user documents in the database.
The User schema includes fields for name, email, password, role, and timestamps. It also contains important security features and helper methods.
Sources: backend/src/models/User.js
The following diagram represents the User schema.
Key features of the User model include:
- Password Hashing: A
pre('save')middleware automatically hashes the user's password usingbcryptjsbefore saving it to the database. The password field is also configured withselect: falseto prevent it from being returned in queries by default. - Password Comparison: An instance method
comparePasswordis available to safely compare a candidate password with the stored hash. - Indexes: The schema defines indexes on
email,createdAt, andisActiveto optimize query performance.
Sources: backend/src/models/User.js:71-84, 93-95, 111-113
Frontend Architecture
The frontend is a Single Page Application (SPA) built with React. It is responsible for rendering the user interface and interacting with the backend API to fetch and display data.
Sources: frontend/src/App.js, frontend/package.json
Application Entry Point (index.js)
The application's entry point is frontend/src/index.js. It renders the main App component into the <div id="root"></div> element in public/index.html.
It also wraps the App component with several context providers for global state management:
BrowserRouter: Enables client-side routing viareact-router-dom.AuthProvider: Manages user authentication state.ThemeProvider: Manages the application's theme (e.g., light/dark mode).
Sources: frontend/src/index.js:11-23, frontend/public/index.html:18
Routing (App.js)
Routing is managed by react-router-dom in the App.js component. The application defines three main categories of routes:
- Public Routes: Accessible to all users (e.g.,
/,/signin,/register). - Protected Routes: Require user authentication. These are wrapped in a
<ProtectedRoute />component. - Admin Routes: Require administrator privileges. These are wrapped in a
<RequireAdmin />component.
Sources: frontend/src/App.js:25-58
The routing structure is visualized below.
Sources: frontend/src/App.js:25-58
Layout Components
The application uses Layout and LayoutAdmin components to provide a consistent structure for protected pages. These components typically include a fixed sidebar and a top navigation bar, with the page-specific content rendered via the <Outlet /> component from react-router-dom. This ensures a consistent user experience across different sections of the application.
Sources: frontend/src/components/common/Layout.js:11-40, frontend/src/components/common/LayoutAdmin.js:11-40
Conclusion
The CDIO4 project employs a modern, decoupled architecture that separates frontend and backend concerns. The monorepo structure, managed with concurrently, streamlines the development workflow. The backend provides a secure REST API using Express.js and Mongoose, while the React frontend delivers a dynamic and responsive user experience with client-side routing and global state management. This architecture is well-suited for building and maintaining a scalable, feature-rich web application.