# navadon/pubpub architecture

> Architecture diagram of the GitHub repository navadon/pubpub, 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/navadon/pubpub
- Repository: https://github.com/navadon/pubpub

## Overview

PubPub is a static publication dashboard for Computer Engineering staff at Chiang Mai University. The workflow is: refresh the staff roster, build publication data from OpenAlex or an optional Scopus export, enrich records with journal tiers and collaboration/keyword information, then display the generated dashboard. The README documents the page’s yearly and cumulative counts, SJR/CiteScore tiers, collaboration, staff totals, and research keywords. Frontend implementation details are not sampled, so its internal links are limited to documented behavior.

Main entry points: [`scripts/build_data.py`](https://github.com/navadon/pubpub/blob/main/scripts/build_data.py) (Data builder), [`index.html`](https://github.com/navadon/pubpub/blob/main/index.html) (Dashboard page), [`scripts/fetch_staff.py`](https://github.com/navadon/pubpub/blob/main/scripts/fetch_staff.py) (Roster fetcher), [`data/staff.json`](https://github.com/navadon/pubpub/blob/main/data/staff.json) (Staff records)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_roster["Staff roster"]
  node_staff_fetcher["Roster fetcher<br/>[fetch_staff.py]"]
  node_staff_data[("Staff records<br/>[staff.json]")]
end

subgraph group_builder["Publication data"]
  node_builder_script["Data builder<br/>[build_data.py]"]
  node_dashboard_data[("Dashboard data<br/>[dashboard.json]")]
  node_history_data[("Publication history<br/>[history.json]")]
end

subgraph group_inputs["Data sources"]
  node_sjr_data[("SJR rankings<br/>[sjr_latest.csv]")]
  node_citescore[("CiteScore tiers")]
end

subgraph group_dashboard["Dashboard"]
  node_dashboard_page["Dashboard page<br/>[index.html]"]
  node_publication_counts["Yearly and cumulative counts<br/>[index.html]"]
  node_journal_tiers["Journal quartiles<br/>[index.html]"]
  node_collaboration["Collaboration types<br/>[index.html]"]
  node_staff_totals["Per-staff totals<br/>[index.html]"]
  node_research_keywords["Research keywords<br/>[index.html]"]
end

node_staff_site(("Staff roster site"))
node_openalex(("OpenAlex"))
node_scopus(("Scopus export"))

node_staff_site -->|"provides roster"| node_staff_fetcher
node_staff_fetcher -->|"writes records"| node_staff_data
node_staff_data -->|"supplies staff"| node_builder_script
node_openalex -->|"provides works"| node_builder_script
node_scopus -.->|"optional export"| node_builder_script
node_sjr_data -->|"supplies rankings"| node_builder_script
node_citescore -.->|"optional tiers"| node_builder_script
node_builder_script -->|"writes dashboard"| node_dashboard_data
node_builder_script -->|"updates history"| node_history_data
node_dashboard_page -->|"reads data"| node_dashboard_data
node_dashboard_page -->|"presents counts"| node_publication_counts
node_dashboard_page -->|"presents tiers"| node_journal_tiers
node_dashboard_page -->|"presents types"| node_collaboration
node_dashboard_page -->|"presents totals"| node_staff_totals
node_dashboard_page -->|"presents keywords"| node_research_keywords

click node_staff_fetcher "https://github.com/navadon/pubpub/blob/main/scripts/fetch_staff.py"
click node_staff_data "https://github.com/navadon/pubpub/blob/main/data/staff.json"
click node_builder_script "https://github.com/navadon/pubpub/blob/main/scripts/build_data.py"
click node_sjr_data "https://github.com/navadon/pubpub/blob/main/data/raw/sjr_latest.csv"
click node_citescore "https://github.com/navadon/pubpub/tree/main/data/raw"
click node_dashboard_data "https://github.com/navadon/pubpub/blob/main/data/dashboard.json"
click node_history_data "https://github.com/navadon/pubpub/blob/main/data/history.json"
click node_dashboard_page "https://github.com/navadon/pubpub/blob/main/index.html"
click node_publication_counts "https://github.com/navadon/pubpub/blob/main/index.html"
click node_journal_tiers "https://github.com/navadon/pubpub/blob/main/index.html"
click node_collaboration "https://github.com/navadon/pubpub/blob/main/index.html"
click node_staff_totals "https://github.com/navadon/pubpub/blob/main/index.html"
click node_research_keywords "https://github.com/navadon/pubpub/blob/main/index.html"

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_staff_fetcher,node_staff_data toneBlue
class node_builder_script,node_dashboard_data,node_history_data toneAmber
class node_sjr_data,node_citescore toneMint
class node_dashboard_page,node_publication_counts,node_journal_tiers,node_collaboration,node_staff_totals,node_research_keywords toneRose
class node_staff_site,node_openalex,node_scopus toneIndigo
```

## Components

### Staff roster

- [Roster fetcher](https://github.com/navadon/pubpub/blob/main/scripts/fetch_staff.py): `scripts/fetch_staff.py`
- [Staff records](https://github.com/navadon/pubpub/blob/main/data/staff.json): `data/staff.json`

### Publication data

- [Data builder](https://github.com/navadon/pubpub/blob/main/scripts/build_data.py): `scripts/build_data.py`
- [Dashboard data](https://github.com/navadon/pubpub/blob/main/data/dashboard.json): `data/dashboard.json`
- [Publication history](https://github.com/navadon/pubpub/blob/main/data/history.json): `data/history.json`

### Data sources

- [SJR rankings](https://github.com/navadon/pubpub/blob/main/data/raw/sjr_latest.csv): `data/raw/sjr_latest.csv`
- [CiteScore tiers](https://github.com/navadon/pubpub/tree/main/data/raw): `data/raw`

### Dashboard

- [Dashboard page](https://github.com/navadon/pubpub/blob/main/index.html): `index.html`
- [Yearly and cumulative counts](https://github.com/navadon/pubpub/blob/main/index.html): `index.html`
- [Journal quartiles](https://github.com/navadon/pubpub/blob/main/index.html): `index.html`
- [Collaboration types](https://github.com/navadon/pubpub/blob/main/index.html): `index.html`
- [Per-staff totals](https://github.com/navadon/pubpub/blob/main/index.html): `index.html`
- [Research keywords](https://github.com/navadon/pubpub/blob/main/index.html): `index.html`

### Other components

- **Staff roster site**
- **OpenAlex**
- **Scopus export**

## Connections

- Staff roster site → Roster fetcher: provides roster (evidence: `scripts/fetch_staff.py`)
- Roster fetcher → Staff records: writes records (evidence: `README.md`)
- Staff records → Data builder: supplies staff (evidence: `README.md`)
- OpenAlex → Data builder: provides works (evidence: `README.md`)
- Scopus export → Data builder: optional export (evidence: `README.md`)
- SJR rankings → Data builder: supplies rankings (evidence: `README.md`)
- CiteScore tiers → Data builder: optional tiers (evidence: `README.md`)
- Data builder → Dashboard data: writes dashboard (evidence: `README.md`)
- Data builder → Publication history: updates history (evidence: `scripts/build_data.py`)
- Dashboard page → Dashboard data: reads data (evidence: `README.md`)
- Dashboard page → Yearly and cumulative counts: presents counts (evidence: `README.md`)
- Dashboard page → Journal quartiles: presents tiers (evidence: `README.md`)
- Dashboard page → Collaboration types: presents types (evidence: `README.md`)
- Dashboard page → Per-staff totals: presents totals (evidence: `README.md`)
- Dashboard page → Research keywords: presents keywords (evidence: `README.md`)
