Skip to content

CourseCompilerTeam/CourseCompiler

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

246 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CourseCompiler: UCLA 4-Year Class Planner

CourseCompiler helps UCLA Engineering students plan their 4-year degree path. You can drag and drop courses into a quarterly schedule, see which requirements you need to meet, what prerequisites each class has and track your progress toward graduation.

What It Does

The app lets you search for your engineering major, see all the available classes, and build a plan by dragging courses into quarters. It checks prerequisites automatically and warns you if you're taking too many units. You can save multiple plans and switch between them.

Main Features

Course Planning

  • See all required courses for your major loaded from our database
  • Drag courses into a 4-year quarterly schedule
  • System blocks you from adding classes with a visual warning if:
    • you haven't taken prerequisites
    • a quarter would exceed 21 units

Progress Tracking

  • See how much of your degree you've completed
  • Track progress by requirement type (Prep, Major, Tech Breadth, Sci-Tech, GE, etc.)
  • Progress bar shows completion percentage for each requirement category

Saving Plans

  • Create an account to save your plans
  • Save multiple plans and switch between them
  • Your plans are stored in the database

Search

  • Search for engineering majors with real-time suggestions
  • Results are ranked by relevance (exact matches first, then partial matches)

How It's Built

The frontend is React with Vite. We use React Router for navigation and @dnd-kit for the drag-and-drop functionality. We utilized React Bits for some visual components such as the electric border on the classes and the dots on the homepage. State is managed with React Context (for auth and major selection) and custom hooks for different features.

The backend is Express.js with Prisma as our ORM. We use MySQL for the database. Authentication uses JWT tokens, and passwords are hashed with bcrypt. The server code is organized into separate folders for middleware, controllers, the routes, and the configuration.

We organized the code into custom hooks so each piece has a single, clear responsibility. API calls go through service functions, and protected routes use JWT middleware.

Architecture Diagrams

1. Component Structure Diagram

This diagram shows how React components and hooks are organized and how they interact with each other.

Component Structure Diagram

The App component wraps everything with AuthProvider and MajorProvider for global state management. The DegreePlan page uses the usePlanManager hook, which coordinates useCategorizedCourses (fetches and categorizes courses), useDragAndDrop (handles the drag-and-drop logic), and useCourseValidation (checks prerequisites). PlanGrid renders the 4×4 grid of quarters, and CourseSidebar displays the categorized courses. Components like SavePlanButton, SavedPlansButton, and ProgressBar interact with the plan manager to provide the full functionality.

2. Database Schema Diagram

This ER diagram shows how the database tables relate to each other.

Database Schema Diagram

Users can have multiple Plans. Each Plan belongs to one Major and has multiple Quarters. Each Quarter has multiple classes which are shown through the PlanClasses join table. Majors have Requirements through MajorRequirementGroup (which links to RequirementGroup), and Requirements link to Classes through RequirementClasses. Classes can have Prerequisites pointing to other Classes. The schema supports complex prerequisite relationships and tracks which classes fulfill which requirements.

3. Application State Diagram

This shows the different states the application can be in and how it transitions between them.

Application State Diagram

The application starts at HomeScreen where users can search for engineering majors. Selecting a major transitions to LoadingPlan, then to PlanReady where users can drag and drop courses. The PlanReady state includes nested states for dragging, validating drops, saving plans, and browsing saved plans. Users can also authenticate from HomeScreen, which transitions to the Authenticating state.

4. Major Search Sequence Diagram

This sequence diagram shows how major search and course data retrieval works.

Major Search Sequence Diagram

When a user types in the search bar, the app fetches all engineering majors from the server. The server queries the database through Prisma and returns a list of major names. The client filters and ranks suggestions locally. When a user selects an engineering major, the app navigates to the degree plan page and fetches detailed course data including classes, requirements, and prerequisites. The server performs complex joins to retrieve all related data and transforms it into the format the client needs.

5. Authentication Sequence Diagram

This sequence diagram shows how user authentication (signup and login) works.

Authentication Sequence Diagram

For signup, the client sends user credentials to the server, which hashes the password with bcrypt and creates a user record in the database. After successful signup, the app automatically logs the user in. For login, the server compares the provided password with the stored hash, and if valid, generates a JWT token. The client stores the token and user data in localStorage for future authenticated requests.

