ANU’s enrolment site lets you get most of the way through signing up for a course before telling you that you’re not actually allowed to take it — a missing prerequisite or permission code shows up on the last screen, after you’ve already picked a time slot and read the outline. This prototype inverts that: it shows every course sorted by whether your transcript already clears it, before you try to enrol in anything.
It’s dressed as the student portal of Molonglo University, which is fictional. Log in with any username and password; there’s no real authentication (see below). A brand-new username is offered a randomly generated but plausible transcript, so the portal starts populated instead of empty. The homepage is a tile hub, like a real student-administration system, covering timetable, degree planning, finances and personal details, but only Enrolment, Academic Records and a testing tool are built. Every other tile is visibly marked under construction and isn’t a link, so there are no dead pages to fall into.
Enrolment (/enrolment/) is the point of the prototype. As in the real
portal, you search by subject area first: 196 real ANU courses across eleven
disciplines, from Computer Science to Psychology and History. Unlike the real
portal, each result row already says whether you can take the course:
eligible, enrolled, completed, or not eligible, with the specific reason
(“Needs COMP2300 or ENGN2219”, “Permission required”). The cue is deliberately
quiet, just an edge stripe, a dot and a few words, so a whole subject fits on
one screen at one line per course. Academic Records (/records/) is the
read-only transcript those verdicts are computed from.
What good looks like here
The core bet is that eligibility should be legible before commitment, not revealed after it. Everything else follows from that:
- Reasons, not just verdicts. A blocked course says why — which prerequisite group is unmet, or that it needs a School permission code — so the page functions as a plan (“take COMP2100 next, then COMP3600 opens up”), not just a pass/fail stamp.
- Colour as a second channel, not the only one. Each bucket has a heading and its own section, so the distinction survives without colour; the flat background tints (green/blue/grey/red/amber) are there so the eye doesn’t have to read headings to sort five buckets. Every status also carries a text label, so nothing depends on colour alone. The brand colours (navy and terracotta) stay out of the status palette, so colour inside the enrolment list always means eligibility and never decoration.
- Look like the real thing, but not be a real thing. The layout follows a PeopleSoft-style university portal (crest header, dark toolbar, tile homepage) so the redesign is judged against what students actually use. The university is invented on purpose: a public site styled as a real university’s portal, with a login form that echoes passwords back, would work as a credential-phishing page. The crest and tile illustrations were generated for this project (recraft-v3, one shared style prompt) and imitate no real institution’s marks.
- Real prerequisite data, not toy examples. The courses, terms, and prerequisite structure come from ANU’s actual Programs & Courses pages, modelled as AND-of-OR groups (a course can need A and (B or C)). An option can be a course, a unit count (“6 units of MATH, excluding MATH1003”, “12 units of 2000-level COMP”), or a co-requisite you may be enrolled in right now. Incompatible courses block you. A blocked row says what’s missing and how far off you are (“24 units of COMP (you have 6)”). Three things genuinely can’t be checked from a transcript: program membership, mark thresholds and convener discretion. An otherwise-eligible course with one of those says “Eligible · check requirement” rather than pretending to know. Where a course has alternative pathways, only the main one is checked and the rest are listed in the note. The catalogue is a sample, so a few courses depend on courses outside it, such as superseded BIOL codes. Those courses stay “not eligible”, and god mode can’t mark their requirements passed.
- The login is a testing harness, not a feature. The brief was to
prototype the eligibility view, which means testing it against many
different plausible transcripts matters more than the login itself. So:
- Any username/password combination works. A new username creates an account on the spot with whatever password was typed — there’s no separate signup.
- Because there’s no real security here, the “forgot password” flow is a joke instead of a feature: get the password wrong three times in a row and the portal just tells you what you set it to. It’s the honest version of what “no auth” already implies.
- A fresh account is offered a randomly generated transcript — a plausible 1st/2nd/3rd-year mix of courses that actually satisfies each other’s prerequisites, generated by walking the same prerequisite-group data the eligibility page reads, so the demo data and the real logic never disagree with each other.
- God mode (
/god-mode/) lets you set exactly which courses a user has passed or failed directly, bypassing prerequisites entirely, so you can hand-construct an edge case (someone who failed a prerequisite, someone one course short of a permission gate) in seconds rather than hoping the randomiser produces it.
- Two tables, two concerns.
coursesandprerequisite_groupsare the shared catalogue — one copy, true for everyone.users,completed_coursesandenrolmentsare per-student state. Nothing about a student’s transcript is denormalised into the catalogue, and nothing about the catalogue is duplicated per student; the eligibility check reads both and joins them at request time.
Enforced vs. judgement
spec/invariants.test.ts enforces the baseline true of any page here: a
language tag, one <h1>, a nav landmark, alt text, and an axe-core
accessibility pass. It sweeps /, /enrolment/, /records/, /login/ and
/readme/, which all render a real logged-out page rather than redirecting.
/welcome/ and /god-mode/ require a logged-in session and the invariants
fetch cold, so they’re deliberately left out rather than faked with a session
the test harness doesn’t have.
What’s not enforced by any check, and is a judgement call instead:
- Whether the colour choices for the five buckets are actually distinguishable
and not just “different” — axe’s
color-contrastrule is disabled in the jsdom-based invariants run (no real layout to measure against), so this is eyeballed, not tested. - Whether the blocked-course explanations are actually the clearest way to phrase “why not,” versus e.g. always naming every missing course.
- Whether the random transcript generator produces genuinely plausible student histories, versus merely prerequisite-valid ones — validity is mechanical, plausibility isn’t.
- Whether the portal reads as a credible university system. That’s a judgement against the real portals it imitates, not something a test can hold. So is whether the under-construction tiles read as “not built yet” rather than as broken.