# sahityabiswas/job_nexus architecture

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

- Interactive diagram: https://gitdiagram.com/sahityabiswas/job_nexus
- Repository: https://github.com/sahityabiswas/job_nexus

## Overview

#### Purpose and Entry Points
JOB NEXUS is a career recommendation system that stores jobs, skills, and courses in Neo4j, then recommends jobs from a user skill profile. Runtime entry points are the FastAPI service in `src/api.py`, the standard ingestion command in `src/ingest_simple.py`, and a scalable Spark ingestion alternative in `src/ingest_spark.py`. The browser SPA is `static/index.html`.

#### API and SPA Boundary
`src/api.py` serves the SPA and exposes REST endpoints for skill search/normalization, filter metadata, recommendations, and graph data. `static/index.html` owns interactive profile entry, filtering, recommendation display, graph visualization, sharing, and PDF export. The frontend communicates only through the FastAPI API boundary; matching and graph queries remain server-side.

#### Recommendation Pipeline
`src/recommender.py` is the ranking engine. It accepts normalized user skills plus proficiency and filtering/sort inputs, retrieves job requirements from Neo4j, and combines graph-overlap information with TF-IDF/cosine similarity. Its outputs include match scores and matched/missing skill breakdowns used by the recommendation UI and learning simulation.

#### Skill Canonicalization
`src/normalize.py` centralizes alias mapping and canonical skill lookup. Both ingestion and request-time profile handling should pass through this layer so variants such as misspellings or alternate spellings resolve to one `Skill` node identity. This is a key consistency boundary between raw external records/user input and the graph schema.

#### Graph Persistence and Query Layer
`src/db_neo4j.py` manages the Neo4j driver/connection pool and isolates AuraDB credentials and database access from API, matching, and ingestion code. The graph’s architectural entities are Job, Skill, and Course, connected by `REQUIRES` and `TEACHES` relationships. Neo4j supports both recommendation retrieval and the graph payload rendered in the client.

#### Ingestion Paths
`src/ingest_simple.py` is the local/default loader, likely consuming repository seed datasets such as `data/courses.csv` and `data/users.csv` before creating normalized nodes and relationships. `src/ingest_spark.py` is the distributed path: it fetches public job/course data, partitions processing with Spark, performs NLP normalization, and writes graph partitions concurrently to Neo4j. spaCy is a material dependency for skill extraction/normalization.

#### Runtime and Deployment
The backend is Python/FastAPI with scikit-learn vector matching, spaCy NLP, and Neo4j AuraDB as the external graph service. `requirements.txt` defines Python runtime dependencies. Render deployment is represented by `Procfile` and `render.yaml`; connection configuration is supplied through environment variables or the template in `config.example.json`.

