|
1 | | -`TODO: Add a nice screenshot of the app!` |
| 1 | +# StudyBridge |
2 | 2 |
|
3 | | -# Cohort XX final project |
| 3 | +## Overview |
4 | 4 |
|
5 | | -This is the final project for the HackYourFuture curriculum we did as a cohort using the [MERN stack](https://www.mongodb.com/resources/languages/mern-stack) by following the agile methodology with our team and a group of mentors. A quick guide to what we built: |
| 5 | +StudyBridge is a full-stack educational platform that connects students and teachers in one ecosystem. |
| 6 | +The application is designed to simplify the process of finding a tutor, booking lessons, managing communication, and organizing the learning workflow in real time. |
6 | 7 |
|
7 | | -> TODO: Add short description of the app |
| 8 | +The platform supports two main user journeys: |
8 | 9 |
|
9 | | -`[Click here for the Demo version](TODO: add link)` |
| 10 | +- **Student flow** - search for teachers, view profiles, create lesson appointments, communicate with tutors, receive notifications, and join online lessons |
| 11 | +- **Teacher flow** - create and manage a professional profile, receive and process appointment requests, communicate with students, manage regular learners, and conduct online lessons |
10 | 12 |
|
11 | | -## 1. Setup |
| 13 | +In addition, the platform includes moderation flows that help keep content structured and the teacher approval process controlled. |
12 | 14 |
|
13 | | -First, to setup all the directories run the following in the main directory: |
| 15 | +StudyBridge is built as a modern full-stack application with strong attention to architecture, scalability, and real user interaction. The project combines a React-based client application with a Node.js backend, |
| 16 | +real-time features via WebSockets, structured backend layering with CQRS, dependency injection, and TypeScript across the stack. |
14 | 17 |
|
15 | | -`npm install` |
| 18 | +--- |
16 | 19 |
|
17 | | -`npm run setup` |
| 20 | +## Tech Stack |
18 | 21 |
|
19 | | -The first command will install `cypress` and some small libraries needed for running the rest of the commands. The second will go into the `client` and `server` directories and set those up to be ran. |
| 22 | +### Core stack |
| 23 | +- **MERN** |
| 24 | +- **TypeScript** |
| 25 | +- **CQRS** |
| 26 | +- **Dependency Injection** |
20 | 27 |
|
21 | | -In the `client` and `server` directory there are two `.env.example` files. Create a copy and rename that to `.env`. Then follow the instructions in those files to fill in the right values. |
| 28 | +### Frontend |
| 29 | +- **React** |
| 30 | +- **React Router** |
| 31 | +- **TanStack Query (React Query)** |
| 32 | +- **Zustand** |
| 33 | +- **Socket.IO Client** |
| 34 | +- **Tailwind CSS** |
| 35 | +- **Framer Motion** |
| 36 | +- **Axios** |
22 | 37 |
|
23 | | -To run the app in dev mode you can run the following command in the main directory: |
| 38 | +### Backend |
| 39 | +- **Node.js** |
| 40 | +- **Express** |
| 41 | +- **Socket.IO** |
| 42 | +- **MongoDB** |
| 43 | +- **Mongoose** |
| 44 | +- **InversifyJS** |
24 | 45 |
|
25 | | -`npm run dev` |
| 46 | +### Tooling |
| 47 | +- **ESLint** |
| 48 | +- **Prettier** |
| 49 | +- **Husky** |
| 50 | +- **npm** |
26 | 51 |
|
27 | | -## 2. Code structure |
| 52 | +--- |
28 | 53 |
|
29 | | -``` |
30 | | -client |
31 | | -├── public |
32 | | -└── src |
33 | | -| └── __tests__ |
34 | | -| └── __testUtils__ |
35 | | -| └── components |
36 | | -| └── hooks |
37 | | -| └── pages |
38 | | -| └── __tests__ |
39 | | -| └── components |
40 | | -| └── util |
41 | | -| index.jsx |
42 | | -cypress |
43 | | -| └── fixtures |
44 | | -| └── integration |
45 | | -| └── plugins |
46 | | -| └── support |
47 | | -server |
48 | | -└── src |
49 | | - └── __tests__ |
50 | | - └── __testUtils__ |
51 | | - └── controllers |
52 | | - └── db |
53 | | - └── models |
54 | | - └── routes |
55 | | - └── util |
56 | | - index.ts |
57 | | -``` |
| 54 | +## Full Stack Description |
| 55 | + |
| 56 | +### MERN |
| 57 | +StudyBridge follows the **MERN** stack architecture: |
| 58 | + |
| 59 | +- **MongoDB** for storing users, appointments, conversations, messages, notifications, and related entities |
| 60 | +- **Express** for building the backend API and request handling |
| 61 | +- **React** for the client-side user interface |
| 62 | +- **Node.js** as the server runtime |
| 63 | + |
| 64 | +### TypeScript |
| 65 | +TypeScript is used across both frontend and backend to ensure strong typing, safer refactoring, and better maintainability. This helps reduce runtime errors and improves developer experience. |
| 66 | + |
| 67 | +### CQRS |
| 68 | +The backend uses **CQRS (Command Query Responsibility Segregation)**: |
| 69 | + |
| 70 | +- **Command repositories** are responsible for create, update, and delete operations |
| 71 | +- **Query repositories** are responsible for read operations |
| 72 | + |
| 73 | +This separation makes the backend more scalable and keeps business logic organized. |
| 74 | + |
| 75 | +### Dependency Injection |
| 76 | +The backend uses **InversifyJS** for dependency injection. |
| 77 | +This allows services, repositories, and controllers to stay decoupled and easier to test. |
| 78 | + |
| 79 | +### Real-time communication |
| 80 | +**Socket.IO** powers the real-time features of the platform: |
| 81 | + |
| 82 | +- live chat messaging |
| 83 | +- typing indicators |
| 84 | +- unread message counters |
| 85 | +- online presence tracking |
| 86 | +- incoming call events |
| 87 | +- live notifications |
| 88 | + |
| 89 | +### State management |
| 90 | +The frontend clearly separates responsibilities between: |
| 91 | + |
| 92 | +- **React Query** for server state |
| 93 | +- **Zustand** for client-side and UI state |
| 94 | + |
| 95 | +This keeps the application predictable and easier to manage as it grows. |
| 96 | + |
| 97 | +--- |
| 98 | + |
| 99 | +## Features |
| 100 | + |
| 101 | +### Authentication and authorization |
| 102 | +- Student and teacher registration |
| 103 | +- Secure login flow |
| 104 | +- Access token and refresh token handling |
| 105 | +- Protected routes |
| 106 | +- Role-based access control |
| 107 | +- Session restore and logout flow |
| 108 | + |
| 109 | +### Teacher discovery |
| 110 | +- Browse teacher profiles |
| 111 | +- View lesson details, pricing, and profile information |
| 112 | +- Search and filtering |
| 113 | +- Teacher profile editing |
| 114 | + |
| 115 | +### Appointment management |
| 116 | +- Create lesson appointments |
| 117 | +- Approve or reject lesson requests |
| 118 | +- Track appointment statuses |
| 119 | +- Manage regular students |
| 120 | +- Support recurring weekly schedules |
| 121 | + |
| 122 | +### Real-time chat |
| 123 | +- One chat per teacher-student pair |
| 124 | +- Real-time messaging |
| 125 | +- Typing indicators |
| 126 | +- Online presence |
| 127 | +- Unread message counters |
| 128 | +- Read/unread synchronization |
| 129 | + |
| 130 | +### Notifications |
| 131 | +- Real-time notifications for new messages |
| 132 | +- Notifications for appointment approval or rejection |
| 133 | +- Persistent notifications stored in database |
| 134 | +- Mark one as read |
| 135 | +- Clear read notifications |
| 136 | + |
| 137 | +### Video calls |
| 138 | +- Online lesson calls |
| 139 | +- Incoming call popup |
| 140 | +- Join links for specific calls |
| 141 | +- Teacher-student live communication flow |
| 142 | + |
| 143 | +### Moderation |
| 144 | +- Teacher moderation workflow |
| 145 | +- Status management |
| 146 | +- Restricted moderator routes |
58 | 147 |
|
59 | | -### 2.1 Client structure |
| 148 | +--- |
60 | 149 |
|
61 | | -- `public` || public facing client code |
62 | | -- `__tests__` || any `jest` tests for specific components will be in a `__tests__` folder on the same level |
63 | | -- `__testUtils__` || any code that is only being used in the tests is put in the `__testUtils__` folder to separate that away from the rest of the code |
64 | | -- `components` || all of our shared components that are used over multiple pages |
65 | | -- `hooks` || all of our custom hooks |
66 | | -- `pages` || the page components of our app, any routing will go between these components |
67 | | -- `pages/components` || components used specifically on those pages |
68 | | -- `util` || any utility functions that can be used anywhere on the client side |
69 | | -- `main.tsx` || the start point of the client |
70 | | -- `vite.config.ts` || to configure vite |
| 150 | +## Screenshots |
71 | 151 |
|
72 | | -### 2.2 Cypress structure |
| 152 | +### Home page |
| 153 | + |
73 | 154 |
|
74 | | -- `fixtures` || any data/files that `cypress` needs can be placed here |
75 | | -- `integration` || all of our tests are in here, separated in folders based on the pages in our app |
76 | | -- `plugins` || any plugins for our `cypress` configuration can be placed here |
77 | | -- `support` || custom commands and other support files for `cypress` can be placed here |
| 155 | +### Teachers list |
| 156 | + |
78 | 157 |
|
79 | | -### 2.3 Server structure |
| 158 | +### Teacher profile |
| 159 | + |
80 | 160 |
|
81 | | -- `__tests__` || any `jest` tests for the api endpoints as that is our testing strategy for the backend |
82 | | -- `__testUtils__` || any code that is only being used in the tests is put in the `__testUtils__` folder to separate that away from the rest of the code |
83 | | -- `controllers` || all of our controller functions that interact with the database |
84 | | -- `db` || all of our configuration for the database |
85 | | -- `models` || all of our `mongoose` models will be placed here |
86 | | -- `routes` || code to match up the API with our controllers |
87 | | -- `util` || any utility functions that can be used anywhere on the server side |
88 | | -- `index.ts` || the start point of the server |
| 161 | +### Appointments |
| 162 | + |
89 | 163 |
|
90 | | -## 3. Stack / external libraries |
| 164 | +--- |
91 | 165 |
|
92 | | -The base stack of the app is a MERN stack (Mongoose, Express, React, Node). Next to that we make use of the following extras: |
| 166 | +## Architecture |
93 | 167 |
|
94 | | -### 3.1 Configuration libraries |
| 168 | +StudyBridge is structured as a layered full-stack application. |
95 | 169 |
|
96 | | -- `dotenv` || To load the .env variables into the process environment. See [docs](https://www.npmjs.com/package/dotenv) |
97 | | -- `vite` || To bundle our React app and create a static app to host. See [docs](https://vite.dev/) |
98 | | -- `husky` || To run our tests and linter before committing. See [docs](https://typicode.github.io/husky/#/) |
99 | | -- `eslint` || To check our code. We have different configurations for frontend and backend. You can check out the configuration in the `.eslintrc.(c)js` files in the respective `client` and `server` folders. See [docs](https://eslint.org/) |
100 | | -- `prettier` || To automatically format our code. See [docs](https://prettier.io/) |
101 | | -- `concurrently` || To run commands in parallel. See [docs](https://github.com/open-cli-tools/concurrently#readme) |
| 170 | +### Frontend architecture |
| 171 | +The frontend is built as a React SPA with a modular structure. |
102 | 172 |
|
103 | | -For more information on how these work together including the automatic deployment to heroku, have a look at our detailed [DEV](./DEV.md) file. |
| 173 | +Main responsibilities are split into: |
| 174 | +- **Pages** for route-level UI |
| 175 | +- **Components** for reusable UI blocks |
| 176 | +- **Features** for domain-specific logic |
| 177 | +- **Hooks** for reusable behavior |
| 178 | +- **Stores** for client-side state |
| 179 | +- **API layer** for backend communication |
104 | 180 |
|
105 | | -### 3.2 Client-side libraries |
| 181 | +### Backend architecture |
| 182 | +The backend is divided into clear layers: |
106 | 183 |
|
107 | | -- `@testing-library/*` || We use React Testing Library to write all of our tests. See [docs](https://testing-library.com/docs/react-testing-library/intro/) |
108 | | -- `jest` || To run our tests and coverage. See [docs](https://jestjs.io/) |
109 | | -- `jest-fetch-mock` || To mock out the backend for our testing purposes. See [docs](https://github.com/jefflau/jest-fetch-mock#readme) |
| 184 | +- **Controllers** — handle HTTP requests and responses |
| 185 | +- **Services** — contain business logic |
| 186 | +- **Command repositories** — handle write operations |
| 187 | +- **Query repositories** — handle read operations |
| 188 | +- **Schemas/models** — define persistence layer |
| 189 | +- **Socket handlers** — manage real-time events |
| 190 | + |
| 191 | +This structure helps keep the codebase maintainable and scalable. |
| 192 | + |
| 193 | +--- |
| 194 | + |
| 195 | +## Why this project is technically interesting |
| 196 | + |
| 197 | +StudyBridge is more than a simple CRUD application. |
| 198 | +It combines several real-world product requirements in one system: |
| 199 | + |
| 200 | +- authentication with refresh flow |
| 201 | +- role-based access control |
| 202 | +- real-time messaging |
| 203 | +- persistent notifications |
| 204 | +- appointment approval workflow |
| 205 | +- online presence tracking |
| 206 | +- video call integration |
| 207 | +- CQRS-based backend architecture |
| 208 | +- dependency injection |
| 209 | + |
| 210 | +The project demonstrates how to build a production-style platform with real-time communication and maintainable architecture. |
| 211 | + |
| 212 | +--- |
| 213 | + |
| 214 | +## Project Goal |
| 215 | + |
| 216 | +The goal of StudyBridge is to provide a convenient and structured environment where: |
| 217 | + |
| 218 | +- students can quickly find suitable teachers |
| 219 | +- teachers can present their expertise and manage their work |
| 220 | +- both sides can communicate smoothly in one application |
| 221 | + |
| 222 | +The platform is designed to reduce friction in online learning by combining search, booking, messaging, and lesson management in a single place. |
| 223 | + |
| 224 | +--- |
| 225 | + |
| 226 | +## Folder Structure |
| 227 | + |
| 228 | +### Client |
| 229 | +```bash |
| 230 | +client/ |
| 231 | + src/ |
| 232 | + api/ |
| 233 | + components/ |
| 234 | + features/ |
| 235 | + hooks/ |
| 236 | + layouts/ |
| 237 | + pages/ |
| 238 | + router/ |
| 239 | + store/ |
| 240 | + types/ |
| 241 | + util/ |
| 242 | + |
| 243 | +server/ |
| 244 | + src/ |
| 245 | + composition/ |
| 246 | + controllers/ |
| 247 | + db/ |
| 248 | + repositories/ |
| 249 | + commandRepositories/ |
| 250 | + queryRepositories/ |
| 251 | + routes/ |
| 252 | + services/ |
| 253 | + socket/ |
| 254 | + types/ |
| 255 | + utils/ |
| 256 | + validation/ |
| 257 | +``` |
| 258 | +## How to run locally |
| 259 | + |
| 260 | +## Clone repository |
| 261 | +```bash |
| 262 | +git clone <your-repository-url> |
| 263 | +cd StudyBridge |
| 264 | +``` |
| 265 | + |
| 266 | +## Install dependencies |
| 267 | +```bash |
| 268 | +npm install |
| 269 | +cd client && npm install |
| 270 | +cd ../server && npm install |
| 271 | +``` |
| 272 | +## Start the development servers |
| 273 | + |
| 274 | +```bash |
| 275 | +cd client |
| 276 | +npm run dev |
| 277 | +``` |
| 278 | +## Open the application |
| 279 | +```bash |
| 280 | +http://localhost:5173 |
| 281 | +``` |
110 | 282 |
|
111 | | -### 3.3 Server-side libraries |
112 | 283 |
|
113 | | -- `nodemon` || To automatically restart the server when in development mode. See [docs](https://nodemon.io/) |
114 | | -- `jest` || To run our tests and coverage. See [docs](https://jestjs.io/) |
115 | | -- `supertest` || To more easily test our endpoints. See [docs](https://github.com/visionmedia/supertest#readme) |
116 | | -- `mongodb-memory-server` || To mock out our database in our backend tests. See [docs](https://github.com/nodkz/mongodb-memory-server) |
117 | | -- `cors` || To open up our API. See [docs](https://github.com/expressjs/cors#readme) |
118 | | -- `mongoose` || To add schemas to our database. See [docs](https://mongoosejs.com/) |
|
0 commit comments