6. Plan Saving Sequence Diagram

This sequence diagram shows how plans are saved, retrieved, and loaded.

Plan Saving Sequence Diagram

When saving a plan, the client serializes the drag-and-drop zones into a quarters array and sends it to the server with authentication. The server validates the JWT token, looks up the major, and creates the plan with nested quarters and plan classes in a database transaction. When browsing plans, the server fetches all plans for the authenticated user with all related data. When loading a plan, the client deserializes the quarters back into the zone structure and updates the UI.

Getting Started

What You Need

  • npm
  • The .env file (ask a team member for it)

Setup

  1. Clone the repo

    git clone <repository-url>
    cd CourseCompiler
  2. Set up the server

    cd server
    npm install
    npx prisma generate

    You'll need a .env file in the server/ folder with your database info:

    DB_URL=mysql://user:password@host:port/database
    ACCESS_TOKEN_SECRET=your_jwt_secret_key
    OPENAI_API_KEY=your_openai_api_key  # Optional: only needed for AI chat feature
  3. Set up the client

    cd ../client
    npm install

Running It

  1. Start the server (in one terminal)

    cd server
    node src/server.js

    You should see "Server running on port 3000" and "Connected to MySQL successfully."

  2. Start the client (in another terminal)

    cd client
    npm run dev

    It'll run on http://localhost:5173

  3. Open it in your browser

    • Go to http://localhost:5173
    • Search for an engineering major (try "Computer Science" or "Computer Engineering")
    • Start building your plan
    • Log in to save your plan

API Endpoints

Authentication

POST /users - Create account

{
  "username": "username",
  "password": "password123"
}

Returns 201 with user data (no password).

POST /users/login - Log in

{
  "username": "username",
  "password": "password123"
}

Returns 200 with user object and JWT token.

Major Data

GET /majors - Get all engineering majors Returns array of engineering major names: ["Computer Engineering", "Computer Science", ...]

GET /majors/:majorName - Get engineering major details Returns courses and requirements for that engineering major:

{
  "availableClasses": [...],
  "majorRequirementGroups": [...]
}

Plans (Requires Authentication)

POST /plans - Save a plan Headers: Authorization: Bearer <token> Body:

{
  "name": "My Plan",
  "majorName": "Computer Science",
  "quarters": [
    {
      "quarterNumber": 1,
      "classIds": [1, 2, 3]
    }
  ]
}

GET /plans - Get your saved plans Headers: Authorization: Bearer <token> Returns array of your plans with all the quarter and class data.

PUT /plans/:planId - Update a plan Headers: Authorization: Bearer <token> Body:

{
  "name": "Updated Plan Name",
  "quarters": [
    {
      "quarterNumber": 1,
      "classIds": [1, 2, 3]
    }
  ]
}

PATCH /plans/:planId/name - Update plan name only Headers: Authorization: Bearer <token> Body:

{
  "name": "New Plan Name"
}

DELETE /plans/:planId - Delete a plan Headers: Authorization: Bearer <token> Returns 200 on successful deletion.

AI Chat (Requires Authentication)

POST /ai/chat - Send a message to the AI assistant Headers: Authorization: Bearer <token> Body:

{
  "messages": [
    {
      "role": "user",
      "content": "What prerequisites do I need for CS 31?"
    }
  ]
}

Returns 200 with AI response. Requires OPENAI_API_KEY to be set in .env.

Testing

We have comprehensive end-to-end tests using Cucumber and Gherkin. The test suite includes both E2E UI tests (using Playwright) and API tests (using Supertest).

Running Tests

You must set up your .env.test file to run with our test database

   DB_URL=mysql://user:password@host:port/database

Run all tests (API + E2E):

cd server
npm test

