# jainikbhandari/resumeiq architecture

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

- Interactive diagram: https://gitdiagram.com/jainikbhandari/resumeiq
- Repository: https://github.com/jainikbhandari/resumeiq

## Overview

1. **Overall shape**
   ResumeIQ is a two-tier MERN application: a React/Vite single-page app in `client/` talks to an Express API in `server/`, and the backend persists users and resume reports in MongoDB Atlas. The frontend and backend are deployed separately, so the main architecture boundary is the REST API.

2. **Frontend entry and shell**
   The client boots from `main.jsx`, renders `App.jsx`, and uses React Router to switch between public pages and authenticated dashboard pages. The page set includes login/register/reset-password flows plus the protected product areas: upload, result, dashboard, and history.

3. **Frontend state and auth boundary**
   Authentication is centralized in `context/AuthContext.jsx` plus the `useAuth` hook, with route gating handled by `ProtectedRoute.jsx`. This is the client-side boundary that decides whether a user can enter the dashboard/history/result surfaces or must be redirected to login.

4. **Client API layer**
   All backend communication is funneled through the small API layer in `src/api/axios.js` and `src/api/config.js`. That keeps the UI components and pages separated from backend URLs and request wiring, which matters for the diagram as the client does not directly embed business logic.

5. **Public auth flows**
   The auth pages (`Login`, `Register`, `ForgotPassword`, `ResetPassword`) use the auth API to create accounts, sign users in, support Google login, and run password reset email/token flows. `GoogleAuthButton` is the client entry point for OAuth login, while `auth.js` in utils likely provides token/session helpers.

6. **Resume upload and analysis flow**
   The main product flow starts on `UploadResume.jsx`: the user submits a PDF and optional job/role context. The backend accepts the multipart upload, extracts PDF text, scores the resume, runs Gemini-based analysis, generates interview questions and job-match insights, then returns a structured report that is shown in `Result.jsx` and persisted for history.

7. **Backend request pipeline**
   `server/app.js` is the composition root: it connects Express routes, database initialization, middleware, and likely CORS/body parsing. Requests are split into `authRoutes.js` and `resumeRoutes.js`, with `authMiddleware.js` protecting all user-specific resume endpoints and `uploadMiddleware.js` handling PDF file ingestion.

8. **Backend domain controllers**
   `controllers/authController.js` owns registration, login, Google token verification, profile lookup, forgot/reset password, and JWT issuance. `controllers/resumeController.js` owns upload, analysis orchestration, history retrieval, single-report fetch, and deletion. This is the main separation between identity logic and resume-processing logic.

9. **Processing and AI services**
   The resume analysis pipeline is decomposed into service-like utilities: `utils/atsScoring.js` for deterministic ATS-style scoring, `utils/gemini.js` for LLM-generated analysis, and `utils/sendEmail.js` for password-reset mail. This separation keeps the controller layer thin and makes the AI/scoring logic reusable across requests.

10. **Persistence model**
   MongoDB is modeled with `models/User.js` and `models/Resume.js`. User records support authentication and recovery data, while resume records store per-user analysis results so the history page can list, reopen, and delete previous reports independently for each account.

11. **User-facing dashboard features**
   The dashboard area is composed from reusable UI pieces such as `Navbar`, `AppLoader`, and `GoogleAuthButton`, plus pages for `Dashboard`, `History`, and `Result`. The app also includes accessibility and usability features like read-aloud, report PDF download, light/dark mode, and mobile bottom navigation, all driven from the frontend layer.

12. **External services and deployment**
   The backend depends on MongoDB Atlas, Google OAuth, Gemini API, and SMTP email delivery; the frontend is a static SPA hosted on Vercel, and the API is hosted on Render. Environment variables are therefore a critical architectural boundary: the client only needs the API base URL and Google client ID, while the server owns database, JWT, Gemini, OAuth, and email secrets.

13. **Data flow summary**
   The typical end-to-end path is: browser login/session state → protected dashboard → PDF upload to Express → auth/file middleware → PDF text extraction and scoring/LLM analysis → MongoDB persistence → response rendering in the client → optional history lookup, deletion, or report download. That’s the key flow an architecture diagram should emphasize.

