3 min readCase study

MasterPlan: student–advisor and student–course matching in JavaScript

Pure JavaScript (ES5-style classes) for advisor–student pairing and course recommendations — no framework, just algorithms and CSV ingestion.

  • JavaScript
  • Algorithms
  • Education

MasterPlan: student–advisor and student–course matching in JavaScript

Before LLM rerankers, matching was tags and set containment. MasterPlan (2019) is pure JavaScript — no React, no backend — that scores advisor and course compatibility from CSV inputs and prints explainable recommendations.

#TL;DR

MasterPlan (2019) is a small JavaScript program — no React, no backend — that reads student, advisor, and course data and prints compatibility-based recommendations. README goals:

  • Student–advisor matching — implemented via AdvStudCompat objects and scheduler logic
  • Student–course matching — tag overlap + prerequisite checks, top-N course names per student

It is a batch CLI mindset prototype: load CSVs, compute scores, emit text. That pattern reappears in my later hybrid match scoring work — deterministic ranking first, language model second.


#How course matching works

Runner.js initializes courses and students, then for each student:

  1. getCompatibility — array parallel to every course
  2. checkPrereqs — student’s classesTaken must contain all course prerequisites
  3. Tag overlap — increment score when student and course tags align
  4. getMostCompatible — select top N course indices and print names
JavaScript
console.info(
  "\nHello " + student.getName() + ", the top " + Runner.numRecommended + " recommended courses for you are:",
);

The code reads like transpiled Java (typed-style comments, ArrayList wording) — likely from a course tooling pipeline. Maintaining it taught me to focus on data invariants (tags, prereq lists) before UI.


#Advisor matching

AdvStudCompat.js wraps a (student, advisor, compatibility) triple with getters. The scheduler consumes these objects to pair advisees — same compatibility theme as courses, different domain rules.


#Why it still matters on a portfolio site

SkillEvidence here
Explainable scoringNumeric compatibility, not black-box ML
Prerequisite graphsSet containment check — precursor to “can user access resource?”
Separation of concernsStudent.js, Course.js, Advisor.js, Scheduler.js modules

#Prerequisite gate (courses)

checkPrereqs is set containment — every course prerequisite must appear in the student’s completed list before tag overlap scoring runs. Courses that fail the gate stay at compatibility 0, regardless of tag match count:

JavaScript
Runner.prototype.checkPrereqs = function (course, student) {
  var preReqs = course.getPreReqs();
  var classesTaken = student.getClassesTaken();
  return preReqs.every(function (req) { return classesTaken.indexOf(req) >= 0; });
};

#Advisor assignment: global sort + greedy match

adviseeAssigned builds all (student, advisor) pairs, scores tag overlap as count / advisorTags.length, merge-sorts AdvStudCompat objects by compatibility, then assigns greedily from highest score downward while skipping already-matched students or advisors. Same explainable pattern as the later mobile BFF — numeric score first, narrative second.


#Closing thought

Matching engines are boring on purpose: tags, prerequisites, and additive scores give you an audit trail chat models skip. Ship the table first, then decide if language adds anything.


#Reader field guide

When deterministic matching beats ML first: You need explainable scores; prerequisites are set containment; stakeholders ask “why this course?”; batch CLI output is enough for v1.

Operational checklist

  • Gate courses with checkPrereqs before tag overlap — failed prereqs stay at score 0
  • Tag overlap is additive and auditable — log top-N indices, not black-box ranks
  • Advisor pairing: build all pairs, sort by compatibility, greedy assign without reusing students/advisors
  • Keep Student, Course, Advisor, Scheduler modules separate — data invariants before UI
  • Validate CSV inputs for missing tags or unknown prereq codes before scoring

Later echo: Same score-first pattern shows up in hybrid match scoring — deterministic rank, language model second.


#On this site

PostWhy
Building a Gemini AI backend with SSELater matching math—rules in code, language from the model
Public API course enrollment dashboardAnother “explainable pipeline” exercise with explicit HTTP boundaries

#References (curated)

No framework magic here—plain CSV + functions kept the matching rules auditable, which is the point.

ReferenceNotes
MasterPlan (2019 coursework)Tag overlap + prerequisite checks in plain JavaScript—local workspace, not published.
CSV parsing in NodeBatch runner input—validate headers before you score rows.
Explainable recommendation systemsWhy we kept scores inspectable instead of black-box ranks.