Submitted to UCLA Hack on the Hill (HOTH) XIII
Planning classes at UCLA is a notorious headache. Students have to cross-reference their convoluted DARS (Degree Audit Reporting System) PDFs with BruinWalk ratings, prerequisite chains, and enrollment windows. One wrong class choice can lead to a quarter of all "killer" classes or missing a prerequisite that delays graduation. We wanted to build a unified tool that takes the stress out of course planning by combining these scattered resources into one intelligent, automated system.
Blueprint takes your degree requirements and turns them into a balanced, actionable 4-year plan in seconds:
- DARS Ingestion: Upload your DARS report PDF or paste the raw text. Blueprint extracts your completed courses, remaining major requirements, and current unit count.
- AI-Powered Planning: Using OpenAI's GPT-5.2 with structured outputs via the Responses API, Blueprint generates a quarter-by-quarter schedule. It respects complex prerequisite chains and ensures you are on track to graduate.
- BruinWalk Integration: Every generated course card features its BruinWalk difficulty rating (color-coded green/yellow/red). Blueprint actively balances your workload, preventing you from stacking multiple high-difficulty ("killer") classes in a single quarter.
- Interactive Drag-and-Drop: Plans aren't static. Drag and drop courses between quarters to customize your schedule with real-time visual feedback.
- AI Chat: Ask follow-up questions about your plan directly within the editor. Blueprint can answer "what-if" scenarios and advise on schedule changes.
- Plan Regeneration: Not satisfied? Regenerate your plan with updated preferences and constraints without re-uploading your DARS.
- Smart Enrollment Strategy: Based on your unit count, Blueprint estimates your enrollment window and provides actionable advice on which classes to prioritize during first pass versus second pass.
- Plan Management: Save multiple plan variations to your dashboard, compare approaches, and delete old drafts.
- Dark Mode: Full light/dark theme support with a UCLA-branded design system.
- Frontend: Built with Next.js 16 and React 19, utilizing the App Router for seamless navigation. We used Tailwind CSS 4 and Framer Motion for a clean, animated, and highly responsive user interface that feels native to the UCLA aesthetic.
- Backend & Auth: Powered by Firebase. We use Firebase Authentication for secure Google Sign-In (restricted to
@g.ucla.edu/@ucla.edudomains) and Firestore to persist users' generated plans and profile data. New users go through an onboarding flow to set their major, year, and starting quarter. - AI Engine: The core parsing and generation logic calls OpenAI's GPT-5.2 directly via the Responses API (no SDK — raw
fetchfor minimal dependencies). We use JSON schemas to strictly enforce prerequisite rules and generate the plan data as structured output. - Drag-and-Drop: Implemented using
@hello-pangea/dndfor fluid, accessible, and performant list interactions. - Data: Integrated scraped BruinWalk review data (with a 2-week caching layer) to provide real-time feedback on course difficulty ratings.
- Parsing DARS PDFs: UCLA's DARS reports are notoriously unstructured and visually dense. Reliably extracting completed courses and remaining requirements required significant iteration and prompt engineering.
- Constraint Satisfaction: Instructing an LLM to generate a valid course plan is difficult. We had to ensure the model respected hard constraints (prerequisites, quarter availability) while optimizing soft constraints (balancing BruinWalk ratings across quarters).
- Complex UI State: Managing the drag-and-drop state across multiple quarters while keeping the UI snappy and synchronized with Firebase required careful React state management.
- The UI/UX: We're incredibly proud of the clean, intuitive interface. The visual indicators for course difficulty (Green/Yellow/Red) and the interactive drag-and-drop make the app a joy to use.
- Speed to Value: We successfully reduced a process that usually takes students hours (cross-referencing DARS, Bruinwalk, and course catalogs) into a simple PDF upload that takes less than a minute.
- BruinWalk Workload Balancing: The AI actually understands difficulty. Getting the model to output a balanced schedule that actively avoids terrible quarters was a huge win.
- Advanced Prompt Engineering: We learned how to guide LLMs to produce highly structured JSON outputs that adhere to strict logical constraints.
- Next.js Server Actions: We deepened our understanding of server-side data fetching and API route handling in the new Next.js architecture.
- Firebase Integration: Gained experience securely connecting Next.js with Firebase Auth and Firestore for real-time data persistence.
- Real-Time Enrollment Data: Integrating with UCLA's actual course catalog API to show real-time seat availability and waitlist status.
- More Majors: Expanding our internal prerequisite mapping to reliably support double majors, minors, and more complex degree requirements.
- Social Features: Allowing friends to share schedules and coordinate taking classes together.
src/
├── app/ # Next.js App Router
│ ├── page.tsx # Landing page
│ ├── layout.tsx # Root layout with auth/theme providers
│ ├── upload/page.tsx # DARS upload (PDF or paste)
│ ├── dashboard/page.tsx # Saved plans list
│ ├── plan/[planId]/page.tsx # Plan editor (drag-and-drop, chat, regenerate)
│ ├── privacy/page.tsx # Privacy policy
│ ├── terms/page.tsx # Terms of service
│ └── api/plan/
│ ├── generate/route.ts # POST — DARS → plan generation
│ ├── chat/route.ts # POST — in-plan AI chat
│ └── regenerate/route.ts # POST — rebuild plan with preferences
├── components/
│ └── Navbar.tsx # Top navigation with auth & theme toggle
└── lib/
├── auth.tsx # Firebase auth provider & hooks
├── firebase.ts # Firebase config & initialization
├── theme.tsx # Dark/light mode context
├── plans.ts # Firestore CRUD for plans
├── user-profile.ts # User onboarding state
├── plan-data.ts # TypeScript interfaces
└── server/
├── openai-client.ts # OpenAI Responses API wrapper (raw fetch)
├── dars-parser.ts # Regex parser for DARS text/PDF
├── bruinwalk.ts # BruinWalk scraper with caching
└── generate-plan.ts # Plan generation orchestration
1. Install dependencies
npm install2. Set up environment variables
Create a .env.local file in the project root:
# Firebase
NEXT_PUBLIC_FIREBASE_API_KEY=your_api_key
NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=your_project.firebaseapp.com
NEXT_PUBLIC_FIREBASE_PROJECT_ID=your_project_id
NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET=your_project.firebasestorage.app
NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID=your_sender_id
NEXT_PUBLIC_FIREBASE_APP_ID=your_app_id
# OpenAI
OPENAI_API_KEY=your_openai_api_key
# Optional
OPENAI_MODEL=gpt-5.2 # defaults to gpt-5.2
OPENAI_REASONING_EFFORT=medium # minimal | low | medium | high3. Run the development server
npm run devOpen http://localhost:3000 with your browser to see the application.