# chandanvura/jobradar architecture

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

- Interactive diagram: https://gitdiagram.com/chandanvura/jobradar
- Repository: https://github.com/chandanvura/jobradar

## Overview

JobRadar collects employer job listings, validates and enriches them, then serves a public catalogue for job search and recommendations. Its other major product branches support private browser-based application tracking and resume work, and operational recovery of public catalogue data. The README documents the broad collection-to-Worker-to-interface architecture; sampled source confirms selected calls and UI composition, but not every runtime route or collector detail.

Main entry points: [`scraper/adapters.py`](https://github.com/chandanvura/jobradar/blob/main/scraper/adapters.py) (ATS adapters), [`scraper/normalization.py`](https://github.com/chandanvura/jobradar/blob/main/scraper/normalization.py) (Job enrichment), [`scraper/main.py`](https://github.com/chandanvura/jobradar/blob/main/scraper/main.py) (Scan runner), [`web/worker/index.ts`](https://github.com/chandanvura/jobradar/blob/main/web/worker/index.ts) (API Worker)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_collection["Job collection"]
  node_scan_runner["Scan runner<br/>[main.py]"]
  node_adapter_core["ATS adapters<br/>[adapters.py]"]
  node_special_adapters["Employer adapters"]
  node_avature["Avature adapter<br/>[avature.py]"]
  node_career_widgets["Career widgets<br/>[career_widgets.py]"]
  node_jibe["Jibe adapter<br/>[jibe.py]"]
  node_talentbrew["Talentbrew adapter<br/>[talentbrew.py]"]
  node_public_platforms["Public platforms"]
  node_job_model["Job records<br/>[models.py]"]
end

subgraph group_validation["Validation and eligibility"]
  node_normalization["Job enrichment<br/>[normalization.py]"]
  node_experience_rules["Experience rules<br/>[experience.py]"]
  node_posting_rules["Posting freshness<br/>[posting.py]"]
  node_role_rules["Role taxonomy<br/>[roles.py]"]
  node_location_rules["Location rules<br/>[locations.py]"]
end

subgraph group_catalogue["Public catalogue"]
  node_api_worker["API Worker<br/>[index.ts]"]
  node_catalog_cache["Catalogue cache<br/>[catalog-cache.ts]"]
  node_failure_handling["API failures<br/>[api-failure.ts]"]
  node_d1_store[("D1 catalogue<br/>[schema.ts]")]
end

subgraph group_workspace["Career workspace"]
  node_web_app["Dashboard"]
  node_search_engine["Job search<br/>[job-search.ts]"]
  node_search_worker["Search worker"]
  node_requirement_analysis["Requirement analysis"]
  node_private_profile["Private profile<br/>[private-profile.ts]"]
  node_resume_workspace["Resume workspace"]
end

subgraph group_recovery["Recovery operations"]
  node_public_backup["Static backup<br/>[public-backup.ts]"]
  node_cron_scheduler["Recovery scheduler<br/>[index.ts]"]
end

node_employer_sources(("Employer sources"))
node_telegram(("Telegram"))

node_employer_sources -->|"provides listings"| node_scan_runner
node_scan_runner -->|"dispatches collection"| node_adapter_core
node_adapter_core -->|"uses adapters"| node_special_adapters
node_adapter_core -->|"uses adapter"| node_avature
node_adapter_core -->|"uses adapter"| node_career_widgets
node_adapter_core -->|"uses adapter"| node_jibe
node_adapter_core -->|"uses adapter"| node_talentbrew
node_adapter_core -->|"uses platforms"| node_public_platforms
node_adapter_core -->|"creates records"| node_job_model
node_scan_runner -->|"enriches records"| node_normalization
node_normalization -->|"enriches fields"| node_job_model
node_normalization -->|"analyzes experience"| node_experience_rules
node_normalization -->|"checks freshness"| node_posting_rules
node_normalization -->|"classifies roles"| node_role_rules
node_normalization -->|"normalizes locations"| node_location_rules
node_scan_runner -->|"submits scan"| node_api_worker
node_api_worker -->|"writes catalogue"| node_d1_store
node_api_worker -->|"reads cache"| node_catalog_cache
node_api_worker -->|"formats failures"| node_failure_handling
node_api_worker -->|"serves fallback"| node_public_backup
node_web_app -->|"loads catalogue"| node_api_worker
node_web_app -.->|"searches jobs"| node_search_engine
node_search_worker -->|"builds index"| node_search_engine
node_search_engine -->|"scores requirements"| node_requirement_analysis
node_web_app -->|"stores preferences"| node_private_profile
node_web_app -->|"renders workspace"| node_resume_workspace
node_scan_runner -->|"sends alerts"| node_telegram
node_cron_scheduler -->|"recovers missed scans"| node_scan_runner
node_public_backup -->|"backs up public data"| node_d1_store

click node_scan_runner "https://github.com/chandanvura/jobradar/blob/main/scraper/main.py"
click node_adapter_core "https://github.com/chandanvura/jobradar/blob/main/scraper/adapters.py"
click node_special_adapters "https://github.com/chandanvura/jobradar/tree/main/scraper"
click node_avature "https://github.com/chandanvura/jobradar/blob/main/scraper/avature.py"
click node_career_widgets "https://github.com/chandanvura/jobradar/blob/main/scraper/career_widgets.py"
click node_jibe "https://github.com/chandanvura/jobradar/blob/main/scraper/jibe.py"
click node_talentbrew "https://github.com/chandanvura/jobradar/blob/main/scraper/talentbrew.py"
click node_public_platforms "https://github.com/chandanvura/jobradar/blob/main/scraper/public_platforms.py"
click node_job_model "https://github.com/chandanvura/jobradar/blob/main/scraper/models.py"
click node_normalization "https://github.com/chandanvura/jobradar/blob/main/scraper/normalization.py"
click node_experience_rules "https://github.com/chandanvura/jobradar/blob/main/scraper/experience.py"
click node_posting_rules "https://github.com/chandanvura/jobradar/blob/main/scraper/posting.py"
click node_role_rules "https://github.com/chandanvura/jobradar/blob/main/scraper/roles.py"
click node_location_rules "https://github.com/chandanvura/jobradar/blob/main/scraper/locations.py"
click node_web_app "https://github.com/chandanvura/jobradar/blob/main/web/components/jobradar-dashboard.tsx"
click node_search_engine "https://github.com/chandanvura/jobradar/blob/main/web/lib/job-search.ts"
click node_search_worker "https://github.com/chandanvura/jobradar/blob/main/web/lib/job-search-worker.ts"
click node_requirement_analysis "https://github.com/chandanvura/jobradar/blob/main/web/lib/job-requirements.ts"
click node_private_profile "https://github.com/chandanvura/jobradar/blob/main/web/lib/private-profile.ts"
click node_resume_workspace "https://github.com/chandanvura/jobradar/blob/main/web/components/resume-workspace.tsx"
click node_api_worker "https://github.com/chandanvura/jobradar/blob/main/web/worker/index.ts"
click node_catalog_cache "https://github.com/chandanvura/jobradar/blob/main/web/worker/catalog-cache.ts"
click node_failure_handling "https://github.com/chandanvura/jobradar/blob/main/web/worker/api-failure.ts"
click node_d1_store "https://github.com/chandanvura/jobradar/blob/main/web/db/schema.ts"
click node_public_backup "https://github.com/chandanvura/jobradar/blob/main/web/worker/public-backup.ts"
click node_cron_scheduler "https://github.com/chandanvura/jobradar/blob/main/web/ops-scheduler/index.ts"

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_scan_runner,node_adapter_core,node_special_adapters,node_avature,node_career_widgets,node_jibe,node_talentbrew,node_public_platforms,node_job_model toneBlue
class node_normalization,node_experience_rules,node_posting_rules,node_role_rules,node_location_rules toneAmber
class node_api_worker,node_catalog_cache,node_failure_handling,node_d1_store toneMint
class node_web_app,node_search_engine,node_search_worker,node_requirement_analysis,node_private_profile,node_resume_workspace toneRose
class node_public_backup,node_cron_scheduler,node_employer_sources,node_telegram toneIndigo
```

## Components

### Job collection

- [Scan runner](https://github.com/chandanvura/jobradar/blob/main/scraper/main.py): `scraper/main.py`
- [ATS adapters](https://github.com/chandanvura/jobradar/blob/main/scraper/adapters.py): `scraper/adapters.py`
- [Employer adapters](https://github.com/chandanvura/jobradar/tree/main/scraper): `scraper`
- [Avature adapter](https://github.com/chandanvura/jobradar/blob/main/scraper/avature.py): `scraper/avature.py`
- [Career widgets](https://github.com/chandanvura/jobradar/blob/main/scraper/career_widgets.py): `scraper/career_widgets.py`
- [Jibe adapter](https://github.com/chandanvura/jobradar/blob/main/scraper/jibe.py): `scraper/jibe.py`
- [Talentbrew adapter](https://github.com/chandanvura/jobradar/blob/main/scraper/talentbrew.py): `scraper/talentbrew.py`
- [Public platforms](https://github.com/chandanvura/jobradar/blob/main/scraper/public_platforms.py): `scraper/public_platforms.py`
- [Job records](https://github.com/chandanvura/jobradar/blob/main/scraper/models.py): `scraper/models.py`

### Validation and eligibility

- [Job enrichment](https://github.com/chandanvura/jobradar/blob/main/scraper/normalization.py): `scraper/normalization.py`
- [Experience rules](https://github.com/chandanvura/jobradar/blob/main/scraper/experience.py): `scraper/experience.py`
- [Posting freshness](https://github.com/chandanvura/jobradar/blob/main/scraper/posting.py): `scraper/posting.py`
- [Role taxonomy](https://github.com/chandanvura/jobradar/blob/main/scraper/roles.py): `scraper/roles.py`
- [Location rules](https://github.com/chandanvura/jobradar/blob/main/scraper/locations.py): `scraper/locations.py`

### Public catalogue

- [API Worker](https://github.com/chandanvura/jobradar/blob/main/web/worker/index.ts): `web/worker/index.ts`
- [Catalogue cache](https://github.com/chandanvura/jobradar/blob/main/web/worker/catalog-cache.ts): `web/worker/catalog-cache.ts`
- [API failures](https://github.com/chandanvura/jobradar/blob/main/web/worker/api-failure.ts): `web/worker/api-failure.ts`
- [D1 catalogue](https://github.com/chandanvura/jobradar/blob/main/web/db/schema.ts): `web/db/schema.ts`

### Career workspace

- [Dashboard](https://github.com/chandanvura/jobradar/blob/main/web/components/jobradar-dashboard.tsx): `web/components/jobradar-dashboard.tsx`
- [Job search](https://github.com/chandanvura/jobradar/blob/main/web/lib/job-search.ts): `web/lib/job-search.ts`
- [Search worker](https://github.com/chandanvura/jobradar/blob/main/web/lib/job-search-worker.ts): `web/lib/job-search-worker.ts`
- [Requirement analysis](https://github.com/chandanvura/jobradar/blob/main/web/lib/job-requirements.ts): `web/lib/job-requirements.ts`
- [Private profile](https://github.com/chandanvura/jobradar/blob/main/web/lib/private-profile.ts): `web/lib/private-profile.ts`
- [Resume workspace](https://github.com/chandanvura/jobradar/blob/main/web/components/resume-workspace.tsx): `web/components/resume-workspace.tsx`

### Recovery operations

- [Static backup](https://github.com/chandanvura/jobradar/blob/main/web/worker/public-backup.ts): `web/worker/public-backup.ts`
- [Recovery scheduler](https://github.com/chandanvura/jobradar/blob/main/web/ops-scheduler/index.ts): `web/ops-scheduler/index.ts`

### Other components

- **Employer sources**
- **Telegram**

## Connections

- Employer sources → Scan runner: provides listings (evidence: `README.md`)
- Scan runner → ATS adapters: dispatches collection (evidence: `scraper/main.py`)
- ATS adapters → Employer adapters: uses adapters (evidence: `scraper/adapters.py`)
- ATS adapters → Avature adapter: uses adapter (evidence: `scraper/adapters.py`)
- ATS adapters → Career widgets: uses adapter (evidence: `scraper/adapters.py`)
- ATS adapters → Jibe adapter: uses adapter (evidence: `scraper/adapters.py`)
- ATS adapters → Talentbrew adapter: uses adapter (evidence: `scraper/adapters.py`)
- ATS adapters → Public platforms: uses platforms (evidence: `scraper/adapters.py`)
- ATS adapters → Job records: creates records (evidence: `scraper/adapters.py`)
- Scan runner → Job enrichment: enriches records (evidence: `scraper/main.py`)
- Job enrichment → Job records: enriches fields (evidence: `scraper/normalization.py`)
- Job enrichment → Experience rules: analyzes experience (evidence: `scraper/normalization.py`)
- Job enrichment → Posting freshness: checks freshness (evidence: `scraper/normalization.py`)
- Job enrichment → Role taxonomy: classifies roles (evidence: `scraper/normalization.py`)
- Job enrichment → Location rules: normalizes locations (evidence: `scraper/normalization.py`)
- Scan runner → API Worker: submits scan (evidence: `README.md`)
- API Worker → D1 catalogue: writes catalogue (evidence: `README.md`)
- API Worker → Catalogue cache: reads cache (evidence: `web/worker/index.ts`)
- API Worker → API failures: formats failures (evidence: `web/worker/index.ts`)
- API Worker → Static backup: serves fallback (evidence: `web/worker/index.ts`)
- Dashboard → API Worker: loads catalogue (evidence: `README.md`)
- Dashboard → Job search: searches jobs
- Search worker → Job search: builds index (evidence: `web/lib/job-search-worker.ts`)
- Job search → Requirement analysis: scores requirements (evidence: `web/lib/job-search.ts`)
- Dashboard → Private profile: stores preferences (evidence: `web/components/jobradar-dashboard.tsx`)
- Dashboard → Resume workspace: renders workspace (evidence: `web/components/jobradar-dashboard.tsx`)
- Scan runner → Telegram: sends alerts (evidence: `README.md`)
- Recovery scheduler → Scan runner: recovers missed scans (evidence: `README.md`)
- Static backup → D1 catalogue: backs up public data (evidence: `README.md`)