Main entry points: [`src/api.py`](https://github.com/sahityabiswas/job_nexus/blob/main/src/api.py) (FastAPI Service), [`src/db_neo4j.py`](https://github.com/sahityabiswas/job_nexus/blob/main/src/db_neo4j.py) (Neo4j Access Layer), [`src/ingest_simple.py`](https://github.com/sahityabiswas/job_nexus/blob/main/src/ingest_simple.py) (Local Loader), [`src/ingest_spark.py`](https://github.com/sahityabiswas/job_nexus/blob/main/src/ingest_spark.py) (Spark Loader)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_client["Browser Client"]
  node_spa["Career SPA<br/>browser SPA<br/>[index.html]"]
end

subgraph group_backend["Python Backend"]
  node_api["FastAPI Service<br/>REST API<br/>[api.py]"]
  node_normalizer["Skill Canonicalizer<br/>normalization<br/>[normalize.py]"]
  node_recommender["Ranking Engine<br/>recommendation engine<br/>[recommender.py]"]
  node_sklearn["Vector Matching<br/>scikit-learn"]
end

subgraph group_ingestion["Ingestion Paths"]
  node_simple_ingest["Local Loader<br/>ingestion command<br/>[ingest_simple.py]"]
  node_spark_ingest["Spark Loader<br/>distributed ingestion<br/>[ingest_spark.py]"]
  node_seed_courses["Course Seed Data<br/>CSV dataset<br/>[courses.csv]"]
  node_seed_users["User Seed Data<br/>CSV dataset<br/>[users.csv]"]
  node_public_data["Public Job &amp; Course Data<br/>external data source"]
  node_spacy["spaCy NLP<br/>NLP dependency"]
end

subgraph group_graph["Graph Persistence"]
  node_neo4j_access["Neo4j Access Layer<br/>driver and query boundary<br/>[db_neo4j.py]"]
  node_neo4j[("Neo4j AuraDB<br/>graph database")]
  node_graph_schema{{"Career Knowledge Graph<br/>Job–Skill–Course graph"}}
end

subgraph group_deployment["Runtime &amp; Deployment"]
  node_dependencies["Python Dependencies<br/>runtime manifest<br/>[requirements.txt]"]
  node_render["Render Deployment<br/>hosting configuration<br/>[render.yaml]"]
  node_procfile["Service Process<br/>process command"]
  node_config_template["Connection Config Template<br/>configuration template"]
end

node_spa -->|"REST requests"| node_api
node_api -->|"normalize profile skills"| node_normalizer
node_api -->|"recommendations"| node_recommender
node_api -->|"graph payload and metadata"| node_neo4j_access
node_recommender -->|"TF-IDF and cosine similarity"| node_sklearn
node_recommender -->|"retrieve requirements"| node_neo4j_access
node_simple_ingest -->|"loads"| node_seed_courses
node_simple_ingest -->|"loads"| node_seed_users
node_simple_ingest -->|"canonicalizes skills"| node_normalizer
node_simple_ingest -->|"writes graph"| node_neo4j_access
node_spark_ingest -->|"fetches"| node_public_data
node_spark_ingest -->|"skill extraction"| node_spacy
node_spark_ingest -->|"canonicalizes skills"| node_normalizer
node_spark_ingest -->|"concurrent partition writes"| node_neo4j_access
node_neo4j_access -->|"driver queries"| node_neo4j
node_neo4j -->|"persists"| node_graph_schema
node_dependencies -.->|"runtime dependencies"| node_api
node_render -->|"launches"| node_procfile
node_procfile -->|"runs service"| node_api
node_config_template -.->|"connection settings"| node_neo4j_access

click node_spa "https://github.com/sahityabiswas/job_nexus/blob/main/static/index.html"
click node_api "https://github.com/sahityabiswas/job_nexus/blob/main/src/api.py"
click node_normalizer "https://github.com/sahityabiswas/job_nexus/blob/main/src/normalize.py"
click node_recommender "https://github.com/sahityabiswas/job_nexus/blob/main/src/recommender.py"
click node_simple_ingest "https://github.com/sahityabiswas/job_nexus/blob/main/src/ingest_simple.py"
click node_spark_ingest "https://github.com/sahityabiswas/job_nexus/blob/main/src/ingest_spark.py"
click node_seed_courses "https://github.com/sahityabiswas/job_nexus/blob/main/data/courses.csv"
click node_seed_users "https://github.com/sahityabiswas/job_nexus/blob/main/data/users.csv"
click node_neo4j_access "https://github.com/sahityabiswas/job_nexus/blob/main/src/db_neo4j.py"
click node_dependencies "https://github.com/sahityabiswas/job_nexus/blob/main/requirements.txt"
click node_render "https://github.com/sahityabiswas/job_nexus/blob/main/render.yaml"
click node_procfile "https://github.com/sahityabiswas/job_nexus/blob/main/Procfile"
click node_config_template "https://github.com/sahityabiswas/job_nexus/blob/main/config.example.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_spa toneBlue
class node_api,node_normalizer,node_recommender,node_sklearn toneAmber
class node_simple_ingest,node_spark_ingest,node_seed_courses,node_seed_users,node_public_data,node_spacy toneMint
class node_neo4j_access,node_neo4j,node_graph_schema toneRose
class node_dependencies,node_render,node_procfile,node_config_template toneIndigo
```

## Components

### Browser Client

- [Career SPA](https://github.com/sahityabiswas/job_nexus/blob/main/static/index.html): browser SPA · Profile entry, filters, results, graph view, sharing, and PDF export. · `static/index.html`

### Python Backend

- [FastAPI Service](https://github.com/sahityabiswas/job_nexus/blob/main/src/api.py): REST API · Serves the SPA and keeps matching and graph queries server-side. · `src/api.py`
- [Skill Canonicalizer](https://github.com/sahityabiswas/job_nexus/blob/main/src/normalize.py): normalization · Maps aliases and variants to canonical skill identities. · `src/normalize.py`
- [Ranking Engine](https://github.com/sahityabiswas/job_nexus/blob/main/src/recommender.py): recommendation engine · Combines graph overlap with TF-IDF/cosine ranking and filters. · `src/recommender.py`
- **Vector Matching**: scikit-learn

### Ingestion Paths

- [Local Loader](https://github.com/sahityabiswas/job_nexus/blob/main/src/ingest_simple.py): ingestion command · Default loader for normalized graph records. · `src/ingest_simple.py`
- [Spark Loader](https://github.com/sahityabiswas/job_nexus/blob/main/src/ingest_spark.py): distributed ingestion · Partitions public data processing and writes graph partitions concurrently. · `src/ingest_spark.py`
- [Course Seed Data](https://github.com/sahityabiswas/job_nexus/blob/main/data/courses.csv): CSV dataset · `data/courses.csv`
- [User Seed Data](https://github.com/sahityabiswas/job_nexus/blob/main/data/users.csv): CSV dataset · `data/users.csv`
- **Public Job & Course Data**: external data source
- **spaCy NLP**: NLP dependency · Extracts and normalizes skills in the distributed path.

### Graph Persistence

- [Neo4j Access Layer](https://github.com/sahityabiswas/job_nexus/blob/main/src/db_neo4j.py): driver and query boundary · Owns driver pooling, credentials isolation, and database access. · `src/db_neo4j.py`
- **Neo4j AuraDB**: graph database · Stores Job, Skill, and Course nodes with REQUIRES and TEACHES relationships.
- **Career Knowledge Graph**: Job–Skill–Course graph · Job REQUIRES Skill; Course TEACHES Skill.

### Runtime & Deployment

- [Python Dependencies](https://github.com/sahityabiswas/job_nexus/blob/main/requirements.txt): runtime manifest · Defines FastAPI, Neo4j, spaCy, and scikit-learn dependencies. · `requirements.txt`
- [Render Deployment](https://github.com/sahityabiswas/job_nexus/blob/main/render.yaml): hosting configuration · `render.yaml`
- [Service Process](https://github.com/sahityabiswas/job_nexus/blob/main/Procfile): process command · `Procfile`
- [Connection Config Template](https://github.com/sahityabiswas/job_nexus/blob/main/config.example.json): configuration template · Environment variables or this template supply connection settings. · `config.example.json`

## Connections

- Career SPA → FastAPI Service: REST requests
- FastAPI Service → Skill Canonicalizer: normalize profile skills
- FastAPI Service → Ranking Engine: recommendations
- FastAPI Service → Neo4j Access Layer: graph payload and metadata
- Ranking Engine → Vector Matching: TF-IDF and cosine similarity
- Ranking Engine → Neo4j Access Layer: retrieve requirements
- Local Loader → Course Seed Data: loads
- Local Loader → User Seed Data: loads
- Local Loader → Skill Canonicalizer: canonicalizes skills
- Local Loader → Neo4j Access Layer: writes graph
- Spark Loader → Public Job & Course Data: fetches
- Spark Loader → spaCy NLP: skill extraction
- Spark Loader → Skill Canonicalizer: canonicalizes skills
- Spark Loader → Neo4j Access Layer: concurrent partition writes
- Neo4j Access Layer → Neo4j AuraDB: driver queries
- Neo4j AuraDB → Career Knowledge Graph: persists
- Python Dependencies → FastAPI Service: runtime dependencies
- Render Deployment → Service Process: launches
- Service Process → FastAPI Service: runs service
- Connection Config Template → Neo4j Access Layer: connection settings
