# srujanrana07/researchreach-a-cold-email-helper architecture

> Architecture diagram of the GitHub repository srujanrana07/researchreach-a-cold-email-helper, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-05-12). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/srujanrana07/researchreach-a-cold-email-helper
- Repository: https://github.com/srujanrana07/researchreach-a-cold-email-helper

## Overview

1. **Repository shape**
   - The repo is split into two top-level applications:
     - `app/`: a Python backend, likely a Flask service.
     - `front/`: a React single-page frontend.
   - There is no obvious database, message queue, or worker system in the file tree; the architecture appears **request-driven and stateless**.

2. **Frontend boundary**
   - `front/src/App.js` is the main client shell, with standard React bootstrap files in `index.js`, `index.css`, and test scaffolding.
   - The frontend’s role is to collect user input, display matched papers, and show generated email content or status.
   - It likely consumes backend HTTP endpoints directly; no separate frontend state service is visible.

3. **Backend entrypoint**
   - `app/app.py` is the backend entrypoint and likely exposes the API surface for the UI.
   - This is the orchestration layer: it would receive uploaded resumes or text, call the processing modules, and return ranked papers and email drafts.

4. **Resume ingestion and extraction**
   - `app/resume_processor.py` is the first major processing boundary.
   - Per the README, this stage extracts skills, projects, and other relevant text from resumes, likely from PDF input.
   - This module is the bridge between raw user documents and the semantic matching pipeline.

5. **Candidate text normalization**
   - The extracted resume content is condensed into a single “candidate profile text” used downstream.
   - This flattened text is important because it becomes the semantic input for similarity matching against paper text.

6. **Research paper acquisition**
   - `app/paper_retrieval.py` handles finding candidate papers.
   - The README indicates paper discovery via Semantic Scholar / web scraping, and possible access to full text via Unpaywall.
   - This is the external-data boundary: the backend depends on third-party scholarly APIs and web sources.

7. **Semantic matching**
   - `app/similarity.py` performs the core ranking logic.
   - The README specifies Sentence-BERT embeddings (`all-MiniLM-L6-v2`) and cosine similarity, so this module likely encodes both resume and paper text and scores their semantic closeness.
   - This is the primary ML/NLP subsystem in the repo.

8. **Email generation**
   - `app/email_generator.py` generates a cold email tailored to the selected paper and candidate profile.
   - The README says this uses Gemini, so this module is an LLM integration boundary that turns structured match results into prose.

9. **Email delivery**
   - `app/email_sender.py` is the outbound communication layer.
   - It likely sends the generated email through SMTP or a mail API, separating drafting from actual delivery.

10. **End-to-end data flow**
   - User interacts with the React UI → backend receives resume/input → resume text is extracted → papers are retrieved → resume and paper texts are embedded → cosine similarity ranks results → top match is returned → email draft is generated → optional email sending occurs.
   - The central artifact moving through the system is **text**, transformed progressively from document content into embeddings, scores, and finally an email.

11. **Testing and validation**
   - Backend-side testing appears in `app/test.py`.
   - Frontend tests are set up via `front/src/App.test.js` and `setupTests.js`.
   - This suggests the repo validates both the UI shell and backend logic, though no dedicated integration-test harness is visible.

12. **Operational characteristics**
   - Dependencies are managed separately with `app/requirements.txt` for Python and `front/package.json` / `package-lock.json` for React.
   - Because the visible architecture has no persistence layer, match results and generated emails are probably computed on demand rather than stored long-term.
   - External services materially affecting the design are: **Semantic Scholar**, **Unpaywall**, and **Gemini**.

