# amansinghy30/ai-resume-platform architecture

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

- Interactive diagram: https://gitdiagram.com/amansinghy30/ai-resume-platform
- Repository: https://github.com/amansinghy30/ai-resume-platform

## Overview

1. **Repository shape**
   - This is a split-client/server application. The `client/` folder is a React + TypeScript SPA, and `server/` is an Express/Node API with MongoDB persistence.
   - The root also contains a saved n8n workflow export (`Job Matching Workflow (1).json`), which is part of the automation layer rather than the main app runtime.

2. **Primary user-facing app**
   - The frontend is centered around a hiring workflow UI: landing, auth, dashboard, jobs, candidates, rankings, shortlisted, uploads, activity, and detail pages.
   - Routes are likely protected after login via `ProtectedRoute`, with public entry points for `Landing`, `Login`, and `Register`.

3. **Frontend state and layout boundaries**
   - `AuthContext` owns session/login state; `ThemeContext` owns dark/light mode persistence.
   - The UI is composed from reusable presentational pieces in `components/` such as tables, cards, badges, score widgets, nav/sidebar/layout shells, forms, and loading states.
   - Page components in `pages/` assemble these into feature screens rather than containing low-level network logic.

4. **Frontend data access layer**
   - Network calls are isolated in `client/src/services/`, with separate service modules for auth, candidates, jobs, dashboard, and activity.
   - This creates a clean boundary between the UI and the backend API, making the pages thin consumers of domain-specific endpoints.

5. **Backend API structure**
   - The server is organized by domain: `auth`, `candidates`, `jobs`, `dashboard`, `activity`, and `ai`.
   - Controllers contain the business logic, routes expose REST endpoints, and middleware handles cross-cutting concerns like JWT auth, file uploads, error handling, and 404s.

6. **Data model boundary**
   - MongoDB/Mongoose models represent the core entities: `User`, `Job`, `Candidate`, and `ActivityLog`.
   - These collections are the system of record for candidate intake, job definitions, scoring results, and audit/activity history.

7. **Resume ingestion and parsing pipeline**
   - PDF resume uploads enter through the backend upload middleware (`multer`-style handling), then are parsed with utilities such as `pdfParser`, `contactExtractor`, `skillExtractor`, and `backfillParsing`.
   - The parsed text is turned into structured candidate data before being stored or further analyzed, which is the main ingestion boundary in the system.

8. **AI scoring and enrichment path**
   - The server’s AI utilities (`aiClient`, `prompts`, `parseJSON`) indicate a structured prompt/response pipeline around Gemini AI.
   - Candidate data is transformed into richer outputs: match score, strengths, concerns, skill matches, missing requirements, and likely shortlist/reject decisions.
   - The `aiController` and `ai` route form the API boundary for this scoring/enrichment flow.

9. **Automation and external workflow integration**
   - The project integrates with n8n through `n8nClient` and the exported workflow JSON, suggesting an asynchronous automation layer outside the core API.
   - The README describes conditional branching for acceptance/rejection emails, so email outreach is handled as an external workflow rather than inside the main Express request path.

10. **Activity logging and event visibility**
   - Activity is treated as a first-class subsystem: `activityLogger`, `ActivityLog` model, and `activity` routes support a feed in the UI.
   - MongoDB Change Streams are used to detect document updates and emit log entries automatically, so auditing is event-driven rather than manually written at every UI action.

11. **Main end-to-end flow**
   - A typical flow is: user logs in → uploads a resume → backend parses PDF → AI scores candidate against a selected job → candidate record is updated → n8n may send email → Change Stream writes an activity event → frontend refreshes dashboard/activity/candidate views.
   - That makes the system a pipeline from file ingestion to structured candidate intelligence and operational follow-up.

12. **Operational/support pieces**
   - `seed.js` and `migrateUserData.js` suggest setup and maintenance scripts for initial data and schema evolution.
   - `dashboardController` and `dashboardService` indicate an aggregated metrics layer for totals, shortlisted counts, pending review, and active jobs, rather than computing everything in the client.

