COMP courses — 2027
ANU’s course site (programsandcourses.anu.edu.au) only lets you check whether a course is actually running one course page at a time — and some courses that show up in the course search as if they’re offered turn out, on their own page, to have no current offering at all. This app checks every COMP-prefixed course’s own Offerings page directly for 2027 and lists all 128 of them in one flat, filterable table: real class number for First Semester, real class number for Second Semester, and whether the course has any current offering at all (27 of 128 don’t, despite sitting in the search results as if active). Filters combine — search, which semester it’s actually confirmed running, and course level (1000/2000/3000/4000/6000/8000) — rather than pre-sorting courses into fixed groups, so a reader can slice the list however they’re actually using it.
A second, small feature sits alongside it: courses are likeable and
markable-taken, two independent toggles per row. Liking is for a course
you’re considering; taken is for one you’ve already done. The list can be
sorted to show liked courses first, or filtered to hide taken ones outright,
and /my-courses/ pulls both into one shortlist view. All of it is saved
and shared with everyone, surviving a reload the way the list of courses
itself deliberately doesn’t (that list gets replaced wholesale by the latest
scrape on every boot). Every toggle is a plain HTML form post underneath, so
it works with JavaScript off; with it on, a small script asks the same
endpoint for JSON instead of a redirect and patches the button in place, so
marking a course taken doesn’t reload the page.
What good looks like here
The headline promise is trustworthiness of the data, not completeness of the
UI: every class number shown on / is read directly from a real fetch of
that course’s own ANU page (scripts/scrape-courses.ts), never guessed from
the catalogue search alone — that search field is shown alongside the scraped
truth specifically so a reader can see ANU’s own claim next to what was
actually found and check the app’s work. The rules that decision produced
live in CLAUDE.md.
What’s enforced (see spec/): every scraped course code appears on the list,
each links out to its own ANU page so the claim is checkable, and the
offering/level filters each show exactly the matching courses. What’s a
judgement call, not a test: whether a flat, filterable table communicates the
“no current offerings” surprise as clearly as separated groups would, and
whether the course data is current — the scrape is a point-in-time snapshot,
re-run by hand (pnpm run scrape:courses), not live.
What I chose not to build: accounts or authentication (likes are shared and anonymous, same as the starter’s guestbook was), live cross-tab updates (a course list doesn’t change second-to-second the way a chat does), and coverage beyond COMP-prefixed courses (scoped deliberately — the brief asks for a slice, not the whole system).