data/ I/O layer
Four thin I/O adapters. No business logic. Each module wraps one type of external resource: the course catalog JSON, the major/minor requirement JSON files, and browser localStorage. Called exclusively by PlannerContext.
Children
module
courseLoader.js
Fetches the 6.5 MB course catalog JSON. Tries bundled file first, falls back to live API.
module
majorLoader.js + minorLoader.js
Async-fetches Major2 requirement JSON from the graduatenu fork. Provides grouped dropdown options.
module
persistence.js
Reads and writes plan state to browser localStorage. Three functions: loadSaved, saveState, clearState.
Full data pipeline
sequenceDiagram
participant App as App startup
participant PS as persistence.js
participant CL as courseLoader.js
participant LS as localStorage
participant FS as public/ (static files)
participant ML as majorLoader.js
participant GN as graduatenu/ fork
App->>PS: loadSaved()
PS->>LS: read ncp-plan-index, ncp-active-plan, ncp-plan-data-{id}
LS-->>PS: saved JSON or null
PS-->>App: hydrated state (or defaults)
App->>CL: fetchCourses()
CL->>FS: GET /all-courses.json
FS-->>CL: 6.5 MB JSON array
CL-->>App: Course[] (raw)
Note over App: normalizeCourse() called for each
Note over App: User selects major in GradPanel
App->>ML: loadMajor(path)
ML->>GN: GET parsed.initial.json
GN-->>ML: Major2 requirement tree
ML-->>App: major JSON
Note over App: Any state mutation
App->>PS: saveState(persist, planObj)
PS->>LS: write ncp-plan-data-{id}
Complete data flow from app start through user interaction. All I/O goes through this layer.
External data sources
| Source | What it is | How updated |
|---|---|---|
public/all-courses.json | 4,800+ normalized course objects. 6.5 MB. Bundled at build. | npm run scrape + npm run patch + commit |
graduatenu/packages/api/src/major/ | 1,471 Major2 JSON files. Served as static assets. | Scraped from Northeastern catalog. Patched by fix-pooled-requirements.js. |
localStorage | Plan data, settings, theme. Per-browser. | Auto-saved on every state mutation (when persistEnabled=true) |
husker.vercel.app/courses/all | Live course API (fallback only) | Maintained by nu-courses author. Only used if bundled JSON fails to load. |