Main entry points: [`server/index.js`](https://github.com/amansinghy30/ai-resume-platform/blob/main/server/index.js) (API entry), [`server/models/Candidate.js`](https://github.com/amansinghy30/ai-resume-platform/blob/main/server/models/Candidate.js) (Data models), [`server/controllers/candidateController.js`](https://github.com/amansinghy30/ai-resume-platform/blob/main/server/controllers/candidateController.js) (Candidate API), [`client/src/pages/Dashboard.tsx`](https://github.com/amansinghy30/ai-resume-platform/blob/main/client/src/pages/Dashboard.tsx) (Work pages)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_client["Client"]
  node_app_shell["App shell<br/>spa router<br/>[App.tsx]"]
  node_auth_ctx(("Auth state<br/>context<br/>[AuthContext.tsx]"))
  node_theme_ctx(("Theme state<br/>context<br/>[ThemeContext.tsx]"))
  node_public_pages["Public pages<br/>[Landing.tsx]"]
  node_workspace_pages["Work pages<br/>[Dashboard.tsx]"]
  node_protect_route{{"Protected route<br/>guard<br/>[ProtectedRoute.tsx]"}}
  node_layout_ui["Layout UI<br/>shell components<br/>[Layout.tsx]"]
  node_feature_ui["Feature UI<br/>presentational components<br/>[CandidateTable.tsx]"]
  node_api_services["Client API<br/>service layer<br/>[api.ts]"]
end

subgraph group_server["Server"]
  node_server_entry["API entry<br/>express app<br/>[index.js]"]
  node_auth_api["Auth API<br/>controller+route<br/>[authController.js]"]
  node_candidate_api["Candidate API<br/>controller+route"]
  node_job_api["Jobs API<br/>controller+route<br/>[jobController.js]"]
  node_dashboard_api["Dashboard API<br/>controller+route"]
  node_activity_api["Activity API<br/>route<br/>[activity.js]"]
  node_ai_api["AI API<br/>controller+route<br/>[aiController.js]"]
  node_upload_pipe["Upload pipeline<br/>middleware+parsing<br/>[upload.js]"]
  node_ai_pipeline["AI pipeline<br/>utils<br/>[aiClient.js]"]
  node_activity_system["Activity system<br/>logging<br/>[activityLogger.js]"]
  node_data_models[("Data models<br/>mongoose models<br/>[Candidate.js]")]
end

subgraph group_automation["Automation"]
  node_n8n_workflow["n8n workflow<br/>automation export"]
end

node_app_shell -->|"routes to"| node_public_pages
node_app_shell -->|"guards"| node_protect_route
node_protect_route -->|"allows"| node_workspace_pages
node_auth_ctx -->|"drives access"| node_protect_route
node_theme_ctx -->|"styles"| node_layout_ui
node_workspace_pages -->|"compose with"| node_layout_ui
node_workspace_pages -->|"use"| node_feature_ui
node_feature_ui -->|"fetch via"| node_api_services
node_api_services -->|"calls"| node_server_entry
node_server_entry -->|"mounts"| node_auth_api
node_server_entry -->|"mounts"| node_candidate_api
node_server_entry -->|"mounts"| node_job_api
node_server_entry -->|"mounts"| node_dashboard_api
node_server_entry -->|"mounts"| node_activity_api
node_server_entry -->|"mounts"| node_ai_api
node_candidate_api -->|"ingests"| node_upload_pipe
node_candidate_api -->|"scores with"| node_ai_pipeline
node_candidate_api -->|"persists to"| node_data_models
node_auth_api -->|"reads/writes"| node_data_models
node_job_api -->|"reads/writes"| node_data_models
node_dashboard_api -->|"aggregates"| node_data_models
node_activity_api -->|"reads"| node_activity_system
node_activity_system -->|"writes"| node_data_models
node_ai_pipeline -->|"branches to"| node_n8n_workflow
node_activity_system -.->|"triggers"| node_n8n_workflow

click node_app_shell "https://github.com/amansinghy30/ai-resume-platform/blob/main/client/src/App.tsx"
click node_auth_ctx "https://github.com/amansinghy30/ai-resume-platform/blob/main/client/src/context/AuthContext.tsx"
click node_theme_ctx "https://github.com/amansinghy30/ai-resume-platform/blob/main/client/src/context/ThemeContext.tsx"
click node_public_pages "https://github.com/amansinghy30/ai-resume-platform/blob/main/client/src/pages/Landing.tsx"
click node_workspace_pages "https://github.com/amansinghy30/ai-resume-platform/blob/main/client/src/pages/Dashboard.tsx"
click node_protect_route "https://github.com/amansinghy30/ai-resume-platform/blob/main/client/src/components/ProtectedRoute.tsx"
click node_layout_ui "https://github.com/amansinghy30/ai-resume-platform/blob/main/client/src/components/Layout.tsx"
click node_feature_ui "https://github.com/amansinghy30/ai-resume-platform/blob/main/client/src/components/CandidateTable.tsx"
click node_api_services "https://github.com/amansinghy30/ai-resume-platform/blob/main/client/src/services/api.ts"
click node_server_entry "https://github.com/amansinghy30/ai-resume-platform/blob/main/server/index.js"
click node_auth_api "https://github.com/amansinghy30/ai-resume-platform/blob/main/server/controllers/authController.js"
click node_candidate_api "https://github.com/amansinghy30/ai-resume-platform/blob/main/server/controllers/candidateController.js"
click node_job_api "https://github.com/amansinghy30/ai-resume-platform/blob/main/server/controllers/jobController.js"
click node_dashboard_api "https://github.com/amansinghy30/ai-resume-platform/blob/main/server/controllers/dashboardController.js"
click node_activity_api "https://github.com/amansinghy30/ai-resume-platform/blob/main/server/routes/activity.js"
click node_ai_api "https://github.com/amansinghy30/ai-resume-platform/blob/main/server/controllers/aiController.js"
click node_upload_pipe "https://github.com/amansinghy30/ai-resume-platform/blob/main/server/middleware/upload.js"
click node_ai_pipeline "https://github.com/amansinghy30/ai-resume-platform/blob/main/server/utils/aiClient.js"
click node_activity_system "https://github.com/amansinghy30/ai-resume-platform/blob/main/server/utils/activityLogger.js"
click node_data_models "https://github.com/amansinghy30/ai-resume-platform/blob/main/server/models/Candidate.js"
click node_n8n_workflow "https://github.com/amansinghy30/ai-resume-platform/blob/main/Job Matching Workflow (1).json"

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_app_shell,node_auth_ctx,node_theme_ctx,node_public_pages,node_workspace_pages,node_protect_route,node_layout_ui,node_feature_ui,node_api_services toneBlue
class node_server_entry,node_auth_api,node_candidate_api,node_job_api,node_dashboard_api,node_activity_api,node_ai_api,node_upload_pipe,node_ai_pipeline,node_activity_system,node_data_models toneAmber
class node_n8n_workflow toneMint
```

## Components

### Client

React + TypeScript SPA for hiring workflow and candidate management.

- [App shell](https://github.com/amansinghy30/ai-resume-platform/blob/main/client/src/App.tsx): spa router · Top-level client routing and application composition. · `client/src/App.tsx`
- [Auth state](https://github.com/amansinghy30/ai-resume-platform/blob/main/client/src/context/AuthContext.tsx): context · Session and login state for protected areas. · `client/src/context/AuthContext.tsx`
- [Theme state](https://github.com/amansinghy30/ai-resume-platform/blob/main/client/src/context/ThemeContext.tsx): context · Light/dark theme persistence and toggling. · `client/src/context/ThemeContext.tsx`
- [Public pages](https://github.com/amansinghy30/ai-resume-platform/blob/main/client/src/pages/Landing.tsx): pages · Landing, login, and registration entry points. · `client/src/pages/Landing.tsx`
- [Work pages](https://github.com/amansinghy30/ai-resume-platform/blob/main/client/src/pages/Dashboard.tsx): pages · Dashboard, jobs, candidates, rankings, shortlisted, upload, activity, and detail views. · `client/src/pages/Dashboard.tsx`
- [Protected route](https://github.com/amansinghy30/ai-resume-platform/blob/main/client/src/components/ProtectedRoute.tsx): guard · Route gate for authenticated application areas. · `client/src/components/ProtectedRoute.tsx`
- [Layout UI](https://github.com/amansinghy30/ai-resume-platform/blob/main/client/src/components/Layout.tsx): shell components · Navbar, sidebar, and layout scaffolding for the SPA. · `client/src/components/Layout.tsx`
- [Feature UI](https://github.com/amansinghy30/ai-resume-platform/blob/main/client/src/components/CandidateTable.tsx): presentational components · Tables, cards, badges, search, filters, scores, forms, and loading states. · `client/src/components/CandidateTable.tsx`
- [Client API](https://github.com/amansinghy30/ai-resume-platform/blob/main/client/src/services/api.ts): service layer · Domain-specific client calls for auth, candidates, jobs, dashboard, and activity. · `client/src/services/api.ts`

### Server

Express API with MongoDB persistence, AI scoring, and activity logging.

- [API entry](https://github.com/amansinghy30/ai-resume-platform/blob/main/server/index.js): express app · Server bootstrap and middleware wiring. · `server/index.js`
- [Auth API](https://github.com/amansinghy30/ai-resume-platform/blob/main/server/controllers/authController.js): controller+route · Login, registration, and JWT session handling. · `server/controllers/authController.js`
- [Candidate API](https://github.com/amansinghy30/ai-resume-platform/blob/main/server/controllers/candidateController.js): controller+route · Candidate intake, retrieval, and scoring-related operations. · `server/controllers/candidateController.js`
- [Jobs API](https://github.com/amansinghy30/ai-resume-platform/blob/main/server/controllers/jobController.js): controller+route · Job definitions and job detail endpoints. · `server/controllers/jobController.js`
- [Dashboard API](https://github.com/amansinghy30/ai-resume-platform/blob/main/server/controllers/dashboardController.js): controller+route · Aggregated counts, shortlist metrics, and review status data. · `server/controllers/dashboardController.js`
- [Activity API](https://github.com/amansinghy30/ai-resume-platform/blob/main/server/routes/activity.js): route · Activity feed endpoints for audit and visibility. · `server/routes/activity.js`
- [AI API](https://github.com/amansinghy30/ai-resume-platform/blob/main/server/controllers/aiController.js): controller+route · Candidate enrichment and scoring endpoints. · `server/controllers/aiController.js`
- [Upload pipeline](https://github.com/amansinghy30/ai-resume-platform/blob/main/server/middleware/upload.js): middleware+parsing · Resume upload handling and PDF-to-text parsing boundary. · `server/middleware/upload.js`
- [AI pipeline](https://github.com/amansinghy30/ai-resume-platform/blob/main/server/utils/aiClient.js): utils · Prompting, Gemini client, and JSON response parsing for candidate enrichment. · `server/utils/aiClient.js`
- [Activity system](https://github.com/amansinghy30/ai-resume-platform/blob/main/server/utils/activityLogger.js): logging · Activity log writer and change-stream driven event visibility. · `server/utils/activityLogger.js`
- [Data models](https://github.com/amansinghy30/ai-resume-platform/blob/main/server/models/Candidate.js): mongoose models · User, Job, Candidate, and ActivityLog collections. · `server/models/Candidate.js`

### Automation

External workflow export and integration layer for follow-up actions.

- [n8n workflow](https://github.com/amansinghy30/ai-resume-platform/blob/HEAD/Job%20Matching%20Workflow%20(1).json): automation export · Saved workflow export for branching follow-up automation. · `Job Matching Workflow (1).json`

## Connections

- App shell → Public pages: routes to · Public entry screens are mounted from the app router.
- App shell → Protected route: guards · Authenticated areas are wrapped by the protected route boundary.
- Protected route → Work pages: allows · Protected navigation leads into the main app screens.
- Auth state → Protected route: drives access · Session state determines whether protected routes render.
- Theme state → Layout UI: styles · Theme state affects shared UI shell rendering.
- Work pages → Layout UI: compose with · Feature screens are assembled inside the common layout.
- Work pages → Feature UI: use · Pages rely on reusable presentational widgets.
- Feature UI → Client API: fetch via · UI components consume data through service modules.
- Client API → API entry: calls · Client requests are sent to the Express API.
- API entry → Auth API: mounts · Authentication routes and controller logic are exposed here.
- API entry → Candidate API: mounts · Candidate domain endpoints are exposed here.
- API entry → Jobs API: mounts · Job domain endpoints are exposed here.
- API entry → Dashboard API: mounts · Dashboard aggregation endpoints are exposed here.
- API entry → Activity API: mounts · Activity feed endpoints are exposed here.
- API entry → AI API: mounts · AI scoring and enrichment endpoints are exposed here.
- Candidate API → Upload pipeline: ingests · Resume uploads are parsed before candidate records are updated.
- Candidate API → AI pipeline: scores with · Candidate data is enriched through the AI prompt/response pipeline.
- Candidate API → Data models: persists to · Candidate records are stored in MongoDB.
- Auth API → Data models: reads/writes · User accounts are managed in MongoDB.
- Jobs API → Data models: reads/writes · Job definitions are stored in MongoDB.
- Dashboard API → Data models: aggregates · Dashboard metrics are computed from stored domain records.
- Activity API → Activity system: reads · Feed entries come from the logging subsystem.
- Activity system → Data models: writes · Activity events are persisted as log documents.
- AI pipeline → n8n workflow: branches to · Enrichment can hand off to external automation for follow-up actions.
- Activity system → n8n workflow: triggers · Automation may emit outreach or status-change follow-ups.