Main entry points: [`client/src/App.jsx`](https://github.com/jainikbhandari/resumeiq/blob/main/client/src/App.jsx) (App shell), [`client/src/api/axios.js`](https://github.com/jainikbhandari/resumeiq/blob/main/client/src/api/axios.js) (API layer), [`server/controllers/resumeController.js`](https://github.com/jainikbhandari/resumeiq/blob/main/server/controllers/resumeController.js) (Resume controller), [`server/app.js`](https://github.com/jainikbhandari/resumeiq/blob/main/server/app.js) (Express app)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_client["Client"]
  node_client_main(("Main<br/>entry<br/>[main.jsx]"))
  node_client_app["App shell<br/>router shell<br/>[App.jsx]"]
  node_client_auth["Auth context<br/>state/auth<br/>[AuthContext.jsx]"]
  node_client_route_guard["Protected route<br/>route guard<br/>[ProtectedRoute.jsx]"]
  node_client_api["API layer<br/>http client<br/>[axios.js]"]
  node_client_login["Login<br/>auth page<br/>[Login.jsx]"]
  node_client_register["Register<br/>auth page<br/>[Register.jsx]"]
  node_client_reset["Password reset<br/>auth flow<br/>[ForgotPassword.jsx]"]
  node_client_upload["Upload resume<br/>product page<br/>[UploadResume.jsx]"]
  node_client_result["Result view<br/>product page<br/>[Result.jsx]"]
  node_client_dashboard["Dashboard<br/>product page<br/>[Dashboard.jsx]"]
  node_client_history["History<br/>product page<br/>[History.jsx]"]
end

subgraph group_server["Server"]
  node_server_app["Express app<br/>api root<br/>[app.js]"]
  node_server_routes_auth["Auth routes<br/>route module<br/>[authRoutes.js]"]
  node_server_routes_resume["Resume routes<br/>route module<br/>[resumeRoutes.js]"]
  node_server_auth_controller["Auth controller<br/>[authController.js]"]
  node_server_resume_controller["Resume controller"]
  node_server_auth_mw["Auth middleware<br/>[authMiddleware.js]"]
  node_server_upload_mw["Upload middleware"]
  node_server_db[("Database config<br/>db init<br/>[db.js]")]
  node_server_user_model[("User model<br/>mongoose model<br/>[User.js]")]
  node_server_resume_model[("Resume model<br/>mongoose model<br/>[Resume.js]")]
  node_server_ats["ATS scoring<br/>analysis util<br/>[atsScoring.js]"]
  node_server_gemini["Gemini analysis<br/>ai util<br/>[gemini.js]"]
  node_server_email["Email service<br/>mail util<br/>[sendEmail.js]"]
end

subgraph group_external["External services"]
  node_ext_mongo[("MongoDB Atlas<br/>database service")]
  node_ext_google{{"Google OAuth<br/>identity service"}}
  node_ext_gemini{{"Gemini API<br/>LLM service"}}
  node_ext_smtp{{"SMTP provider<br/>email service"}}
  node_ext_vercel{{"Vercel<br/>hosting"}}
  node_ext_render{{"Render<br/>hosting"}}
end

node_client_main -->|"renders"| node_client_app
node_client_app -->|"uses"| node_client_auth
node_client_app -->|"protects"| node_client_route_guard
node_client_app -->|"routes to"| node_client_login
node_client_app -->|"routes to"| node_client_register
node_client_app -->|"routes to"| node_client_reset
node_client_app -->|"routes to"| node_client_upload
node_client_app -->|"routes to"| node_client_result
node_client_app -->|"routes to"| node_client_dashboard
node_client_app -->|"routes to"| node_client_history
node_client_login -->|"calls"| node_client_api
node_client_register -->|"calls"| node_client_api
node_client_reset -->|"calls"| node_client_api
node_client_upload -->|"submits"| node_client_api
node_client_result -->|"fetches"| node_client_api
node_client_history -->|"lists"| node_client_api
node_client_auth -->|"attaches"| node_client_api
node_server_app -->|"mounts"| node_server_routes_auth
node_server_app -->|"mounts"| node_server_routes_resume
node_server_app -->|"connects"| node_server_db
node_server_routes_auth -->|"delegates"| node_server_auth_controller
node_server_routes_resume -->|"guards"| node_server_auth_mw
node_server_routes_resume -->|"ingests"| node_server_upload_mw
node_server_routes_resume -->|"delegates"| node_server_resume_controller
node_server_auth_controller -->|"reads/writes"| node_server_user_model
node_server_auth_controller -->|"verifies"| node_ext_google
node_server_auth_controller -->|"sends"| node_server_email
node_server_email -->|"uses"| node_ext_smtp
node_server_resume_controller -->|"scores"| node_server_ats
node_server_resume_controller -->|"analyzes"| node_server_gemini
node_server_resume_controller -->|"reads/writes"| node_server_resume_model
node_server_resume_controller -->|"associates"| node_server_user_model
node_server_db -->|"connects to"| node_ext_mongo
node_server_user_model -->|"persists to"| node_ext_mongo
node_server_resume_model -->|"persists to"| node_ext_mongo
node_server_gemini -->|"calls"| node_ext_gemini
node_client_app -.->|"deployed on"| node_ext_vercel
node_server_app -.->|"deployed on"| node_ext_render

click node_client_main "https://github.com/jainikbhandari/resumeiq/blob/main/client/src/main.jsx"
click node_client_app "https://github.com/jainikbhandari/resumeiq/blob/main/client/src/App.jsx"
click node_client_auth "https://github.com/jainikbhandari/resumeiq/blob/main/client/src/context/AuthContext.jsx"
click node_client_route_guard "https://github.com/jainikbhandari/resumeiq/blob/main/client/src/components/ProtectedRoute.jsx"
click node_client_api "https://github.com/jainikbhandari/resumeiq/blob/main/client/src/api/axios.js"
click node_client_login "https://github.com/jainikbhandari/resumeiq/blob/main/client/src/pages/Login.jsx"
click node_client_register "https://github.com/jainikbhandari/resumeiq/blob/main/client/src/pages/Register.jsx"
click node_client_reset "https://github.com/jainikbhandari/resumeiq/blob/main/client/src/pages/ForgotPassword.jsx"
click node_client_upload "https://github.com/jainikbhandari/resumeiq/blob/main/client/src/pages/UploadResume.jsx"
click node_client_result "https://github.com/jainikbhandari/resumeiq/blob/main/client/src/pages/Result.jsx"
click node_client_dashboard "https://github.com/jainikbhandari/resumeiq/blob/main/client/src/pages/Dashboard.jsx"
click node_client_history "https://github.com/jainikbhandari/resumeiq/blob/main/client/src/pages/History.jsx"
click node_server_app "https://github.com/jainikbhandari/resumeiq/blob/main/server/app.js"
click node_server_routes_auth "https://github.com/jainikbhandari/resumeiq/blob/main/server/routes/authRoutes.js"
click node_server_routes_resume "https://github.com/jainikbhandari/resumeiq/blob/main/server/routes/resumeRoutes.js"
click node_server_auth_controller "https://github.com/jainikbhandari/resumeiq/blob/main/server/controllers/authController.js"
click node_server_resume_controller "https://github.com/jainikbhandari/resumeiq/blob/main/server/controllers/resumeController.js"
click node_server_auth_mw "https://github.com/jainikbhandari/resumeiq/blob/main/server/middleware/authMiddleware.js"
click node_server_upload_mw "https://github.com/jainikbhandari/resumeiq/blob/main/server/middleware/uploadMiddleware.js"
click node_server_db "https://github.com/jainikbhandari/resumeiq/blob/main/server/config/db.js"
click node_server_user_model "https://github.com/jainikbhandari/resumeiq/blob/main/server/models/User.js"
click node_server_resume_model "https://github.com/jainikbhandari/resumeiq/blob/main/server/models/Resume.js"
click node_server_ats "https://github.com/jainikbhandari/resumeiq/blob/main/server/utils/atsScoring.js"
click node_server_gemini "https://github.com/jainikbhandari/resumeiq/blob/main/server/utils/gemini.js"
click node_server_email "https://github.com/jainikbhandari/resumeiq/blob/main/server/utils/sendEmail.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_client_main,node_client_app,node_client_auth,node_client_route_guard,node_client_api,node_client_login,node_client_register,node_client_reset,node_client_upload,node_client_result,node_client_dashboard,node_client_history toneBlue
class node_server_app,node_server_routes_auth,node_server_routes_resume,node_server_auth_controller,node_server_resume_controller,node_server_auth_mw,node_server_upload_mw,node_server_db,node_server_user_model,node_server_resume_model,node_server_ats,node_server_gemini,node_server_email toneAmber
class node_ext_mongo,node_ext_google,node_ext_gemini,node_ext_smtp,node_ext_vercel,node_ext_render toneMint
```

## Components

### Client

React/Vite single-page app and UI flows

- [Main](https://github.com/jainikbhandari/resumeiq/blob/main/client/src/main.jsx): entry · Bootstraps the React app and renders the root shell · `client/src/main.jsx`
- [App shell](https://github.com/jainikbhandari/resumeiq/blob/main/client/src/App.jsx): router shell · Defines the application routes and page composition · `client/src/App.jsx`
- [Auth context](https://github.com/jainikbhandari/resumeiq/blob/main/client/src/context/AuthContext.jsx): state/auth · Central client-side auth state and session handling · `client/src/context/AuthContext.jsx`
- [Protected route](https://github.com/jainikbhandari/resumeiq/blob/main/client/src/components/ProtectedRoute.jsx): route guard · Blocks dashboard areas unless the user is authenticated · `client/src/components/ProtectedRoute.jsx`
- [API layer](https://github.com/jainikbhandari/resumeiq/blob/main/client/src/api/axios.js): http client · Shared Axios configuration and backend endpoint wiring · `client/src/api/axios.js`
- [Login](https://github.com/jainikbhandari/resumeiq/blob/main/client/src/pages/Login.jsx): auth page · Signs users in and starts the session · `client/src/pages/Login.jsx`
- [Register](https://github.com/jainikbhandari/resumeiq/blob/main/client/src/pages/Register.jsx): auth page · Creates new user accounts · `client/src/pages/Register.jsx`
- [Password reset](https://github.com/jainikbhandari/resumeiq/blob/main/client/src/pages/ForgotPassword.jsx): auth flow · Forgot and reset password screens · `client/src/pages/ForgotPassword.jsx`
- [Upload resume](https://github.com/jainikbhandari/resumeiq/blob/main/client/src/pages/UploadResume.jsx): product page · Main intake screen for PDF upload and role context · `client/src/pages/UploadResume.jsx`
- [Result view](https://github.com/jainikbhandari/resumeiq/blob/main/client/src/pages/Result.jsx): product page · Displays analysis, score, and generated insights · `client/src/pages/Result.jsx`
- [Dashboard](https://github.com/jainikbhandari/resumeiq/blob/main/client/src/pages/Dashboard.jsx): product page · Authenticated landing area and summary surface · `client/src/pages/Dashboard.jsx`
- [History](https://github.com/jainikbhandari/resumeiq/blob/main/client/src/pages/History.jsx): product page · Lists prior reports for the current user · `client/src/pages/History.jsx`

### Server

Express API, middleware, controllers, and persistence

- [Express app](https://github.com/jainikbhandari/resumeiq/blob/main/server/app.js): api root · Composes middleware, routes, and database setup · `server/app.js`
- [Auth routes](https://github.com/jainikbhandari/resumeiq/blob/main/server/routes/authRoutes.js): route module · HTTP endpoints for sign-in, signup, profile, and recovery · `server/routes/authRoutes.js`
- [Resume routes](https://github.com/jainikbhandari/resumeiq/blob/main/server/routes/resumeRoutes.js): route module · HTTP endpoints for upload, report retrieval, history, and deletion · `server/routes/resumeRoutes.js`
- [Auth controller](https://github.com/jainikbhandari/resumeiq/blob/main/server/controllers/authController.js): controller · Registration, login, Google auth, profile, and password reset logic · `server/controllers/authController.js`
- [Resume controller](https://github.com/jainikbhandari/resumeiq/blob/main/server/controllers/resumeController.js): controller · Upload orchestration, analysis, persistence, history, and deletion · `server/controllers/resumeController.js`
- [Auth middleware](https://github.com/jainikbhandari/resumeiq/blob/main/server/middleware/authMiddleware.js): middleware · Verifies JWTs for user-specific resume endpoints · `server/middleware/authMiddleware.js`
- [Upload middleware](https://github.com/jainikbhandari/resumeiq/blob/main/server/middleware/uploadMiddleware.js): middleware · Handles multipart PDF ingestion · `server/middleware/uploadMiddleware.js`
- [Database config](https://github.com/jainikbhandari/resumeiq/blob/main/server/config/db.js): db init · Connects the API to MongoDB · `server/config/db.js`
- [User model](https://github.com/jainikbhandari/resumeiq/blob/main/server/models/User.js): mongoose model · Stores auth and recovery data · `server/models/User.js`
- [Resume model](https://github.com/jainikbhandari/resumeiq/blob/main/server/models/Resume.js): mongoose model · Stores per-user analysis reports and history · `server/models/Resume.js`
- [ATS scoring](https://github.com/jainikbhandari/resumeiq/blob/main/server/utils/atsScoring.js): analysis util · Deterministic resume scoring and rule-based checks · `server/utils/atsScoring.js`
- [Gemini analysis](https://github.com/jainikbhandari/resumeiq/blob/main/server/utils/gemini.js): ai util · LLM-backed resume insights and interview question generation · `server/utils/gemini.js`
- [Email service](https://github.com/jainikbhandari/resumeiq/blob/main/server/utils/sendEmail.js): mail util · Sends password-reset messages · `server/utils/sendEmail.js`

### External services

Managed services the app integrates with

- **MongoDB Atlas**: database service · Persistent storage for users and resume reports
- **Google OAuth**: identity service · Google sign-in and token verification
- **Gemini API**: LLM service · Generative analysis provider used by resume processing
- **SMTP provider**: email service · Outbound email transport for recovery flows
- **Vercel**: hosting · Static hosting for the client SPA
- **Render**: hosting · Hosting for the Express API

## Connections

- Main → App shell: renders · Application entry mounts the router shell
- App shell → Auth context: uses · Route and session decisions depend on auth state
- App shell → Protected route: protects · Authenticated sections are wrapped with route guarding
- App shell → Login: routes to · Public auth flow for sign-in
- App shell → Register: routes to · Public auth flow for account creation
- App shell → Password reset: routes to · Password recovery flow
- App shell → Upload resume: routes to · Primary resume submission screen
- App shell → Result view: routes to · Displays the generated report
- App shell → Dashboard: routes to · Authenticated landing area
- App shell → History: routes to · Report history surface
- Login → API layer: calls · Uses shared HTTP client for auth requests
- Register → API layer: calls · Uses shared HTTP client for signup requests
- Password reset → API layer: calls · Uses shared HTTP client for recovery requests
- Upload resume → API layer: submits · Uploads resume and context to the API
- Result view → API layer: fetches · Retrieves report data when needed
- History → API layer: lists · Loads prior reports from the API
- Auth context → API layer: attaches · Auth layer adds session-aware request handling
- Express app → Auth routes: mounts · Wires auth endpoints into the API
- Express app → Resume routes: mounts · Wires resume endpoints into the API
- Express app → Database config: connects · Initializes database connection on startup
- Auth routes → Auth controller: delegates · Auth requests are handled by the controller
- Resume routes → Auth middleware: guards · Protects user-scoped resume operations
- Resume routes → Upload middleware: ingests · Handles PDF multipart upload before processing
- Resume routes → Resume controller: delegates · Resume requests are handled by the controller
- Auth controller → User model: reads/writes · Creates and updates user records
- Auth controller → Google OAuth: verifies · Validates Google login tokens
- Auth controller → Email service: sends · Triggers password reset emails
- Email service → SMTP provider: uses · Relies on outbound mail transport
- Resume controller → ATS scoring: scores · Runs deterministic ATS-style evaluation
- Resume controller → Gemini analysis: analyzes · Calls LLM service for generated insights
- Resume controller → Resume model: reads/writes · Persists and retrieves resume reports
- Resume controller → User model: associates · Links reports to the authenticated user
- Database config → MongoDB Atlas: connects to · MongoDB Atlas stores application data
- User model → MongoDB Atlas: persists to · User documents live in MongoDB
- Resume model → MongoDB Atlas: persists to · Report documents live in MongoDB
- Gemini analysis → Gemini API: calls · Uses the Gemini API for generation
- App shell → Vercel: deployed on · Frontend SPA is hosted separately
- Express app → Render: deployed on · API service is hosted separately
