Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

716 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

dads2busy.github.io

Personal academic portfolio website + curriculum vitae for Aaron D. Schroeder, Ph.D. β€” Research Associate Professor, Social & Decision Analytics Division, University of Virginia Biocomplexity Institute.

πŸ”— Live site: https://dads2busy.github.io πŸ“„ Vita PDF: https://dads2busy.github.io/vita.pdf


Architecture in 60 seconds

One YAML file is the single source of truth. Tooling renders it into multiple outputs.

                          Data-build layer (write to SSOT)
                          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
External sources          β”‚ scripts/analyze_sources.py        β”‚ ← LLM-extracts CV/DOCX
  CV / DOCX     ─────────▢│ scripts/orcid_works.py            β”‚ ← ORCID API + diff
  ORCID API               β”‚ scripts/fill_missing_fields.py    β”‚ ← propose blanks to fill
                          β”‚   (all emit review diffs;          β”‚
                          β”‚    NEVER auto-edit profile.yaml)   β”‚
                          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                          β”‚ human paste
                                          β–Ό
                         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                         β”‚  site/content/profile.yaml (SSOT) β”‚
                         β”‚  site/content/site_extras.yaml    β”‚
                         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                          β”‚
                          Delivery layer (read from SSOT)
                          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                          β”‚ scripts/profile_to_content_jsons  β”‚
                          β”‚   β†’ 5 site content JSONs           β”‚
                          β”‚   β†’ website pages render            β”‚
                          β”‚                                    β”‚
                          β”‚ rendercv render β†’ vita.pdf         β”‚
                          β”‚                                    β”‚
                          β”‚ site/src/app/page.tsx              β”‚
                          β”‚   β†’ home page (reads YAML directly)β”‚
                          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Full architecture details: see ARCHITECTURE.md.


Where to make common changes

Add or edit a publication

Edit site/content/profile.yaml β€” find the matching publication-style section (Refereed Journal Articles, Book Chapters, Research / Technical Reports, etc.) and add/edit the entry. Use the existing entries' shape as a template.

Add or edit a presentation/talk

Edit site/content/profile.yaml β€” Presentations: section. Set subcategory: to one of: Panelist, Presentations/Workshops, Committee, Lecture, Expert Forum, Expert Webinar.

Add or edit a research project

Edit site/content/profile.yaml β€” Research Projects: section. Fields: name, funder, award, role, date, summary, slug.

Update bio / education / skills / awards (home page)

Edit site/content/profile.yaml β€” Summary, Education, Skills, Awards & Honors sections. The home page reads these directly via js-yaml at build time.

Update tagline or polymath callout

Edit site/content/site_extras.yaml. Validated by a Zod schema at site/src/lib/site-extras-schema.ts.

Change presentation category order on /speaking

Edit CATEGORY_ORDER in site/src/app/speaking/page.tsx.

Change citation rendering

Change vita PDF look

Edit design.theme: in profile.yaml (currently classic). RenderCV ships several built-in themes; full customization via custom RenderCV themes.

Bulk-import new entries from a CV/DOCX

Drop the file into sources/cvs/, then run:

.venv/bin/python scripts/analyze_sources.py

Review sources/_diff.md (gitignored) and hand-paste accepted entries into profile.yaml. The script never touches profile.yaml directly.

Sync new publications from ORCID

.venv/bin/python orcid_works.py

Review orcid_diff.md (gitignored). Same paste workflow.

Sync new datasets from Zenodo

.venv/bin/python scripts/zenodo_works.py

Review zenodo_diff.md (gitignored). Same paste workflow β€” proposed entries land in profile.yaml's Data & Software section.

Find missing fields across profile.yaml

.venv/bin/python scripts/fill_missing_fields.py

Reviews profile.yaml for blank name/category fields, suggests derivations, writes profile_fill_diff.md.


Local development

Setup (one-time)

# Python venv for build tooling + RenderCV
python3 -m venv .venv
.venv/bin/pip install -r scripts/requirements.txt

# Node deps for the website
cd site && npm ci

Set up .env at the repo root with:

ORCID_CLIENT_ID=APP-...           # for orcid_works.py
ORCID_CLIENT_SECRET=...
ORCID_ID=0000-0003-4372-2241
ANTHROPIC_API_KEY=sk-ant-...      # for analyze_sources.py

Run the dev server

cd site && npm run dev   # http://localhost:3000

The predev npm script automatically regenerates the 5 content JSONs from profile.yaml before starting the dev server, so any YAML change is visible after the next page reload.

Build the static site locally

cd site && npm run build

Output lands in site/out/. The prebuild npm script regenerates JSONs first.

Generate the vita PDF locally

cd site && npm run gen:vita

Output: site/public/vita.pdf (gitignored). CI also runs RenderCV on every push.

Run tests

.venv/bin/pytest scripts/tests/

108 tests cover the data-build/delivery libraries.


Tech stack

Layer Tools
Frontend Next.js 16 (App Router, TypeScript, static export), Tailwind CSS v4, Google Fonts (Inter / Instrument Serif / Geist Mono)
YAML loading js-yaml + zod (validates site_extras.yaml) at build time
SSOT site/content/profile.yaml (RenderCV-format YAML with custom keys)
Vita PDF RenderCV (Python) β€” classic theme
CV / source analyzer Anthropic Claude API (claude-sonnet-4-6) + mammoth for DOCX
ORCID sync Python urllib against ORCID Public API v3.0
Tests pytest (Python side); Next.js build is the implicit test on the JS side
Deployment GitHub Actions β†’ GitHub Pages

Repository layout

.
β”œβ”€β”€ site/                          # Next.js project
β”‚   β”œβ”€β”€ content/
β”‚   β”‚   β”œβ”€β”€ profile.yaml           # SSOT β€” edit this for content
β”‚   β”‚   └── site_extras.yaml       # Site-only display fields
β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”œβ”€β”€ app/                   # App Router pages
β”‚   β”‚   β”œβ”€β”€ components/            # WritingCitation, SpeakingCitation, etc.
β”‚   β”‚   └── lib/                   # types, content loader, schemas
β”‚   └── public/                    # Static assets, generated vita.pdf
β”œβ”€β”€ scripts/
β”‚   β”œβ”€β”€ profile_to_content_jsons.py    # SSOT β†’ 5 site JSONs (delivery)
β”‚   β”œβ”€β”€ json_emitters.py               # Per-section converters
β”‚   β”œβ”€β”€ analyze_sources.py             # Plan G: CV/DOCX β†’ review diff
β”‚   β”œβ”€β”€ analyzer_lib.py                # Source analyzer helpers
β”‚   β”œβ”€β”€ orcid_diff_lib.py              # Plan E: ORCID diff helpers
β”‚   β”œβ”€β”€ fill_missing_fields.py         # Plan H: blank-field review tool
β”‚   β”œβ”€β”€ profile_derive_lib.py          # Plan H: title/category derivation
β”‚   └── tests/                         # pytest suite (108 tests)
β”œβ”€β”€ sources/                       # Drop-zone for raw artifacts
β”‚   β”œβ”€β”€ cvs/                       # Old vitae (DOCX) for analyzer ingest
β”‚   └── README.md                  # Drop-zone workflow
β”œβ”€β”€ orcid_works.py                 # Plan E: ORCID fetcher + diff
β”œβ”€β”€ orcid_works.json               # ORCID snapshot (committed)
β”œβ”€β”€ docs/superpowers/plans/        # Implementation plans (Plans A–H)
β”œβ”€β”€ ARCHITECTURE.md                # Data-build vs delivery layer details
β”œβ”€β”€ SSOT_PLAN.md                   # Higher-level SSOT vision
β”œβ”€β”€ .github/workflows/deploy.yml   # CI: render vita + build + deploy
└── old jekyll site/               # Archived original Jekyll site

Contributing / extending

  • Add a new delivery output (e.g. CSL JSON for Zotero, LinkedIn paste view): write a pure Python emitter in scripts/, mirror the profile_to_content_jsons.py pattern, add shape-completeness tests.
  • Add a new section to profile.yaml: append to cv.sections.<NewSection>. RenderCV will pick it up automatically. The website's content pages only render sections explicitly mapped in WRITING_SUBCATEGORY (in profile_to_content_jsons.py).
  • Add a new delivery template: each delivery has its own format/template β€” RenderCV theme for the vita, React components for the website. Don't push delivery-specific formatting back into profile.yaml.

See ARCHITECTURE.md for the design principles, and docs/superpowers/plans/ for the historical implementation plans (each documents a chunk of the migration from the original Jekyll site).


License

Content is licensed under Creative Commons Attribution 4.0. Code is MIT-licensed where not otherwise noted.

About

Personal academic portfolio website for Aaron D. Schroeder, Ph.D. -- Research Associate Professor at the Social & Decision Analytics Division, University of Virginia Biocomplexity Institute.

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages