# thefelixiam/tailoredcv architecture

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

- Interactive diagram: https://gitdiagram.com/thefelixiam/tailoredcv
- Repository: https://github.com/thefelixiam/tailoredcv

## Overview

TailoredCV combines a public portfolio with an authenticated admin workflow for maintaining a master profile, analyzing job descriptions, matching real profile evidence, and producing job-specific CVs and PDFs. The graph follows the README’s documented workflow and sampled module responsibilities; several page/action implementations and storage internals were not sampled, so uncertain wiring is omitted.

Main entry points: [`src/app/(admin)/jobs/actions.ts`](https://github.com/thefelixiam/tailoredcv/blob/main/src/app/(admin)/jobs/actions.ts) (Job actions), [`src/app/api/cv/[id]/pdf/route.ts`](https://github.com/thefelixiam/tailoredcv/blob/main/src/app/api/cv/%5Bid%5D/pdf/route.ts) (PDF download route), [`src/lib/profiles.ts`](https://github.com/thefelixiam/tailoredcv/blob/main/src/lib/profiles.ts) (Profile storage), [`src/lib/db.ts`](https://github.com/thefelixiam/tailoredcv/blob/main/src/lib/db.ts) (SQLite)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_auth["Account access"]
  node_login["Login UI<br/>[page.tsx]"]
  node_login_actions["Login actions<br/>[actions.ts]"]
  node_session["Session handling<br/>[session.ts]"]
  node_auth_lib["Authentication<br/>[auth.ts]"]
end

subgraph group_tailoring["Job tailoring"]
  node_jobs_ui["Job management<br/>[page.tsx]"]
  node_job_actions["Job actions<br/>[actions.ts]"]
  node_job_store["Job storage<br/>[store.ts]"]
  node_parser["Job description parser<br/>[parser.ts]"]
  node_ollama["Ollama analysis<br/>[ollamaParser.ts]"]
  node_ollama_service["Ollama service"]
  node_matcher["Profile-job matcher<br/>[engine.ts]"]
  node_taxonomy["Skill taxonomy<br/>[taxonomy.ts]"]
end

subgraph group_cv["CV output"]
  node_cv_editor["CV editor<br/>[CvEditor.tsx]"]
  node_cv_store["CV variant storage<br/>[store.ts]"]
  node_cv_renderer["CV rendering<br/>[CvRenderer.tsx]"]
  node_cv_templates["CV templates<br/>[templates.ts]"]
  node_pdf_route["PDF download route<br/>[route.ts]"]
  node_puppeteer["Headless browser"]
  node_print_page["Print page<br/>[page.tsx]"]
end

subgraph group_portfolio["Public portfolio"]
  node_portfolio_page["Public portfolio<br/>[page.tsx]"]
  node_portfolio_data["Portfolio view<br/>[portfolio.ts]"]
end

subgraph group_data["Profile and storage"]
  node_profile_ui["Profile editor<br/>[ProfileForm.tsx]"]
  node_profile_actions["Profile actions<br/>[actions.ts]"]
  node_profile_store["Profile storage<br/>[profiles.ts]"]
  node_sqlite[("SQLite<br/>[db.ts]")]
end

node_user(("User"))

node_user -->|"opens"| node_login
node_login -->|"submits credentials"| node_login_actions
node_login_actions -->|"verifies and creates session"| node_auth_lib
node_auth_lib -->|"reads and writes"| node_sqlite
node_user -->|"edits profile"| node_profile_ui
node_profile_ui -->|"saves profile"| node_profile_actions
node_profile_actions -->|"persists profile"| node_profile_store
node_profile_store -->|"reads and writes"| node_sqlite
node_user -->|"submits job description"| node_jobs_ui
node_jobs_ui -->|"requests job analysis"| node_job_actions
node_job_actions -->|"parses description"| node_parser
node_parser -->|"resolves skill spellings"| node_taxonomy
node_job_actions -.->|"may analyze"| node_ollama
node_ollama -.->|"requests analysis"| node_ollama_service
node_ollama -.->|"falls back to"| node_parser
node_job_actions -->|"stores job"| node_job_store
node_job_store -->|"reads and writes"| node_sqlite
node_job_actions -->|"loads profile"| node_profile_store
node_job_actions -->|"scores profile against job"| node_matcher
node_matcher -->|"normalizes skills"| node_taxonomy
node_user -->|"reviews and tailors CV"| node_cv_editor
node_cv_editor -->|"saves variant"| node_cv_store
node_cv_store -->|"reads and writes"| node_sqlite
node_user -->|"downloads PDF"| node_pdf_route
node_pdf_route -->|"checks session"| node_auth_lib
node_pdf_route -->|"loads CV variant"| node_cv_store
node_pdf_route -->|"loads job title"| node_job_store
node_pdf_route -->|"renders print page"| node_puppeteer
node_puppeteer -->|"opens page"| node_print_page
node_print_page -->|"renders CV"| node_cv_renderer
node_cv_renderer -->|"selects template"| node_cv_templates
node_user -->|"visits"| node_portfolio_page
node_portfolio_page -->|"loads portfolio view"| node_portfolio_data
node_portfolio_data -->|"reads profile"| node_profile_store

click node_login "https://github.com/thefelixiam/tailoredcv/blob/main/src/app/(admin)/login/page.tsx"
click node_login_actions "https://github.com/thefelixiam/tailoredcv/blob/main/src/app/(admin)/login/actions.ts"
click node_session "https://github.com/thefelixiam/tailoredcv/blob/main/src/lib/session.ts"
click node_auth_lib "https://github.com/thefelixiam/tailoredcv/blob/main/src/lib/auth.ts"
click node_profile_ui "https://github.com/thefelixiam/tailoredcv/blob/main/src/components/ProfileForm.tsx"
click node_profile_actions "https://github.com/thefelixiam/tailoredcv/blob/main/src/app/(admin)/profile/actions.ts"
click node_profile_store "https://github.com/thefelixiam/tailoredcv/blob/main/src/lib/profiles.ts"
click node_sqlite "https://github.com/thefelixiam/tailoredcv/blob/main/src/lib/db.ts"
click node_jobs_ui "https://github.com/thefelixiam/tailoredcv/blob/main/src/app/(admin)/jobs/page.tsx"
click node_job_actions "https://github.com/thefelixiam/tailoredcv/blob/main/src/app/(admin)/jobs/actions.ts"
click node_job_store "https://github.com/thefelixiam/tailoredcv/blob/main/src/lib/jobs/store.ts"
click node_parser "https://github.com/thefelixiam/tailoredcv/blob/main/src/lib/jobs/parser.ts"
click node_ollama "https://github.com/thefelixiam/tailoredcv/blob/main/src/lib/jobs/ollamaParser.ts"
click node_matcher "https://github.com/thefelixiam/tailoredcv/blob/main/src/lib/matching/engine.ts"
click node_taxonomy "https://github.com/thefelixiam/tailoredcv/blob/main/src/lib/skills/taxonomy.ts"
click node_cv_editor "https://github.com/thefelixiam/tailoredcv/blob/main/src/components/CvEditor.tsx"
click node_cv_store "https://github.com/thefelixiam/tailoredcv/blob/main/src/lib/cv/store.ts"
click node_cv_renderer "https://github.com/thefelixiam/tailoredcv/blob/main/src/components/cv/CvRenderer.tsx"
click node_cv_templates "https://github.com/thefelixiam/tailoredcv/blob/main/src/lib/cv/templates.ts"
click node_pdf_route "https://github.com/thefelixiam/tailoredcv/blob/main/src/app/api/cv/%5Bid%5D/pdf/route.ts"
click node_print_page "https://github.com/thefelixiam/tailoredcv/blob/main/src/app/(admin)/cv/%5Bid%5D/print/page.tsx"
click node_portfolio_page "https://github.com/thefelixiam/tailoredcv/blob/main/src/app/page.tsx"
click node_portfolio_data "https://github.com/thefelixiam/tailoredcv/blob/main/src/lib/portfolio.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_login,node_login_actions,node_session,node_auth_lib,node_user toneBlue
class node_jobs_ui,node_job_actions,node_job_store,node_parser,node_ollama,node_ollama_service,node_matcher,node_taxonomy toneAmber
class node_cv_editor,node_cv_store,node_cv_renderer,node_cv_templates,node_pdf_route,node_puppeteer,node_print_page toneMint
class node_portfolio_page,node_portfolio_data toneRose
class node_profile_ui,node_profile_actions,node_profile_store,node_sqlite toneIndigo
```

## Components

### Account access

- [Login UI](https://github.com/thefelixiam/tailoredcv/blob/main/src/app/(admin)/login/page.tsx): `src/app/(admin)/login/page.tsx`
- [Login actions](https://github.com/thefelixiam/tailoredcv/blob/main/src/app/(admin)/login/actions.ts): `src/app/(admin)/login/actions.ts`
- [Session handling](https://github.com/thefelixiam/tailoredcv/blob/main/src/lib/session.ts): `src/lib/session.ts`
- [Authentication](https://github.com/thefelixiam/tailoredcv/blob/main/src/lib/auth.ts): `src/lib/auth.ts`

### Job tailoring

- [Job management](https://github.com/thefelixiam/tailoredcv/blob/main/src/app/(admin)/jobs/page.tsx): `src/app/(admin)/jobs/page.tsx`
- [Job actions](https://github.com/thefelixiam/tailoredcv/blob/main/src/app/(admin)/jobs/actions.ts): `src/app/(admin)/jobs/actions.ts`
- [Job storage](https://github.com/thefelixiam/tailoredcv/blob/main/src/lib/jobs/store.ts): `src/lib/jobs/store.ts`
- [Job description parser](https://github.com/thefelixiam/tailoredcv/blob/main/src/lib/jobs/parser.ts): `src/lib/jobs/parser.ts`
- [Ollama analysis](https://github.com/thefelixiam/tailoredcv/blob/main/src/lib/jobs/ollamaParser.ts): `src/lib/jobs/ollamaParser.ts`
- **Ollama service**
- [Profile-job matcher](https://github.com/thefelixiam/tailoredcv/blob/main/src/lib/matching/engine.ts): `src/lib/matching/engine.ts`
- [Skill taxonomy](https://github.com/thefelixiam/tailoredcv/blob/main/src/lib/skills/taxonomy.ts): `src/lib/skills/taxonomy.ts`

### CV output

- [CV editor](https://github.com/thefelixiam/tailoredcv/blob/main/src/components/CvEditor.tsx): `src/components/CvEditor.tsx`
- [CV variant storage](https://github.com/thefelixiam/tailoredcv/blob/main/src/lib/cv/store.ts): `src/lib/cv/store.ts`
- [CV rendering](https://github.com/thefelixiam/tailoredcv/blob/main/src/components/cv/CvRenderer.tsx): `src/components/cv/CvRenderer.tsx`
- [CV templates](https://github.com/thefelixiam/tailoredcv/blob/main/src/lib/cv/templates.ts): `src/lib/cv/templates.ts`
- [PDF download route](https://github.com/thefelixiam/tailoredcv/blob/main/src/app/api/cv/%5Bid%5D/pdf/route.ts): `src/app/api/cv/[id]/pdf/route.ts`
- **Headless browser**
- [Print page](https://github.com/thefelixiam/tailoredcv/blob/main/src/app/(admin)/cv/%5Bid%5D/print/page.tsx): `src/app/(admin)/cv/[id]/print/page.tsx`

### Public portfolio

- [Public portfolio](https://github.com/thefelixiam/tailoredcv/blob/main/src/app/page.tsx): `src/app/page.tsx`
- [Portfolio view](https://github.com/thefelixiam/tailoredcv/blob/main/src/lib/portfolio.ts): `src/lib/portfolio.ts`

### Profile and storage

- [Profile editor](https://github.com/thefelixiam/tailoredcv/blob/main/src/components/ProfileForm.tsx): `src/components/ProfileForm.tsx`
- [Profile actions](https://github.com/thefelixiam/tailoredcv/blob/main/src/app/(admin)/profile/actions.ts): `src/app/(admin)/profile/actions.ts`
- [Profile storage](https://github.com/thefelixiam/tailoredcv/blob/main/src/lib/profiles.ts): `src/lib/profiles.ts`
- [SQLite](https://github.com/thefelixiam/tailoredcv/blob/main/src/lib/db.ts): `src/lib/db.ts`

### Other components

- **User**

## Connections

- User → Login UI: opens
- Login UI → Login actions: submits credentials
- Login actions → Authentication: verifies and creates session
- Authentication → SQLite: reads and writes
- User → Profile editor: edits profile
- Profile editor → Profile actions: saves profile
- Profile actions → Profile storage: persists profile
- Profile storage → SQLite: reads and writes
- User → Job management: submits job description
- Job management → Job actions: requests job analysis
- Job actions → Job description parser: parses description
- Job description parser → Skill taxonomy: resolves skill spellings
- Job actions → Ollama analysis: may analyze
- Ollama analysis → Ollama service: requests analysis
- Ollama analysis → Job description parser: falls back to
- Job actions → Job storage: stores job
- Job storage → SQLite: reads and writes
- Job actions → Profile storage: loads profile
- Job actions → Profile-job matcher: scores profile against job
- Profile-job matcher → Skill taxonomy: normalizes skills
- User → CV editor: reviews and tailors CV
- CV editor → CV variant storage: saves variant
- CV variant storage → SQLite: reads and writes
- User → PDF download route: downloads PDF
- PDF download route → Authentication: checks session
- PDF download route → CV variant storage: loads CV variant
- PDF download route → Job storage: loads job title
- PDF download route → Headless browser: renders print page
- Headless browser → Print page: opens page
- Print page → CV rendering: renders CV
- CV rendering → CV templates: selects template
- User → Public portfolio: visits
- Public portfolio → Portfolio view: loads portfolio view
- Portfolio view → Profile storage: reads profile
