# abrartoha/educonnect architecture

> Architecture diagram of the GitHub repository abrartoha/educonnect, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-27). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/abrartoha/educonnect
- Repository: https://github.com/abrartoha/educonnect

## Overview

1. **Repository shape**
   EduConnect is a monorepo with three user-facing runtimes and one shared backend: `server/` for the API, `client/` for the web SPA, and `mobile/` for the Expo app. The web and mobile apps both consume the same backend API rather than talking directly to the database.

2. **Backend as the system of record**
   The `server/` workspace is the architectural center. It is a Node 20 + Express application using Prisma to persist data in PostgreSQL. All core business state lives here: users, profiles, posts, marketplace listings, leads/enquiries, campaigns, reviews, and admin operations.

3. **Module boundaries on the server**
   The backend is split by feature area under `server/src/modules/`: `auth`, `posts`, `directory`, `business`, and `admin`. Each module has controllers, routes, and schemas, which makes the API surface explicit and keeps feature logic separated. The directory and business modules are especially important because they power the marketplace and enquiry workflows.

4. **Data access and schema layer**
   Prisma is the persistence boundary. `server/prisma/schema.prisma` defines the domain model, while migrations show the evolution of features such as universities, meetings, messaging, and later simplification/removal of some of those models. This indicates the architecture is database-first with generated typed access through Prisma rather than ad hoc SQL.

5. **Authentication and session model**
   Authentication is handled on the server with JWTs, cookies, CSRF protection, password hashing, and shared auth middleware. The repo uses both access/refresh token helpers and cookie utilities, so the system is designed around browser sessions rather than pure bearer-token APIs. Role-based access is a first-class concern because the app serves students, universities, agents, consultants, and admins.

6. **Primary user flows**
   The most important product flows are feed/posts, marketplace browsing, role dashboards, and enquiry submission. Students can create and browse posts, explore directory listings for universities/agents/consultants, and contact a listing owner. Recipients can then review leads from their dashboards and update status through the backend.

7. **Email-backed enquiries**
   A key architectural feature is the enquiry pipeline. When a student submits an enquiry, the server persists a `Lead` record and sends an email via `nodemailer` to the recipient, with the student as reply-to. In production this uses configured SMTP; in development it falls back to Ethereal preview URLs, so the email service is part of the core product flow rather than a peripheral notification layer.

8. **Scheduled background jobs**
   `server/src/jobs/cron.js` introduces background processing for cleanup and lifecycle automation, including token cleanup and campaign auto-ending. This means some domain transitions happen asynchronously rather than only during request/response cycles.

9. **Web client architecture**
   The `client/` workspace is a React 19 + Vite SPA with React Router and Zustand. It is organized by page and component categories: landing pages, feed, marketplace, auth, dashboards, admin, and static/legal pages. The client is responsible for rendering the public marketing site plus authenticated role-specific UI.

10. **Client-server integration**
   The web app has a dedicated API layer under `client/src/api/` with endpoint definitions, mappers, and an API client, plus a `useApiResource` hook for data fetching. That separation suggests the UI consumes a normalized backend contract and then adapts raw API responses into view-friendly shapes. The store folder handles auth hydration and shared state across the SPA.

11. **Mobile app parity**
   The `mobile/` workspace mirrors much of the client’s domain structure: feed, marketplace, business, profile, admin, posts, and auth. It uses React Navigation with auth and main stacks, and stores auth tokens in AsyncStorage. This indicates the mobile app is a parallel client of the same backend, not a separate product with its own data model.

12. **Shared domain surfaces across clients**
   Both clients expose the same core product concepts—feed/posts, directory listings, dashboards, and enquiries—but with different UI stacks. The mobile app has a slightly more compact feature set and native navigation, while the web app includes richer landing pages, admin screens, and an exploratory campus experience under `client/src/pages/explore/`.

13. **Deployment and runtime boundaries**
   The repository includes containerization artifacts for both server and client, plus a Vercel config for the web app and a GitHub Actions deploy workflow. The practical runtime split is: Express API on port 5050, web SPA on 5173 in dev, and Expo Metro for mobile. PostgreSQL is an external infrastructure dependency required by the backend.

14. **Cross-cutting concerns**
   Shared server middleware covers CORS, CSRF, security headers, rate limiting, validation, and centralized error handling. Those concerns define the trust boundary between clients and the API, and they are part of the architecture diagram because they sit in front of every feature module.