Main entry points: [`app/app.py`](https://github.com/srujanrana07/researchreach-a-cold-email-helper/blob/main/app/app.py) (API app), [`app/paper_retrieval.py`](https://github.com/srujanrana07/researchreach-a-cold-email-helper/blob/main/app/paper_retrieval.py) (Paper search), [`app/email_generator.py`](https://github.com/srujanrana07/researchreach-a-cold-email-helper/blob/main/app/email_generator.py) (Email writer), [`front/src/App.js`](https://github.com/srujanrana07/researchreach-a-cold-email-helper/blob/main/front/src/App.js) (UI shell)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_frontend["Frontend"]
  node_front_app["UI shell<br/>React app<br/>[App.js]"]
  node_front_boot["Bootstrap<br/>React entry<br/>[index.js]"]
end

subgraph group_backend["Backend"]
  node_api_app["API app<br/>Flask service<br/>[app.py]"]
  node_resume_proc["Resume parser<br/>extraction"]
  node_paper_retrieval["Paper search<br/>retrieval<br/>[paper_retrieval.py]"]
  node_similarity{{"Matcher<br/>NLP ranking<br/>[similarity.py]"}}
  node_email_gen["Email writer<br/>LLM drafting<br/>[email_generator.py]"]
  node_email_send["Sender<br/>delivery<br/>[email_sender.py]"]
  node_candidate_text["Candidate text<br/>text artifact"]
  node_paper_text["Paper text<br/>text artifact"]
  node_ranked_papers[("Ranked papers<br/>result set")]
  node_email_draft["Email draft<br/>generated content"]
end

subgraph group_external["External services"]
  node_semantic_scholar(("Semantic Scholar<br/>external API"))
  node_unpaywall(("Unpaywall<br/>external API"))
  node_gemini(("Gemini<br/>LLM API"))
  node_smtp(("Mail service<br/>SMTP/API"))
end

node_front_boot -->|"boots"| node_front_app
node_front_app -->|"requests"| node_api_app
node_api_app -->|"parses resume"| node_resume_proc
node_resume_proc -->|"produces"| node_candidate_text
node_api_app -->|"finds papers"| node_paper_retrieval
node_paper_retrieval -->|"searches"| node_semantic_scholar
node_paper_retrieval -->|"fetches full text"| node_unpaywall
node_paper_retrieval -->|"produces"| node_paper_text
node_candidate_text -->|"scores against"| node_similarity
node_paper_text -->|"scores against"| node_similarity
node_similarity -->|"ranks"| node_ranked_papers
node_api_app -->|"drafts email"| node_email_gen
node_ranked_papers -->|"provides context"| node_email_gen
node_email_gen -->|"calls"| node_gemini
node_email_gen -->|"produces"| node_email_draft
node_email_draft -->|"sends"| node_email_send
node_email_send -->|"delivers via"| node_smtp
node_ranked_papers -->|"returns results"| node_front_app
node_email_draft -->|"returns draft"| node_front_app

click node_front_app "https://github.com/srujanrana07/researchreach-a-cold-email-helper/blob/main/front/src/App.js"
click node_front_boot "https://github.com/srujanrana07/researchreach-a-cold-email-helper/blob/main/front/src/index.js"
click node_api_app "https://github.com/srujanrana07/researchreach-a-cold-email-helper/blob/main/app/app.py"
click node_resume_proc "https://github.com/srujanrana07/researchreach-a-cold-email-helper/blob/main/app/resume_processor.py"
click node_paper_retrieval "https://github.com/srujanrana07/researchreach-a-cold-email-helper/blob/main/app/paper_retrieval.py"
click node_similarity "https://github.com/srujanrana07/researchreach-a-cold-email-helper/blob/main/app/similarity.py"
click node_email_gen "https://github.com/srujanrana07/researchreach-a-cold-email-helper/blob/main/app/email_generator.py"
click node_email_send "https://github.com/srujanrana07/researchreach-a-cold-email-helper/blob/main/app/email_sender.py"

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_front_app,node_front_boot toneBlue
class node_api_app,node_resume_proc,node_paper_retrieval,node_similarity,node_email_gen,node_email_send,node_candidate_text,node_paper_text,node_ranked_papers,node_email_draft toneAmber
class node_semantic_scholar,node_unpaywall,node_gemini,node_smtp toneMint
```

## Components

### Frontend

React single-page client

- [UI shell](https://github.com/srujanrana07/researchreach-a-cold-email-helper/blob/main/front/src/App.js): React app · Main client shell and user interaction surface · `front/src/App.js`
- [Bootstrap](https://github.com/srujanrana07/researchreach-a-cold-email-helper/blob/main/front/src/index.js): React entry · Frontend entry and runtime bootstrap · `front/src/index.js`

### Backend

Python API and processing pipeline

- [API app](https://github.com/srujanrana07/researchreach-a-cold-email-helper/blob/main/app/app.py): Flask service · Backend entrypoint and request orchestration · `app/app.py`
- [Resume parser](https://github.com/srujanrana07/researchreach-a-cold-email-helper/blob/main/app/resume_processor.py): extraction · Extracts and normalizes resume content into candidate text · `app/resume_processor.py`
- [Paper search](https://github.com/srujanrana07/researchreach-a-cold-email-helper/blob/main/app/paper_retrieval.py): retrieval · Finds candidate papers and fetches available full text · `app/paper_retrieval.py`
- [Matcher](https://github.com/srujanrana07/researchreach-a-cold-email-helper/blob/main/app/similarity.py): NLP ranking · Embeds texts and scores semantic similarity · `app/similarity.py`
- [Email writer](https://github.com/srujanrana07/researchreach-a-cold-email-helper/blob/main/app/email_generator.py): LLM drafting · Generates a tailored cold email for the selected paper · `app/email_generator.py`
- [Sender](https://github.com/srujanrana07/researchreach-a-cold-email-helper/blob/main/app/email_sender.py): delivery · Sends the generated email outward · `app/email_sender.py`
- **Candidate text**: text artifact · Flattened resume-derived text used for matching
- **Paper text**: text artifact · Retrieved paper text used for ranking and drafting
- **Ranked papers**: result set · Similarity-scored paper matches returned to the UI
- **Email draft**: generated content · Tailored outreach email produced from the selected match

### External services

Third-party scholarly and LLM integrations

- **Semantic Scholar**: external API · Paper discovery source
- **Unpaywall**: external API · Full-text access source
- **Gemini**: LLM API · Generates the outreach email text
- **Mail service**: SMTP/API · Outbound email transport

## Connections

- Bootstrap → UI shell: boots · React entry renders the main UI shell
- UI shell → API app: requests · UI sends user input and fetch requests to the backend
- API app → Resume parser: parses resume · Backend delegates document extraction to the resume processor
- Resume parser → Candidate text: produces · Extracted resume content is normalized into candidate text
- API app → Paper search: finds papers · Backend initiates paper discovery and full-text lookup
- Paper search → Semantic Scholar: searches · Discovery queries scholarly metadata sources
- Paper search → Unpaywall: fetches full text · Attempts to resolve accessible paper text
- Paper search → Paper text: produces · Retrieved paper content is prepared for ranking
- Candidate text → Matcher: scores against · Candidate profile text is embedded and compared to papers
- Paper text → Matcher: scores against · Paper text is embedded and compared to the candidate profile
- Matcher → Ranked papers: ranks · Similarity module returns the best-matching papers
- API app → Email writer: drafts email · Backend asks for a tailored email based on the selected match
- Ranked papers → Email writer: provides context · Top match and scoring context inform the draft
- Email writer → Gemini: calls · LLM integration generates the prose email
- Email writer → Email draft: produces · Generated outreach content is returned as a draft
- Email draft → Sender: sends · Optional delivery step hands the drafted email to the sender
- Sender → Mail service: delivers via · Outbound communication uses SMTP or a mail API
- Ranked papers → UI shell: returns results · Backend sends ranked matches back to the UI
- Email draft → UI shell: returns draft · Backend can return the generated email for display
