# faiyazawsaf/hire_me_plis architecture

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

- Interactive diagram: https://gitdiagram.com/faiyazawsaf/hire_me_plis
- Repository: https://github.com/faiyazawsaf/hire_me_plis

## Overview

1. **Overall shape**
   - This is a two-tier product: a **FastAPI backend** that owns all domain logic and AI orchestration, and a **Next.js 15 frontend** that renders the user experience.
   - The backend is also split into a synchronous API server and an **ARQ worker** for background AI pipelines.

2. **Backend request boundary**
   - Incoming HTTP/WebSocket traffic enters through `backend/app/routers/*`.
   - Routers stay thin and delegate to `backend/app/services/*`, which act as the main domain orchestrators.
   - Shared API contracts are defined in `backend/app/schemas/*`, while persistent state lives in `backend/app/models/*` with Alembic migrations.

3. **Core persistence layer**
   - **Postgres** is the primary system of record for users, CVs, chat messages, goals, nudges, calendar events, applications, and tracker data.
   - SQLAlchemy models plus Alembic migrations define the relational schema.
   - **Redis** supports transient coordination and worker queues.
   - **Cloudflare R2** stores uploaded CV files and other binary artifacts.
   - **Qdrant** stores embedded CV chunks for semantic retrieval.

4. **AI platform layer**
   - `backend/app/ai/core/*` contains the concrete clients for LLMs, embeddings, Qdrant, Redis, and R2.
   - This layer isolates vendor/infrastructure access from business logic so services and pipelines can depend on stable abstractions.
   - The README indicates a ChatLLM-compatible LLM endpoint plus OpenAI embeddings for vectorization.

5. **CV intelligence pipeline**
   - `backend/app/ai/cv_pipeline/*` is the ingestion path for CVs: parse, chunk, classify, extract metadata/profile, and generate embeddings.
   - The output of this pipeline is both structured profile data and searchable chunks in Qdrant.
   - `backend/workers/tasks/cv_pipeline_task.py` suggests the heavy parts run asynchronously in the worker rather than inline with the user request.

6. **RAG subsystem**
   - `backend/app/ai/rag/*` builds grounded context for chat and generation tasks.
   - Retrieval combines vector search, context assembly, and memory/history, which keeps AI responses tied to the user’s actual CV/profile data.
   - This is the main guardrail against hallucinating career history or qualifications.

7. **Conversation and generation layer**
   - `backend/app/ai/llm/*` centralizes prompt templates and generation/streaming behavior.
   - Prompt families cover chat, CV writing, cover letters, job-related responses, scoring, and nudges.
   - Chat features likely stream responses over WebSocket or chunked HTTP, matching the frontend’s websocket client.

8. **Job hunting subsystem**
   - `backend/app/ai/agents/job_hunter/*` is a LangGraph-style agent pipeline.
   - It takes a natural-language search intent, fans out to multiple job-source tools, and normalizes the results into candidate job cards.
   - Source integrations live in `tools/` for JSearch, LinkedIn, BDJobs, and generic scraping.
   - `fit_scorer/*` then ranks jobs against the user profile and CV-derived evidence.

9. **Productivity and coaching subsystem**
   - The tracker domain (`tracker`, `dashboard`, `goal`, `nudge`, `calendar_event`, `application`) models job-search execution, not just discovery.
   - `nudge_service.py` and `backend/workers/tasks/nudge_task.py` imply scheduled or background AI nudges based on user state and progress.
   - This makes the app a career workflow system, not only a job board aggregator.

10. **Frontend architecture**
   - The frontend uses the **Next.js App Router** with route groups for auth and protected app pages.
   - Pages are organized by user task: chat, CV upload/builder, jobs, dashboard, and tracker.
   - State is centralized in **Zustand** stores under `frontend/store/*`, while `frontend/lib/*` holds API and websocket clients.

11. **Frontend/backend interaction**
   - The frontend talks to the FastAPI backend through a typed API client and a websocket layer.
   - Auth bootstrapping, chat streaming, CV workflows, jobs search, and dashboard/tracker data all flow through backend services rather than direct client-side logic.
   - This keeps the frontend mostly presentational with local state management.

12. **Operational boundaries**
   - Docker Compose brings up the full local stack: Postgres, Redis, Qdrant, API server, and worker.
   - The worker must be restarted for pipeline code changes, which is an important architectural boundary between request-serving code and async processing.
   - The repo also includes an evaluation suite and dedicated tests for auth, chat, CV pipeline, job matching, RAG, and job-source diagnostics.

13. **Key end-to-end data flows**
   - **CV upload**: frontend upload → backend stores file in R2 and metadata in Postgres → worker parses/chunks/embeds → Qdrant becomes the retrieval source.
   - **Chat / assistant**: user query → service builds grounded context from RAG + memory → LLM generates response, often streamed back to UI.
   - **Job search**: natural-language intent → job hunter agent queries external job sources in parallel → fit scoring ranks results → results surface in the jobs UI.
   - **Tracker**: applications/goals/calendar state in Postgres → dashboard aggregates progress → nudges may be generated asynchronously.

14. **Main architectural idea**
   - The repository is centered on a single principle: **all AI features are grounded in a persisted user profile built from the uploaded CV**.
   - Everything else—chat, scoring, cover letters, job search, nudges, and dashboard insights—hangs off that profile and its embeddings.

Main entry points: [`backend/app/services`](https://github.com/faiyazawsaf/hire_me_plis/tree/production/backend/app/services) (Services), [`docker-compose.yml`](https://github.com/faiyazawsaf/hire_me_plis/blob/production/docker-compose.yml) (Docker Compose), [`backend/app/ai/cv_pipeline`](https://github.com/faiyazawsaf/hire_me_plis/tree/production/backend/app/ai/cv_pipeline) (CV Pipeline), [`backend/app/ai/rag`](https://github.com/faiyazawsaf/hire_me_plis/tree/production/backend/app/ai/rag) (RAG)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_backend["Backend"]
  node_api_server["API Server<br/>FastAPI app<br/>[main.py]"]
  node_routers["Routers<br/>HTTP boundary"]
  node_services["Services<br/>domain orchestration"]
  node_schemas["Schemas<br/>API contracts"]
  node_models[("Models")]
  node_ai_core["AI Core<br/>vendor clients"]
  node_cv_pipeline["CV Pipeline<br/>ingestion pipeline"]
  node_rag["RAG<br/>grounding layer"]
  node_llm["LLM Layer<br/>generation layer"]
  node_job_hunter["Job Hunter<br/>agent pipeline"]
  node_fit_scorer["Fit Scorer<br/>ranking logic"]
  node_worker["ARQ Worker<br/>background worker<br/>[arq_app.py]"]
end

subgraph group_frontend["Frontend"]
  node_frontend_app["Next.js App<br/>frontend shell"]
  node_ui_routes["UI Routes<br/>pages"]
  node_stores["Stores<br/>client state"]
  node_clients["Client Libs<br/>API clients"]
end

subgraph group_infra["Infra"]
  node_postgres[("Postgres<br/>system of record")]
  node_redis[("Redis<br/>coordination store")]
  node_r2[("Cloudflare R2<br/>object storage")]
  node_qdrant[("Qdrant<br/>vector store")]
  node_compose["Docker Compose<br/>local stack<br/>[docker-compose.yml]"]
end

node_frontend_app -->|"renders"| node_ui_routes
node_ui_routes -->|"uses"| node_stores
node_stores -->|"calls"| node_clients
node_clients -->|"requests"| node_routers
node_api_server -->|"mounts"| node_routers
node_routers -->|"delegates"| node_services
node_services -->|"validates"| node_schemas
node_services -->|"persists"| node_models
node_services -->|"uses"| node_ai_core
node_cv_pipeline -->|"loads"| node_ai_core
node_cv_pipeline -->|"updates"| node_models
node_cv_pipeline -->|"indexes"| node_qdrant
node_rag -->|"retrieves"| node_qdrant
node_rag -->|"reads"| node_models
node_rag -->|"feeds"| node_llm
node_llm -->|"calls"| node_ai_core
node_job_hunter -->|"orchestrates"| node_llm
node_job_hunter -->|"ranks with"| node_fit_scorer
node_job_hunter -->|"exposed through"| node_services
node_worker -->|"runs"| node_cv_pipeline
node_worker -->|"runs"| node_services
node_services -->|"stores"| node_postgres
node_services -->|"coordinates"| node_redis
node_cv_pipeline -->|"stores files"| node_r2
node_compose -->|"starts"| node_api_server
node_compose -->|"starts"| node_worker
node_compose -->|"provisions"| node_postgres
node_compose -->|"provisions"| node_redis
node_compose -->|"provisions"| node_qdrant

click node_api_server "https://github.com/faiyazawsaf/hire_me_plis/blob/production/backend/app/main.py"
click node_routers "https://github.com/faiyazawsaf/hire_me_plis/tree/production/backend/app/routers"
click node_services "https://github.com/faiyazawsaf/hire_me_plis/tree/production/backend/app/services"
click node_schemas "https://github.com/faiyazawsaf/hire_me_plis/tree/production/backend/app/schemas"
click node_models "https://github.com/faiyazawsaf/hire_me_plis/tree/production/backend/app/models"
click node_ai_core "https://github.com/faiyazawsaf/hire_me_plis/tree/production/backend/app/core"
click node_cv_pipeline "https://github.com/faiyazawsaf/hire_me_plis/tree/production/backend/app/ai/cv_pipeline"
click node_rag "https://github.com/faiyazawsaf/hire_me_plis/tree/production/backend/app/ai/rag"
click node_llm "https://github.com/faiyazawsaf/hire_me_plis/tree/production/backend/app/ai/llm"
click node_job_hunter "https://github.com/faiyazawsaf/hire_me_plis/tree/production/backend/app/ai/agents/job_hunter"
click node_fit_scorer "https://github.com/faiyazawsaf/hire_me_plis/tree/production/backend/app/ai/agents/fit_scorer"
click node_worker "https://github.com/faiyazawsaf/hire_me_plis/blob/production/backend/workers/arq_app.py"
click node_frontend_app "https://github.com/faiyazawsaf/hire_me_plis/tree/production/frontend/app"
click node_ui_routes "https://github.com/faiyazawsaf/hire_me_plis/tree/production/frontend/app/(app)"
click node_stores "https://github.com/faiyazawsaf/hire_me_plis/tree/production/frontend/store"
click node_clients "https://github.com/faiyazawsaf/hire_me_plis/tree/production/frontend/lib"
click node_compose "https://github.com/faiyazawsaf/hire_me_plis/blob/production/docker-compose.yml"

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_api_server,node_routers,node_services,node_schemas,node_models,node_ai_core,node_cv_pipeline,node_rag,node_llm,node_job_hunter,node_fit_scorer,node_worker toneBlue
class node_frontend_app,node_ui_routes,node_stores,node_clients toneAmber
class node_postgres,node_redis,node_r2,node_qdrant,node_compose toneMint
```

## Components

### Backend

FastAPI API, domain services, AI orchestration, persistence, and workers.

- [API Server](https://github.com/faiyazawsaf/hire_me_plis/blob/production/backend/app/main.py): FastAPI app · Main HTTP/WebSocket entrypoint for the backend. · `backend/app/main.py`
- [Routers](https://github.com/faiyazawsaf/hire_me_plis/tree/production/backend/app/routers): HTTP boundary · Thin request handlers for auth, chat, CV, jobs, and tracker. · `backend/app/routers`
- [Services](https://github.com/faiyazawsaf/hire_me_plis/tree/production/backend/app/services): domain orchestration · Primary business logic layer coordinating auth, chat, CV, jobs, dashboard, tracker, and nudges. · `backend/app/services`
- [Schemas](https://github.com/faiyazawsaf/hire_me_plis/tree/production/backend/app/schemas): API contracts · Shared request and response models used by routers and services. · `backend/app/schemas`
- [Models](https://github.com/faiyazawsaf/hire_me_plis/tree/production/backend/app/models): SQLAlchemy models · Persistent domain entities for users, CVs, chat, goals, nudges, calendar events, applications, and trackers. · `backend/app/models`
- [AI Core](https://github.com/faiyazawsaf/hire_me_plis/tree/production/backend/app/core): vendor clients · Adapters for LLM, embeddings, Qdrant, Redis, and R2. · `backend/app/core`
- [CV Pipeline](https://github.com/faiyazawsaf/hire_me_plis/tree/production/backend/app/ai/cv_pipeline): ingestion pipeline · Parses, chunks, classifies, extracts metadata/profile data, and creates embeddings for uploaded CVs. · `backend/app/ai/cv_pipeline`
- [RAG](https://github.com/faiyazawsaf/hire_me_plis/tree/production/backend/app/ai/rag): grounding layer · Builds retrieval context from vector search, memory, and profile data for grounded AI responses. · `backend/app/ai/rag`
- [LLM Layer](https://github.com/faiyazawsaf/hire_me_plis/tree/production/backend/app/ai/llm): generation layer · Prompt templates plus generation and streaming behavior for chat, CVs, jobs, scoring, and nudges. · `backend/app/ai/llm`
- [Job Hunter](https://github.com/faiyazawsaf/hire_me_plis/tree/production/backend/app/ai/agents/job_hunter): agent pipeline · LangGraph-style job search agent that fans out to source tools and normalizes candidate jobs. · `backend/app/ai/agents/job_hunter`
- [Fit Scorer](https://github.com/faiyazawsaf/hire_me_plis/tree/production/backend/app/ai/agents/fit_scorer): ranking logic · Extracts evidence and scores jobs against the user profile and CV-derived context. · `backend/app/ai/agents/fit_scorer`
- [ARQ Worker](https://github.com/faiyazawsaf/hire_me_plis/blob/production/backend/workers/arq_app.py): background worker · Runs asynchronous AI jobs such as CV processing and nudges. · `backend/workers/arq_app.py`

### Frontend

Next.js app, UI routes, and client state.

- [Next.js App](https://github.com/faiyazawsaf/hire_me_plis/tree/production/frontend/app): frontend shell · App Router-based user interface with auth and protected app routes. · `frontend/app`
- [UI Routes](https://github.com/faiyazawsaf/hire_me_plis/tree/production/frontend/app/(app)): pages · User-facing pages for chat, CV upload/builder, jobs, dashboard, and tracker. · `frontend/app/(app)`
- [Stores](https://github.com/faiyazawsaf/hire_me_plis/tree/production/frontend/store): client state · Zustand state for auth, chat, CV, dashboard, jobs, resume, and tracker flows. · `frontend/store`
- [Client Libs](https://github.com/faiyazawsaf/hire_me_plis/tree/production/frontend/lib): API clients · Typed API and websocket clients used by the UI. · `frontend/lib`

### Infra

Local development and deployment boundaries.

- **Postgres**: system of record · Primary relational store for users, CVs, messages, goals, nudges, calendar events, applications, and tracker data.
- **Redis**: coordination store · Transient coordination and worker queue backend.
- **Cloudflare R2**: object storage · Stores uploaded CV files and other binary artifacts.
- **Qdrant**: vector store · Stores embedded CV chunks for semantic retrieval.
- [Docker Compose](https://github.com/faiyazawsaf/hire_me_plis/blob/production/docker-compose.yml): local stack · Brings up the API, worker, Postgres, Redis, Qdrant, and related services. · `docker-compose.yml`

## Connections

- Next.js App → UI Routes: renders · App Router serves the main task-oriented pages.
- UI Routes → Stores: uses · Pages rely on centralized client state for interaction flows.
- Stores → Client Libs: calls · Stores and UI logic invoke typed backend clients.
- Client Libs → Routers: requests · Frontend traffic reaches the backend through API and websocket routes.
- API Server → Routers: mounts · Main app exposes the router set.
- Routers → Services: delegates · Routers stay thin and hand off business logic.
- Services → Schemas: validates · Service boundary uses shared contracts for inputs and outputs.
- Services → Models: persists · Domain services read and write the relational models.
- Services → AI Core: uses · Business logic depends on stable AI/infrastructure adapters.
- CV Pipeline → AI Core: loads · Pipeline uses storage, embeddings, and vector clients.
- CV Pipeline → Models: updates · Structured profile and CV metadata are stored in Postgres.
- CV Pipeline → Qdrant: indexes · Embedded CV chunks are written to the vector store.
- RAG → Qdrant: retrieves · Context assembly performs semantic lookup over CV chunks.
- RAG → Models: reads · Grounding context includes persisted user and history data.
- RAG → LLM Layer: feeds · Retrieved context is passed into generation prompts.
- LLM Layer → AI Core: calls · Generation layer uses the shared LLM client.
- Job Hunter → LLM Layer: orchestrates · Agent pipeline uses LLM-driven planning and normalization.
- Job Hunter → Fit Scorer: ranks with · Search results are scored against user fit evidence.
- Job Hunter → Services: exposed through · Job search is surfaced via backend service orchestration.
- ARQ Worker → CV Pipeline: runs · Heavy CV ingestion is executed asynchronously.
- ARQ Worker → Services: runs · Background tasks support nudges and other async jobs.
- Services → Postgres: stores · Core application state is persisted in Postgres.
- Services → Redis: coordinates · Transient state and queueing use Redis.
- CV Pipeline → Cloudflare R2: stores files · Uploaded CV binaries are stored in object storage.
- Docker Compose → API Server: starts · Compose brings up the API service.
- Docker Compose → ARQ Worker: starts · Compose brings up the background worker.
- Docker Compose → Postgres: provisions · Local stack includes the database.
- Docker Compose → Redis: provisions · Local stack includes Redis.
- Docker Compose → Qdrant: provisions · Local stack includes vector search storage.