15. **How to draw the diagram**
   A good architecture diagram should place PostgreSQL and email delivery as external dependencies behind the server, with the server in the center exposing role-aware API routes. The web SPA and mobile app should be shown as separate consumers of the same API, while background cron jobs attach to the server/database side for asynchronous maintenance.

Main entry points: [`server/prisma/schema.prisma`](https://github.com/abrartoha/educonnect/blob/main/server/prisma/schema.prisma) (Prisma Schema), [`server/src/modules/index.js`](https://github.com/abrartoha/educonnect/blob/main/server/src/modules/index.js) (Modules), [`mobile/App.js`](https://github.com/abrartoha/educonnect/blob/main/mobile/App.js) (Mobile Shell), [`server/src/modules/business/campaigns.controller.js`](https://github.com/abrartoha/educonnect/blob/main/server/src/modules/business/campaigns.controller.js) (Business)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_server["Server"]
  node_server_app["API App<br/>express app<br/>[app.js]"]
  node_server_routes["Modules<br/>[index.js]"]
  node_server_auth["Auth<br/>[auth.controller.js]"]
  node_server_posts["Posts"]
  node_server_directory["Directory"]
  node_server_business["Business"]
  node_server_admin["Admin"]
  node_server_prisma[("Prisma Schema<br/>data model<br/>[schema.prisma]")]
  node_server_cron["Cron Jobs<br/>background jobs<br/>[cron.js]"]
  node_server_middleware{{"Security Layer<br/>shared middleware<br/>[auth.js]"}}
end

subgraph group_client["Web SPA"]
  node_client_app["Web SPA<br/>react app<br/>[App.jsx]"]
  node_client_api["API Layer<br/>client api<br/>[client.js]"]
  node_client_store["Store<br/>zustand state<br/>[useStore.js]"]
  node_client_pages["Pages<br/>route views<br/>[Landing.jsx]"]
end

subgraph group_mobile["Mobile App"]
  node_mobile_app["Mobile Shell<br/>expo app<br/>[App.js]"]
  node_mobile_nav["Navigator<br/>nav stacks<br/>[RootNavigator.js]"]
  node_mobile_api["API Layer<br/>mobile api<br/>[client.js]"]
  node_mobile_auth["Auth State<br/>auth storage<br/>[AuthContext.js]"]
  node_mobile_screens["Screens<br/>native views<br/>[FeedScreen.js]"]
end

subgraph group_infra["External Infra"]
  node_server_email["Email Service<br/>nodemailer service"]
  node_db[("PostgreSQL<br/>database")]
end

node_server_app -->|"uses"| node_server_middleware
node_server_app -->|"mounts"| node_server_routes
node_server_routes -->|"exposes"| node_server_auth
node_server_routes -->|"exposes"| node_server_posts
node_server_routes -->|"exposes"| node_server_directory
node_server_routes -->|"exposes"| node_server_business
node_server_routes -->|"exposes"| node_server_admin
node_server_auth -->|"reads/writes"| node_server_prisma
node_server_posts -->|"reads/writes"| node_server_prisma
node_server_directory -->|"reads/writes"| node_server_prisma
node_server_business -->|"reads/writes"| node_server_prisma
node_server_admin -->|"reads/writes"| node_server_prisma
node_server_business -->|"sends"| node_server_email
node_server_cron -->|"maintains"| node_server_prisma
node_server_prisma -->|"persists"| node_db
node_client_app -->|"uses"| node_client_api
node_client_app -->|"shares state"| node_client_store
node_client_app -->|"renders"| node_client_pages
node_client_api -->|"calls"| node_server_app
node_mobile_app -->|"uses"| node_mobile_nav
node_mobile_app -->|"uses"| node_mobile_api
node_mobile_app -->|"shares state"| node_mobile_auth
node_mobile_app -->|"renders"| node_mobile_screens
node_mobile_api -->|"calls"| node_server_app
node_mobile_auth -->|"supports"| node_server_auth
node_server_business -.->|"depends on"| node_server_directory

click node_server_app "https://github.com/abrartoha/educonnect/blob/main/server/src/app.js"
click node_server_routes "https://github.com/abrartoha/educonnect/blob/main/server/src/modules/index.js"
click node_server_auth "https://github.com/abrartoha/educonnect/blob/main/server/src/modules/auth/auth.controller.js"
click node_server_posts "https://github.com/abrartoha/educonnect/blob/main/server/src/modules/posts/posts.controller.js"
click node_server_directory "https://github.com/abrartoha/educonnect/blob/main/server/src/modules/directory/directory.controller.js"
click node_server_business "https://github.com/abrartoha/educonnect/blob/main/server/src/modules/business/campaigns.controller.js"
click node_server_admin "https://github.com/abrartoha/educonnect/blob/main/server/src/modules/admin/admin.controller.js"
click node_server_prisma "https://github.com/abrartoha/educonnect/blob/main/server/prisma/schema.prisma"
click node_server_cron "https://github.com/abrartoha/educonnect/blob/main/server/src/jobs/cron.js"
click node_server_middleware "https://github.com/abrartoha/educonnect/blob/main/server/src/shared/middleware/auth.js"
click node_client_app "https://github.com/abrartoha/educonnect/blob/main/client/src/App.jsx"
click node_client_api "https://github.com/abrartoha/educonnect/blob/main/client/src/api/client.js"
click node_client_store "https://github.com/abrartoha/educonnect/blob/main/client/src/store/useStore.js"
click node_client_pages "https://github.com/abrartoha/educonnect/blob/main/client/src/pages/Landing.jsx"
click node_mobile_app "https://github.com/abrartoha/educonnect/blob/main/mobile/App.js"
click node_mobile_nav "https://github.com/abrartoha/educonnect/blob/main/mobile/src/navigation/RootNavigator.js"
click node_mobile_api "https://github.com/abrartoha/educonnect/blob/main/mobile/src/api/client.js"
click node_mobile_auth "https://github.com/abrartoha/educonnect/blob/main/mobile/src/auth/AuthContext.js"
click node_mobile_screens "https://github.com/abrartoha/educonnect/blob/main/mobile/src/screens/feed/FeedScreen.js"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_server_app,node_server_routes,node_server_auth,node_server_posts,node_server_directory,node_server_business,node_server_admin,node_server_prisma,node_server_cron,node_server_middleware toneBlue
class node_client_app,node_client_api,node_client_store,node_client_pages toneAmber
class node_mobile_app,node_mobile_nav,node_mobile_api,node_mobile_auth,node_mobile_screens toneMint
class node_server_email,node_db toneRose
```

## Components

### Server

Express API, Prisma persistence, shared middleware, and scheduled jobs.

- [API App](https://github.com/abrartoha/educonnect/blob/main/server/src/app.js): express app · Bootstraps the Node API and wires modules and middleware. · `server/src/app.js`
- [Modules](https://github.com/abrartoha/educonnect/blob/main/server/src/modules/index.js): api modules · Feature-sliced route surface for auth, posts, directory, business, and admin. · `server/src/modules/index.js`
- [Auth](https://github.com/abrartoha/educonnect/blob/main/server/src/modules/auth/auth.controller.js): auth module · Login, signup, tokens, cookies, and session handling. · `server/src/modules/auth/auth.controller.js`
- [Posts](https://github.com/abrartoha/educonnect/blob/main/server/src/modules/posts/posts.controller.js): posts module · Feed and post lifecycle APIs. · `server/src/modules/posts/posts.controller.js`
- [Directory](https://github.com/abrartoha/educonnect/blob/main/server/src/modules/directory/directory.controller.js): directory module · Profiles and marketplace directory APIs for universities and advisors. · `server/src/modules/directory/directory.controller.js`
- [Business](https://github.com/abrartoha/educonnect/blob/main/server/src/modules/business/campaigns.controller.js): business module · Leads, campaigns, and reviews workflows for recipient dashboards. · `server/src/modules/business/campaigns.controller.js`
- [Admin](https://github.com/abrartoha/educonnect/blob/main/server/src/modules/admin/admin.controller.js): admin module · Administrative management APIs for platform oversight. · `server/src/modules/admin/admin.controller.js`
- [Prisma Schema](https://github.com/abrartoha/educonnect/blob/main/server/prisma/schema.prisma): data model · Domain model and generated database access boundary. · `server/prisma/schema.prisma`
- [Cron Jobs](https://github.com/abrartoha/educonnect/blob/main/server/src/jobs/cron.js): background jobs · Asynchronous cleanup and lifecycle automation. · `server/src/jobs/cron.js`
- [Security Layer](https://github.com/abrartoha/educonnect/blob/main/server/src/shared/middleware/auth.js): shared middleware · CORS, CSRF, auth, validation, security headers, rate limits, and errors. · `server/src/shared/middleware/auth.js`

### Web SPA

React/Vite browser client with pages, UI composition, and API integration.

- [Web SPA](https://github.com/abrartoha/educonnect/blob/main/client/src/App.jsx): react app · Browser client for landing pages, dashboards, marketplace, and admin UI. · `client/src/App.jsx`
- [API Layer](https://github.com/abrartoha/educonnect/blob/main/client/src/api/client.js): client api · Endpoint definitions, response mappers, and API client wrapper. · `client/src/api/client.js`
- [Store](https://github.com/abrartoha/educonnect/blob/main/client/src/store/useStore.js): zustand state · Shared auth and UI state hydration for the SPA. · `client/src/store/useStore.js`
- [Pages](https://github.com/abrartoha/educonnect/blob/main/client/src/pages/Landing.jsx): route views · Landing, feed, marketplace, dashboards, auth, static, and explore screens. · `client/src/pages/Landing.jsx`

### Mobile App

Expo/React Native client with navigation, screens, and local auth storage.

- [Mobile Shell](https://github.com/abrartoha/educonnect/blob/main/mobile/App.js): expo app · React Native app shell with navigation and app bootstrap. · `mobile/App.js`
- [Navigator](https://github.com/abrartoha/educonnect/blob/main/mobile/src/navigation/RootNavigator.js): nav stacks · Auth and main navigation stacks for native routing. · `mobile/src/navigation/RootNavigator.js`
- [API Layer](https://github.com/abrartoha/educonnect/blob/main/mobile/src/api/client.js): mobile api · Endpoint definitions, mappers, and API client for the shared backend. · `mobile/src/api/client.js`
- [Auth State](https://github.com/abrartoha/educonnect/blob/main/mobile/src/auth/AuthContext.js): auth storage · Token persistence and auth context for native sessions. · `mobile/src/auth/AuthContext.js`
- [Screens](https://github.com/abrartoha/educonnect/blob/main/mobile/src/screens/feed/FeedScreen.js): native views · Feed, marketplace, business, posts, profile, admin, auth, and dashboard screens. · `mobile/src/screens/feed/FeedScreen.js`

### External Infra

Database and email delivery services used by the backend.

- **Email Service**: nodemailer service · Sends enquiry emails and development previews.
- **PostgreSQL**: database · System of record for users, posts, listings, leads, campaigns, and related state.

## Connections

- API App → Security Layer: uses · All requests pass through shared security and validation controls.
- API App → Modules: mounts · The app composes the feature route modules.
- Modules → Auth: exposes · Authentication endpoints.
- Modules → Posts: exposes · Feed and post endpoints.
- Modules → Directory: exposes · Directory and profile endpoints.
- Modules → Business: exposes · Lead, campaign, and review endpoints.
- Modules → Admin: exposes · Admin endpoints.
- Auth → Prisma Schema: reads/writes · User accounts, sessions, and auth-related records.
- Posts → Prisma Schema: reads/writes · Post and feed state.
- Directory → Prisma Schema: reads/writes · Profiles and marketplace listings.
- Business → Prisma Schema: reads/writes · Leads, campaigns, and reviews.
- Admin → Prisma Schema: reads/writes · Administrative data operations.
- Business → Email Service: sends · Enquiry notifications to listing owners.
- Cron Jobs → Prisma Schema: maintains · Cleans up tokens and closes campaigns.
- Prisma Schema → PostgreSQL: persists · Prisma stores the domain model in PostgreSQL.
- Web SPA → API Layer: uses · The SPA talks to the backend through its API layer.
- Web SPA → Store: shares state · Authentication and UI state are centralized in the store.
- Web SPA → Pages: renders · Pages provide the major user-facing surfaces.
- API Layer → API App: calls · Web client requests the shared backend API.
- Mobile Shell → Navigator: uses · Native app bootstraps through the navigator.
- Mobile Shell → API Layer: uses · Mobile client talks to the same backend API.
- Mobile Shell → Auth State: shares state · Tokens and auth context are managed locally.
- Mobile Shell → Screens: renders · Screens implement the main native experiences.
- API Layer → API App: calls · Mobile client consumes the shared backend API.
- Auth State → Auth: supports · Native login and session flows depend on server auth.
- Business → Directory: depends on · Marketplace enquiries connect directory listings to leads.
