Planner-Of-Steel Inspiration

UofT students know what's required and what they've done, but never what to take next to actually reach graduation without hitting a prerequisite wall. We wanted the tool UofT should have shipped: give it your transcript and program, get back a real plan.

What it does

Takes completed courses (pasted transcript, uploaded image, or picked list), program(s), and optional constraints — co-op, target grad date, specific elective wishes — and produces a full multi-semester plan. Resolves real prerequisites from live UofT data, respects credits and breadth, handles co-op terms properly, and supports group planning.

How we built it

We split the problem: Claude handles messy natural-language text (transcripts, requirement prose, elective ranking); a deterministic TypeScript algorithm (planner.ts) handles the actual scheduling — we don't trust an LLM with that. A Steel.dev + Playwright scraping pipeline pulls live UofT calendar/timetable data, and retrieveTree.ts parses free-text prerequisites into a structured AND-of-OR dependency graph. Standard Express/TypeScript backend, Vite/React/TypeScript frontend styled to sit alongside ACORN.

Challenges we ran into

Some prerequisite strings have no course code at all ("consent from the Supervisor of Studies"), so our parser produced empty — vacuously true — requirement groups, quietly scheduling fourth-year courses in first year. Fixed generally with a year-level credit floor plus consent detection. We also hit co-op semesters getting stacked with a full course load next to a 0-credit work term, since credit capping ran after course-picking, not before. And elective "pick one" slots could get consumed by the first reachable option, burying a student's actual requested (but not-yet-eligible) choice — fixed with a bounded "wait for your top choice" mechanism.

Accomplishments that we're proud of

Fully deterministic, testable scheduling — every fix came from a real regression test, not a hope that an LLM guessed right. The hard line between "Claude reads text" and "the algorithm decides" made every bug debuggable.

What we learned

The real difficulty wasn't the AI — it was UofT's messy, inconsistent calendar prose. And that you don't hand a deterministic problem to an LLM for convenience: keeping scheduling unambiguously on the algorithm's side made every bug fixable, not a black box.

What's next Proper customization of Co-op work terms and summer terms into the planner.

Built With

Share this project:

Updates

Submission history