Note: E2E tests require both client (http://localhost:5173) and server (http://localhost:3000) to be running. If they're not running, E2E tests will fail but API tests will still run.

Run E2E tests (requires both client and server running):

# Terminal 1: Start the client
cd client
npm run dev
# Client should be running on http://localhost:5173

# Terminal 2: Start the server
cd server
node src/server.js
# Server should be running on http://localhost:3000

# Terminal 3: Run E2E tests
cd server

# First time setup: Install Playwright browsers
npx playwright install

# Then run E2E tests
npm run test:e2e  # Run all E2E tests
npm run test:scenario20  # Complete user journey test
npm run test:scenario21  # Plan management E2E test

Important Notes:

  • E2E tests require Playwright browsers to be installed. Run npx playwright install once before running E2E tests.
  • Both client and server (localhost:3000) must be running before E2E tests will work.
  • Port Auto-Detection: E2E tests automatically detect which port your client is running on (tries 5174, 5173, 5175, 5176). You can also set it manually:
    E2E_BASE_URL=http://localhost:5174 npm run test:e2e
  • If tests timeout, verify both servers are running and accessible.
  • E2E tests have 60-second timeouts for steps and 30-second timeouts for page navigation.

Run individual API test scenarios by tag (all 19 API scenarios have individual scripts):

# User authentication (scenarios 1-4)
npm run test:scenario1  # User creation
npm run test:scenario2  # Duplicate user prevention
npm run test:scenario3  # User login
npm run test:scenario4  # Invalid login

# Major endpoints (scenarios 5-7)
npm run test:scenario5  # Get all majors
npm run test:scenario6  # Get major details
npm run test:scenario7  # Nonexistent major error

# Plan management (scenarios 8-13)
npm run test:scenario8  # Create plan
npm run test:scenario9  # Create plan without auth
npm run test:scenario10 # Get all plans
npm run test:scenario11 # Update plan
npm run test:scenario12 # Update plan name
npm run test:scenario13 # Delete plan

# Auth endpoints (scenarios 14)
npm run test:scenario15 # Update username

# AI endpoints (scenarios 15-17)
npm run test:scenario17 # AI chat message
npm run test:scenario18 # AI chat without auth
npm run test:scenario19 # Invalid AI message format

Test Coverage

E2E Tests (Playwright + Cucumber) - 2 comprehensive scenarios:

  • e2e_user_journey.feature (scenario 20) - Complete user flow: signup → search major → create plan → drag and drop courses → save plan
  • e2e_plan_management.feature (scenario 21) - Plan management: load saved plan → modify plan → update plan

API Tests (Supertest) - 19 scenarios covering all 11 API routes:

  • can_users_be_created.feature (scenarios 1-2) - User registration and duplicate prevention
  • can_you_log_in.feature (scenarios 3-4) - User login and authentication
  • major_endpoints.feature (scenarios 5-7) - Major data retrieval (GET all majors, GET major details, error handling)
  • plan_endpoints.feature (scenarios 8-14) - Plan CRUD operations (create, read, update, delete, authorization checks)
  • auth_endpoints.feature (scenarios 15-16) - User account updates (username updates, authentication)
  • ai_endpoints.feature (scenarios 17-19) - AI chat endpoint (authentication, message validation, error handling)

Test Structure

  • Feature files: server/features/*.feature (Gherkin syntax)
  • Step definitions: server/features/step_definitions/
    • stepdefs.js - Step definitions for user authentication tests (scenarios 1-4)
    • api_stepdefs.js - Step definitions for API endpoint tests (scenarios 5-19)
    • e2e_stepdefs.js - Step definitions for E2E UI tests using Playwright (scenarios 20-21)

E2E Test Requirements:

  • Both client (http://localhost:5173) and server (http://localhost:3000) must be running
  • E2E tests use Playwright to automate browser interactions
  • Tests create users and plans via API, then verify UI behavior
  • Tests are configured to run headless by default (set E2E_HEADLESS=false to see browser)

API Tests:

  • All API tests use Supertest to make HTTP requests to the Express app
  • Tests use a separate test database (configured via NODE_ENV=test)
  • Tests automatically set up/tear down test data to ensure test isolation

Troubleshooting

Database connection fails

  • Make sure the .env file exists in server/
  • Check your database credentials
  • Make sure the server is running

Module not found errors

  • Run npm install in both client/ and server/ directories

Prisma errors

  • Run npm run prisma:generate or npx prisma generate in the server/ directory

Port 3000 already in use

  • Kill whatever's using port 3000, or change the PORT constant in server/src/server.js

CORS errors

  • Check the CORS config in server/src/middleware/setup.middleware.js matches your client URL
  • The client uses Vite proxy (/api routes) configured in client/vite.config.js

Built for CS35L at UCLA.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors