# johnitopaisah/portfolio-mcs architecture

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

- Interactive diagram: https://gitdiagram.com/johnitopaisah/portfolio-mcs
- Repository: https://github.com/johnitopaisah/portfolio-mcs

## Overview

Portfolio MCS combines a public portfolio and private CMS with an API-backed career-management product. The main career workflow discovers and scores jobs, lets the admin review and track applications, and supports email-response tracking and tailored CV documents. The README documents additional portfolio, analytics, and monitoring capabilities. Some implementation excerpts are partial, so the graph includes only supported links and uses documented capabilities where their source was not sampled.

Main entry points: [`api/src/db/client.js`](https://github.com/johnitopaisah/portfolio-mcs/blob/main/api/src/db/client.js) (PostgreSQL), [`api/src/index.js`](https://github.com/johnitopaisah/portfolio-mcs/blob/main/api/src/index.js) (REST API), [`admin-ui/src/app/dashboard`](https://github.com/johnitopaisah/portfolio-mcs/tree/main/admin-ui/src/app/dashboard) (Admin CMS), [`scraper/src/pipeline.js`](https://github.com/johnitopaisah/portfolio-mcs/blob/main/scraper/src/pipeline.js) (Job discovery)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_interfaces["User Interfaces"]
  node_public_ui["Public portfolio"]
  node_admin_ui["Admin CMS"]
  node_referee_form["Reference form"]
end

subgraph group_api_content["API and Portfolio Content"]
  node_api["REST API<br/>[index.js]"]
  node_portfolio_routes["Portfolio routes"]
  node_auth_routes["Authentication<br/>[auth.js]"]
  node_blog_ingest["Blog ingestion"]
end

subgraph group_career["Career Intelligence"]
  node_scraper["Job discovery<br/>[pipeline.js]"]
  node_job_sources["Career-site sources"]
  node_ats_parsers["ATS parsers"]
  node_job_filtering["Job filtering and scoring"]
  node_job_routes["Job API<br/>[jobs.js]"]
  node_admin_job_routes["Job administration<br/>[jobs.js]"]
end

subgraph group_applications["Application Workflow"]
  node_application_routes["Application CRM<br/>[applications.js]"]
  node_email_worker["Email tracking worker<br/>[emailWorker.js]"]
  node_email_providers["Mailbox connectors"]
  node_email_classifier["Email classification"]
  node_cv_services["CV and letter generation"]
  node_pdf_service["PDF rendering<br/>[pdfService.js]"]
end

subgraph group_operations["Integrations and Observability"]
  node_database[("PostgreSQL<br/>[client.js]")]
  node_metrics["Prometheus metrics<br/>[metrics.js]"]
  node_monitoring["Monitoring stack"]
end

node_visitor(("Portfolio visitor"))
node_administrator(("Administrator"))
node_referee(("Referee"))
node_medium(("Medium RSS"))
node_mailboxes(("Email providers"))
node_claude(("Claude Haiku"))
node_browser_pdf(("Chromium"))

node_visitor -->|"browses"| node_public_ui
node_administrator -->|"manages content"| node_admin_ui
node_referee -->|"submits reference"| node_referee_form
node_public_ui -->|"requests content"| node_api
node_admin_ui -->|"calls API"| node_api
node_referee_form -->|"submits reference"| node_api
node_api -->|"dispatches"| node_portfolio_routes
node_api -->|"dispatches"| node_auth_routes
node_portfolio_routes -->|"reads and writes"| node_database
node_auth_routes -->|"reads and writes"| node_database
node_medium -.->|"provides feed"| node_blog_ingest
node_blog_ingest -->|"upserts posts"| node_database
node_api -->|"admin sync"| node_blog_ingest
node_scraper -->|"discovers listings"| node_job_sources
node_scraper -->|"fetches board jobs"| node_ats_parsers
node_job_sources -->|"returns candidates"| node_scraper
node_ats_parsers -->|"returns listings"| node_scraper
node_scraper -->|"stores discovered jobs"| node_database
node_job_filtering -.->|"scores jobs"| node_claude
node_job_filtering -->|"records scores"| node_database
node_job_routes -->|"reads listings"| node_database
node_admin_job_routes -->|"manages jobs and targets"| node_database
node_admin_ui -->|"browses jobs"| node_job_routes
node_admin_ui -->|"configures targets"| node_admin_job_routes
node_application_routes -->|"manages applications"| node_database
node_admin_ui -->|"tracks applications"| node_application_routes
node_email_worker -->|"fetches messages"| node_email_providers
node_email_providers -->|"reads inboxes"| node_mailboxes
node_email_worker -->|"classifies messages"| node_email_classifier
node_email_worker -->|"matches and updates"| node_database
node_application_routes -->|"generates documents"| node_cv_services
node_cv_services -.->|"tailors content"| node_claude
node_cv_services -->|"renders document"| node_pdf_service
node_pdf_service -->|"prints PDF"| node_browser_pdf
node_pdf_service -->|"loads CV data"| node_database
node_api -->|"exposes metrics"| node_metrics
node_monitoring -->|"scrapes metrics"| node_api

click node_public_ui "https://github.com/johnitopaisah/portfolio-mcs/tree/main/user-ui/src/app"
click node_admin_ui "https://github.com/johnitopaisah/portfolio-mcs/tree/main/admin-ui/src/app/dashboard"
click node_referee_form "https://github.com/johnitopaisah/portfolio-mcs/blob/main/user-ui/src/app/referee-form/RefereeFormClient.tsx"
click node_api "https://github.com/johnitopaisah/portfolio-mcs/blob/main/api/src/index.js"
click node_portfolio_routes "https://github.com/johnitopaisah/portfolio-mcs/tree/main/api/src/routes"
click node_auth_routes "https://github.com/johnitopaisah/portfolio-mcs/blob/main/api/src/routes/auth.js"
click node_blog_ingest "https://github.com/johnitopaisah/portfolio-mcs/blob/main/api/src/services/blogIngestService.js"
click node_scraper "https://github.com/johnitopaisah/portfolio-mcs/blob/main/scraper/src/pipeline.js"
click node_job_sources "https://github.com/johnitopaisah/portfolio-mcs/tree/main/scraper/src/discovery"
click node_ats_parsers "https://github.com/johnitopaisah/portfolio-mcs/tree/main/scraper/src/parsers"
click node_job_filtering "https://github.com/johnitopaisah/portfolio-mcs/blob/main/api/src/services/jobIngestion/aiFilteringService.js"
click node_job_routes "https://github.com/johnitopaisah/portfolio-mcs/blob/main/api/src/routes/jobs.js"
click node_admin_job_routes "https://github.com/johnitopaisah/portfolio-mcs/blob/main/api/src/routes/admin/jobs.js"
click node_application_routes "https://github.com/johnitopaisah/portfolio-mcs/blob/main/api/src/routes/applications.js"
click node_email_worker "https://github.com/johnitopaisah/portfolio-mcs/blob/main/api/src/workers/emailWorker.js"
click node_email_providers "https://github.com/johnitopaisah/portfolio-mcs/tree/main/api/src/services/emailTracking"
click node_email_classifier "https://github.com/johnitopaisah/portfolio-mcs/blob/main/api/src/services/emailTracking/emailClassificationService.js"
click node_cv_services "https://github.com/johnitopaisah/portfolio-mcs/tree/main/api/src/services/cvGeneration"
click node_pdf_service "https://github.com/johnitopaisah/portfolio-mcs/blob/main/api/src/services/cvGeneration/pdfService.js"
click node_database "https://github.com/johnitopaisah/portfolio-mcs/blob/main/api/src/db/client.js"
click node_metrics "https://github.com/johnitopaisah/portfolio-mcs/blob/main/api/src/metrics.js"
click node_monitoring "https://github.com/johnitopaisah/portfolio-mcs/tree/main/monitoring"

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_public_ui,node_admin_ui,node_referee_form toneBlue
class node_api,node_portfolio_routes,node_auth_routes,node_blog_ingest toneAmber
class node_scraper,node_job_sources,node_ats_parsers,node_job_filtering,node_job_routes,node_admin_job_routes toneMint
class node_application_routes,node_email_worker,node_email_providers,node_email_classifier,node_cv_services,node_pdf_service toneRose
class node_database,node_metrics,node_monitoring,node_visitor,node_administrator,node_referee,node_medium,node_mailboxes,node_claude,node_browser_pdf toneIndigo
```

## Components

### User Interfaces

- [Public portfolio](https://github.com/johnitopaisah/portfolio-mcs/tree/main/user-ui/src/app): `user-ui/src/app`
- [Admin CMS](https://github.com/johnitopaisah/portfolio-mcs/tree/main/admin-ui/src/app/dashboard): `admin-ui/src/app/dashboard`
- [Reference form](https://github.com/johnitopaisah/portfolio-mcs/blob/main/user-ui/src/app/referee-form/RefereeFormClient.tsx): `user-ui/src/app/referee-form/RefereeFormClient.tsx`

### API and Portfolio Content

- [REST API](https://github.com/johnitopaisah/portfolio-mcs/blob/main/api/src/index.js): `api/src/index.js`
- [Portfolio routes](https://github.com/johnitopaisah/portfolio-mcs/tree/main/api/src/routes): `api/src/routes`
- [Authentication](https://github.com/johnitopaisah/portfolio-mcs/blob/main/api/src/routes/auth.js): `api/src/routes/auth.js`
- [Blog ingestion](https://github.com/johnitopaisah/portfolio-mcs/blob/main/api/src/services/blogIngestService.js): `api/src/services/blogIngestService.js`

### Career Intelligence

- [Job discovery](https://github.com/johnitopaisah/portfolio-mcs/blob/main/scraper/src/pipeline.js): `scraper/src/pipeline.js`
- [Career-site sources](https://github.com/johnitopaisah/portfolio-mcs/tree/main/scraper/src/discovery): `scraper/src/discovery`
- [ATS parsers](https://github.com/johnitopaisah/portfolio-mcs/tree/main/scraper/src/parsers): `scraper/src/parsers`
- [Job filtering and scoring](https://github.com/johnitopaisah/portfolio-mcs/blob/main/api/src/services/jobIngestion/aiFilteringService.js): `api/src/services/jobIngestion/aiFilteringService.js`
- [Job API](https://github.com/johnitopaisah/portfolio-mcs/blob/main/api/src/routes/jobs.js): `api/src/routes/jobs.js`
- [Job administration](https://github.com/johnitopaisah/portfolio-mcs/blob/main/api/src/routes/admin/jobs.js): `api/src/routes/admin/jobs.js`

### Application Workflow

- [Application CRM](https://github.com/johnitopaisah/portfolio-mcs/blob/main/api/src/routes/applications.js): `api/src/routes/applications.js`
- [Email tracking worker](https://github.com/johnitopaisah/portfolio-mcs/blob/main/api/src/workers/emailWorker.js): `api/src/workers/emailWorker.js`
- [Mailbox connectors](https://github.com/johnitopaisah/portfolio-mcs/tree/main/api/src/services/emailTracking): `api/src/services/emailTracking`
- [Email classification](https://github.com/johnitopaisah/portfolio-mcs/blob/main/api/src/services/emailTracking/emailClassificationService.js): `api/src/services/emailTracking/emailClassificationService.js`
- [CV and letter generation](https://github.com/johnitopaisah/portfolio-mcs/tree/main/api/src/services/cvGeneration): `api/src/services/cvGeneration`
- [PDF rendering](https://github.com/johnitopaisah/portfolio-mcs/blob/main/api/src/services/cvGeneration/pdfService.js): `api/src/services/cvGeneration/pdfService.js`

### Integrations and Observability

- [PostgreSQL](https://github.com/johnitopaisah/portfolio-mcs/blob/main/api/src/db/client.js): `api/src/db/client.js`
- [Prometheus metrics](https://github.com/johnitopaisah/portfolio-mcs/blob/main/api/src/metrics.js): `api/src/metrics.js`
- [Monitoring stack](https://github.com/johnitopaisah/portfolio-mcs/tree/main/monitoring): `monitoring`

### Other components

- **Portfolio visitor**
- **Administrator**
- **Referee**
- **Medium RSS**
- **Email providers**
- **Claude Haiku**
- **Chromium**

## Connections

- Portfolio visitor → Public portfolio: browses
- Administrator → Admin CMS: manages content
- Referee → Reference form: submits reference
- Public portfolio → REST API: requests content
- Admin CMS → REST API: calls API
- Reference form → REST API: submits reference
- REST API → Portfolio routes: dispatches
- REST API → Authentication: dispatches
- Portfolio routes → PostgreSQL: reads and writes
- Authentication → PostgreSQL: reads and writes
- Medium RSS → Blog ingestion: provides feed
- Blog ingestion → PostgreSQL: upserts posts
- REST API → Blog ingestion: admin sync
- Job discovery → Career-site sources: discovers listings
- Job discovery → ATS parsers: fetches board jobs
- Career-site sources → Job discovery: returns candidates
- ATS parsers → Job discovery: returns listings
- Job discovery → PostgreSQL: stores discovered jobs
- Job filtering and scoring → Claude Haiku: scores jobs
- Job filtering and scoring → PostgreSQL: records scores
- Job API → PostgreSQL: reads listings
- Job administration → PostgreSQL: manages jobs and targets
- Admin CMS → Job API: browses jobs
- Admin CMS → Job administration: configures targets
- Application CRM → PostgreSQL: manages applications
- Admin CMS → Application CRM: tracks applications
- Email tracking worker → Mailbox connectors: fetches messages
- Mailbox connectors → Email providers: reads inboxes
- Email tracking worker → Email classification: classifies messages
- Email tracking worker → PostgreSQL: matches and updates
- Application CRM → CV and letter generation: generates documents
- CV and letter generation → Claude Haiku: tailors content
- CV and letter generation → PDF rendering: renders document
- PDF rendering → Chromium: prints PDF
- PDF rendering → PostgreSQL: loads CV data
- REST API → Prometheus metrics: exposes metrics
- Monitoring stack → REST API: scrapes metrics
