# jjduques/jjduques.github.io architecture

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

- Interactive diagram: https://gitdiagram.com/jjduques/jjduques.github.io
- Repository: https://github.com/jjduques/jjduques.github.io

## Overview

This repository is a personal portfolio site with a static-export frontend and a small FastAPI service for health reporting and contact messages. A visitor reads the portfolio and can submit a message; the API validates and rate-limits it, stores it in SQLite, then retries notification through n8n. The frontend also presents experience, stack, project case studies, and the site’s architecture decisions. API calls and storage behavior are supported by sampled source; deployment and browser-to-service routing are documented in the About page, while unsampled frontend internals are not inferred.

Main entry points: [`api/app/main.py`](https://github.com/jjduques/jjduques.github.io/blob/main/api/app/main.py) (FastAPI endpoints), [`api/app/db.py`](https://github.com/jjduques/jjduques.github.io/blob/main/api/app/db.py) (SQLite access), [`frontend/app/page.tsx`](https://github.com/jjduques/jjduques.github.io/blob/main/frontend/app/page.tsx) (Home page), [`api/app/notify.py`](https://github.com/jjduques/jjduques.github.io/blob/main/api/app/notify.py) (Pending notifier)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_web["Portfolio frontend"]
  node_home["Home page<br/>[page.tsx]"]
  node_projects["Project listing<br/>[page.tsx]"]
  node_project_detail["Project detail<br/>[page.tsx]"]
  node_about["Architecture page<br/>[page.tsx]"]
  node_content["Portfolio content<br/>[content.ts]"]
  node_contact_form["Contact form<br/>[contact-form.tsx]"]
end

subgraph group_api["Contact and health API"]
  node_api_service["FastAPI endpoints<br/>[main.py]"]
  node_settings["Runtime settings<br/>[config.py]"]
  node_limiter["Rate limiter<br/>[ratelimit.py]"]
  node_host_metrics["Host metrics<br/>[system.py]"]
end

subgraph group_data["Message persistence"]
  node_message_store["SQLite access<br/>[db.py]"]
  node_sqlite[("Contact database")]
end

subgraph group_ops["Operations and notification"]
  node_backup["Database backup<br/>[backup.py]"]
  node_notifier["Pending notifier<br/>[notify.py]"]
end

node_visitor(("Site visitor"))
node_n8n{{"n8n webhook"}}
node_funnel{{"Tailscale Funnel"}}
node_pages_host{{"GitHub Pages CDN"}}

node_visitor -->|"requests pages"| node_pages_host
node_pages_host -.->|"serves static files"| node_home
node_visitor -->|"submits message"| node_contact_form
node_home -->|"renders form"| node_contact_form
node_home -->|"loads portfolio data"| node_content
node_projects -->|"loads projects"| node_content
node_project_detail -.->|"loads project"| node_content
node_visitor -->|"sends HTTPS request"| node_funnel
node_funnel -->|"forwards request"| node_api_service
node_api_service -->|"loads settings"| node_settings
node_api_service -->|"checks limits"| node_limiter
node_api_service -->|"reads host metrics"| node_host_metrics
node_api_service -->|"reads and writes messages"| node_message_store
node_message_store -.->|"reads and writes"| node_sqlite
node_api_service -->|"queues notification"| node_notifier
node_notifier -->|"loads and updates pending"| node_message_store
node_notifier -->|"posts webhook"| node_n8n
node_backup -->|"creates safe copy"| node_message_store

click node_home "https://github.com/jjduques/jjduques.github.io/blob/main/frontend/app/page.tsx"
click node_projects "https://github.com/jjduques/jjduques.github.io/blob/main/frontend/app/projects/page.tsx"
click node_project_detail "https://github.com/jjduques/jjduques.github.io/blob/main/frontend/app/projects/%5Bslug%5D/page.tsx"
click node_about "https://github.com/jjduques/jjduques.github.io/blob/main/frontend/app/about/page.tsx"
click node_content "https://github.com/jjduques/jjduques.github.io/blob/main/frontend/lib/content.ts"
click node_contact_form "https://github.com/jjduques/jjduques.github.io/blob/main/frontend/components/contact-form.tsx"
click node_api_service "https://github.com/jjduques/jjduques.github.io/blob/main/api/app/main.py"
click node_settings "https://github.com/jjduques/jjduques.github.io/blob/main/api/app/config.py"
click node_limiter "https://github.com/jjduques/jjduques.github.io/blob/main/api/app/ratelimit.py"
click node_host_metrics "https://github.com/jjduques/jjduques.github.io/blob/main/api/app/system.py"
click node_message_store "https://github.com/jjduques/jjduques.github.io/blob/main/api/app/db.py"
click node_backup "https://github.com/jjduques/jjduques.github.io/blob/main/api/app/backup.py"
click node_notifier "https://github.com/jjduques/jjduques.github.io/blob/main/api/app/notify.py"

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_home,node_projects,node_project_detail,node_about,node_content,node_contact_form toneBlue
class node_api_service,node_settings,node_limiter,node_host_metrics toneAmber
class node_message_store,node_sqlite,node_n8n toneMint
class node_backup,node_notifier toneRose
class node_visitor,node_funnel,node_pages_host toneIndigo
```

## Components

### Portfolio frontend

- [Home page](https://github.com/jjduques/jjduques.github.io/blob/main/frontend/app/page.tsx): `frontend/app/page.tsx`
- [Project listing](https://github.com/jjduques/jjduques.github.io/blob/main/frontend/app/projects/page.tsx): `frontend/app/projects/page.tsx`
- [Project detail](https://github.com/jjduques/jjduques.github.io/blob/main/frontend/app/projects/%5Bslug%5D/page.tsx): `frontend/app/projects/[slug]/page.tsx`
- [Architecture page](https://github.com/jjduques/jjduques.github.io/blob/main/frontend/app/about/page.tsx): `frontend/app/about/page.tsx`
- [Portfolio content](https://github.com/jjduques/jjduques.github.io/blob/main/frontend/lib/content.ts): `frontend/lib/content.ts`
- [Contact form](https://github.com/jjduques/jjduques.github.io/blob/main/frontend/components/contact-form.tsx): `frontend/components/contact-form.tsx`

### Contact and health API

- [FastAPI endpoints](https://github.com/jjduques/jjduques.github.io/blob/main/api/app/main.py): `api/app/main.py`
- [Runtime settings](https://github.com/jjduques/jjduques.github.io/blob/main/api/app/config.py): `api/app/config.py`
- [Rate limiter](https://github.com/jjduques/jjduques.github.io/blob/main/api/app/ratelimit.py): `api/app/ratelimit.py`
- [Host metrics](https://github.com/jjduques/jjduques.github.io/blob/main/api/app/system.py): `api/app/system.py`

### Message persistence

- [SQLite access](https://github.com/jjduques/jjduques.github.io/blob/main/api/app/db.py): `api/app/db.py`
- **Contact database**

### Operations and notification

- [Database backup](https://github.com/jjduques/jjduques.github.io/blob/main/api/app/backup.py): `api/app/backup.py`
- [Pending notifier](https://github.com/jjduques/jjduques.github.io/blob/main/api/app/notify.py): `api/app/notify.py`

### Other components

- **Site visitor**
- **n8n webhook**
- **Tailscale Funnel**
- **GitHub Pages CDN**

## Connections

- Site visitor → GitHub Pages CDN: requests pages
- GitHub Pages CDN → Home page: serves static files
- Site visitor → Contact form: submits message
- Home page → Contact form: renders form (evidence: `frontend/app/page.tsx`)
- Home page → Portfolio content: loads portfolio data (evidence: `frontend/app/page.tsx`)
- Project listing → Portfolio content: loads projects (evidence: `frontend/app/projects/page.tsx`)
- Project detail → Portfolio content: loads project
- Site visitor → Tailscale Funnel: sends HTTPS request
- Tailscale Funnel → FastAPI endpoints: forwards request
- FastAPI endpoints → Runtime settings: loads settings (evidence: `api/app/main.py`)
- FastAPI endpoints → Rate limiter: checks limits (evidence: `api/app/main.py`)
- FastAPI endpoints → Host metrics: reads host metrics (evidence: `api/app/main.py`)
- FastAPI endpoints → SQLite access: reads and writes messages (evidence: `api/app/main.py`)
- SQLite access → Contact database: reads and writes
- FastAPI endpoints → Pending notifier: queues notification (evidence: `api/app/main.py`)
- Pending notifier → SQLite access: loads and updates pending (evidence: `api/app/notify.py`)
- Pending notifier → n8n webhook: posts webhook (evidence: `api/app/notify.py`)
- Database backup → SQLite access: creates safe copy (evidence: `api/app/backup.py`)
