An interactive curriculum map for the West Chester University Computer Science department. Single-page, static, runs entirely in the browser. D3 + a small custom column layout for the chart, vanilla DOM for everything else.
Live: https://courseflowchart.pages.dev/
.
├── public/
│ ├── index.html Public flowchart — HTML, CSS, JS, embedded catalog fallback.
│ └── admin.html Admin console (login → editor + AI chat).
├── functions/
│ ├── _shared/auth.js HMAC-signed session cookie helpers.
│ └── api/
│ ├── catalog.js GET — public, returns KV value.
│ ├── login.js / logout.js / me.js
│ └── admin/
│ ├── catalog.js POST — write KV (auth required).
│ ├── fetch-wcu.js POST — scrape WCU catalog pages.
│ └── chat.js POST — Workers AI chat proxy.
├── wrangler.toml Cloudflare Pages project config + KV + AI bindings.
├── .gitignore
└── README.md
The same chart serves five different program views via hash routing:
| Path | View |
|---|---|
/ |
BS in Computer Science (default) |
/#/minor/cs |
Minor in Computer Science |
/#/minor/it |
Minor in Information Technology |
/#/ms |
MS in Computer Science |
/#/ms/accelerated |
Accelerated BS → MS |
Each view filters the underlying catalog to just the courses in that program.
The Accelerated view also draws the nine mutual-exclusion course pairs
(CSC 525 ↔ CSC 331, …) as red dashed links and adds a red ! badge on
each card in a pair. Hovering or tapping one course in a pair puts a big
red ✕ on its partner.
- Column-based layout — each course level (100 / 200 / 300 / 400 / 500 / 600) is its own column; long columns wrap into sub-columns automatically.
- Mobile layout — sidebar becomes a left drawer, details panel becomes a bottom sheet, first-time hint explains tap / double-tap / drag.
- Map Key floating panel on wide desktops; auto-positions out of the way of the details panel; draggable.
- Cybersecurity and Cloud Engineering certificates are highlighted
via the sidebar's Programs filter. Member courses show a green
Sor pinkCdot on the card. - Junior standing is rendered as a virtual node in the Prerequisites column with a dashed amber edge to the BS courses that accept it as an alternative prereq.
- Program rules sidebar section lists the WCU stipulations for the MS and Accelerated programs.
Visit /admin and sign in. The console has two panels:
- Catalog editor — pre-loaded with whatever is currently in KV. Buttons:
- Fetch from WCU scrapes the two catalog pages (UG + Grad) via a Pages Function (no CORS issues) and overwrites the editor with the parsed text in our flat format.
- Revert restores the last-saved version.
- Save writes to KV. The public page picks up the new text on next
load (it fetches
/api/catalogwithcache: 'no-store').
- AI assistant — chat with Llama 3.3 70B (Workers AI). The assistant
sees your current catalog text plus the read-only
COURSE_METAandACCEL_EXCLUSIONSextracted fromindex.html. When it returns a JSON patch in a ```json fence:catalogPatch: full replacement text → an Apply to editor button.metaPatch/metaRemove/exclusionsAdd/exclusionsRemove: structural changes that live in source → a Copy meta patch button that puts the JSON on your clipboard. You paste it intopublic/index.html, commit, redeploy.
Run these once before the admin works:
# the password you'll type into the login form
wrangler pages secret put ADMIN_PASSWORD --project-name courseflowchart
# any long random string — used to sign session cookies
wrangler pages secret put SESSION_SECRET --project-name courseflowchartUsername is hard-coded to schen in functions/api/login.js. Change the
ADMIN_USERNAME constant if you want a different one.
The catalog is also embedded as a fallback template literal in
public/index.html named DEFAULT_CATALOG. If KV
is empty (or the function is down), the page renders from this fallback.
You can also edit the fallback directly if you prefer source-level
control. Each course is one block:
CSC 141. Computer Science I. 3 Credits. <description>. Prerequisite: CSC NNN.
The parser also accepts Prerequisites:, Pre / Co requisites:, and the
CSC NNN Prerequisite: … form. It extracts course codes after the
prerequisite keyword and treats {… or …} groups as additional prereqs.
Course-level metadata (which program it belongs to, certificate flags,
accelerated-MS pairing, free-text prereq notes, etc.) lives in the
COURSE_META object right next to DEFAULT_CATALOG. To add a new course,
add a block to DEFAULT_CATALOG and, if it needs metadata, a matching
entry in COURSE_META.
To add a new mutual-exclusion pair for the Accelerated program, append to
ACCEL_EXCLUSIONS:
const ACCEL_EXCLUSIONS = [
['CSC 525', 'CSC 331'], // Operating Systems
// …
];Hosted on Cloudflare Pages (project name
courseflowchart). After editing public/index.html:
# Push changes to GitHub (history).
git add . && git commit -m "update catalog" && git push
# Publish to Cloudflare Pages production.
wrangler pages deploy public --project-name courseflowchartThere is no build step — the file in public/ is served as-is.
# 1. Install wrangler.
brew install cloudflare-wrangler # or npm install -g wrangler
# 2. Log in to Cloudflare.
wrangler login
# 3. Verify the Pages project exists; if not:
# wrangler pages project create courseflowchart --production-branch mainIn the Cloudflare dashboard:
- Workers & Pages →
courseflowchart→ Settings → Builds & deployments. - Connect Git → choose this GitHub repo, branch
main. - Build command: leave empty. Build output directory:
public.
After that, every git push origin main triggers a Pages deployment
automatically.
# Cheap option — works for everything except the legacy /api/catalog
# fallback (which the app no longer needs).
open public/index.html
# Or with wrangler (matches the deployed env).
wrangler pages dev public- D3 v7 (via CDN) — rendering, zoom, transitions.
- A small custom Sugiyama-style column layout — no
dagredependency. - Cloudflare Pages — static hosting + global CDN.
Internal department use.