Documentation Index
Fetch the complete documentation index at: https://mintlify.com/cornell-dti/course-plan/llms.txt
Use this file to discover all available pages before exploring further.
Courseplan is a single-page application built with Vue 3 and TypeScript, bundled by Vite, with global state managed by Vuex 4 and persistence handled by Firebase/Firestore. Understanding how these layers connect makes it straightforward to find where any given piece of behaviour lives.
Tech stack
| Layer | Technology |
|---|
| UI framework | Vue 3 (Composition API + Options API) |
| Type system | TypeScript ≤ 4.1.5 |
| Global state | Vuex 4 (src/store.ts) |
| Build tool | Vite 2 |
| Backend / auth | Firebase 9 (Firestore + Google Auth) |
| Styling | SCSS + Bootstrap 4 |
| Testing | Jest (unit) + Cypress (e2e) |
Key directories
src/
├── components/ # Reusable Vue components (modals, course cards, semester rows, …)
├── containers/ # Page-level container components (App.vue, onboarding, …)
├── requirements/ # Requirement computation engine
│ ├── types.ts # Shared TypeScript types (CollegeOrMajorRequirement, RequirementChecker, …)
│ ├── requirement-graph.ts # RequirementFulfillmentGraph data structure
│ ├── requirement-graph-builder.ts # Builds the graph from decorated requirements + user courses
│ ├── requirement-frontend-computation.ts # Produces GroupedRequirementFulfillmentReport for the UI
│ └── requirement-json-generator.ts # CLI script: compiles TS requirement files → JSON
├── data/
│ ├── majors/ # Per-major requirement definitions (cs.ts, ece.ts, …)
│ ├── colleges/ # Per-college requirement definitions (en.ts, as.ts, …)
│ └── index.ts # Aggregates all requirement data
├── store.ts # Vuex store — single source of truth for all runtime state
├── firebase-config.ts # Firebase project initialisation
├── feature-flags.ts # GateKeeper feature flag system
└── schedule-generator/ # Experimental schedule-generation logic
Data flow
Firestore is the persistent source of truth. On login, the store subscribes to the user’s Firestore document via onSnapshot. Every mutation in the store that changes user data writes back to Firestore via setDoc / updateDoc.
Firestore (cloud)
│ onSnapshot (realtime listener)
▼
store.ts ─── Vuex mutations / actions ───► Firestore (writes)
│
│ reactive state
▼
Vue components ── computed properties ──► rendered UI
Vuex store state shape
VuexStoreState in src/store.ts defines every field held in memory at runtime:
export type VuexStoreState = {
// Auth
currentFirebaseUser: SimplifiedFirebaseUser;
userName: FirestoreUserName;
// Onboarding / profile
onboardingData: AppOnboardingData; // college, major, minor, grad year, exam credits, …
orderByNewest: boolean;
// Course data (derived from semester semesters for perf)
derivedCoursesData: DerivedCoursesData; // courseMap, courseToSemesterMap, duplicates
// Requirement fulfillment
toggleableRequirementChoices: AppToggleableRequirementChoices;
overriddenFulfillmentChoices: FirestoreOverriddenFulfillmentChoices;
userRequirementsMap: Readonly<Record<string, RequirementWithIDSourceType>>;
dangerousRequirementFulfillmentGraph: RequirementFulfillmentGraph<string, CourseTaken>;
safeRequirementFulfillmentGraph: RequirementFulfillmentGraph<string, CourseTaken>;
courseToRequirementsInConstraintViolations: ReadonlyMap<string | number, Set<string[]>>;
doubleCountedCourseUniqueIDSet: ReadonlySet<string | number>;
groupedRequirementFulfillmentReport: readonly GroupedRequirementFulfillmentReport[];
// UI / display
subjectColors: Readonly<Record<string, string>>;
uniqueIncrementer: number;
uniqueBlankCourseIncrementer: number;
isTeleportModalOpen: boolean;
// Plans and saved courses
plans: readonly Plan[];
currentPlan: Plan;
savedCourses: readonly Collection[];
allSavedCourses: Collection;
};
Requirements computation pipeline
Requirement fulfillment is computed in several sequential stages each time the user’s courses or profile changes:
src/data/* (TypeScript source)
│
│ npm run req-gen
▼
src/assets/requirements/decorated-requirements.json (pre-computed eligible course IDs)
│
│ requirement-graph-builder.ts
▼
RequirementFulfillmentGraph<string, CourseTaken> (bipartite: requirements ↔ courses)
│
│ requirement-frontend-computation.ts
▼
GroupedRequirementFulfillmentReport[] (one report per college / major / minor)
│
│ Vuex store → reactive props
▼
Requirements sidebar + course row indicators (UI)
The graph is computed twice per state change — a dangerousRequirementFulfillmentGraph that allows double-counting and a safeRequirementFulfillmentGraph that does not — so the UI can highlight conflicts.
decorated-requirements.json is a build artifact checked into the repository. It must be regenerated via npm run req-gen whenever requirement TypeScript files change. See Adding and updating requirements for details.