CampusFlow
CampusFlow turns course materials into organized summaries, practice quizzes, and follow-up study conversations.
Built with JavaScript, TypeScript, Supabase Auth, PostgreSQL, Deno Edge Functions, and OpenRouter. The frontend is a static web application.
Contents
- Features
- Run locally
- Architecture
- Technology stack
- Tests
- Technical decisions and limits
- Portfolio presentation
- Complete setup guide
- Sample walkthrough and portfolio demo
Features
- Analyze PDF, TXT, and CSV files and group related materials by course.
- Save course summaries, schedules, and important details.
- Generate practice quizzes, persist answers, and request explanations for incorrect answers.
- Save and reopen study conversations.
- Keep saved data scoped to its owner through PostgreSQL Row Level Security policies.
Calendar is a planned feature. AI output can be inaccurate and should be checked against the source material.
Run locally
Prerequisite: Node.js 24.20 or later in the Node 24 release line, and internet access for the browser libraries and backend.
npm start
Open http://localhost:5500. This serves the frontend only; it connects to the Supabase project configured in supabase-config.js. Use a separate development Supabase project when experimenting with saved data.
The complete backend configuration and a guided walkthrough using fictional materials are included below.
Architecture
flowchart LR
Browser[Static HTML / CSS / JavaScript] --> Auth[Supabase Auth]
Browser --> DB[PostgreSQL with per-user RLS]
Browser --> Edge[Deno Edge Functions]
Edge --> AI[OpenRouter]
The browser submits documents and study context to Edge Functions. The functions validate inputs, request structured AI responses, and validate or repair incomplete output. The browser saves accepted results to PostgreSQL. OpenRouter credentials stay in backend environment variables.
Technology stack
| Layer | Technologies |
|---|---|
| Frontend | HTML, CSS, vanilla JavaScript, Lucide icons |
| Authentication | Supabase Auth |
| Database | PostgreSQL, SQL migrations, Row Level Security |
| Backend | TypeScript, Deno-based Supabase Edge Functions |
| AI provider | OpenRouter |
| Testing | Node.js test runner and optional Playwright browser tests |
| Local server | Node.js built-in HTTP server |
Data storage
| Table | Purpose |
|---|---|
saved_courses |
Course summaries, schedules, and important details |
saved_quizzes |
Generated questions and saved answers |
saved_conversations |
Study conversation history |
feedback_requests |
Visitor feedback with separate insert-only permissions |
Project structure
CampusFlow/
├── index.html
├── main.css
├── study.css
├── script.js
├── sign_in.html / sign_in.js
├── sign_up.html / sign_up.js
├── supabase-config.js
├── package.json
├── tools/serve.cjs
├── demo/materials/
├── supabase/
│ ├── functions/analyze-course-file/index.ts
│ ├── functions/study-assistant/index.ts
│ └── migrations/
└── tests/
Tests
npm test
The backend suite contains 22 tests and uses mocked provider responses. It verifies application behavior, not real-model accuracy or deployed authentication. These tests passed during the local review.
The browser regression suite requires Playwright and a Chromium installation:
npm install --no-save --package-lock=false playwright
npx playwright install chromium
npm run test:ui
The browser suite was not run during the local review. It mocks Supabase and does not write to the live project. Playwright is optional and is not included in the dependency-free backend setup.
Technical decisions and limits
- SQL migrations define ownership policies, indexes, and basic JSON constraints.
- AI handlers validate file types, sizes, and output structure, with retry and repair behavior.
- Frontend request counters prevent stale results from overwriting newer UI state.
- Conversation persistence includes a retry-save path when database writes fail.
- Frontend state is currently concentrated in
script.js; modularization is planned. - Deployed JWT verification, usage quotas, and real-provider quality benchmarks still need verification or implementation.
Complete setup guide
1. Start the frontend
From the project directory, run npm start and open http://localhost:5500. Stop the server with Ctrl+C. No npm dependencies are needed for the frontend server or backend unit tests.
The server only exposes the application's public assets. It does not expose migrations, tests, environment files, or documentation.
2. Configure your own Supabase project
Create or select a development project. In supabase-config.js, replace url and publishableKey with that project's URL and browser publishable key. This configuration is public; never put service-role credentials or an OpenRouter API key here.
The current file points to an existing project. Simply starting this frontend does not create an isolated backend.
Edit only the configuration object in supabase-config.js, preserving the client initialization code below it:
window.SUPABASE_CONFIG = {
url: "YOUR_SUPABASE_PROJECT_URL",
publishableKey: "YOUR_SUPABASE_PUBLISHABLE_KEY"
};
3. Create the database tables
In a new development database, apply the SQL files from supabase/migrations in filename order:
20260924_create_saved_courses.sql20261001_create_saved_quizzes.sql20261004_create_saved_conversations.sql20261005_create_feedback_requests.sql
Use the Supabase SQL editor, or your established migration workflow. These files create policies as well as tables; do not blindly rerun them against a database where those policies already exist.
4. Deploy the backend functions
Deploy the source directories supabase/functions/analyze-course-file and supabase/functions/study-assistant under their matching function names using your Supabase deployment workflow.
Set these backend environment variables:
| Name | Value |
|---|---|
OPENROUTER_API_KEY |
Your provider key, stored only as a backend secret |
ALLOWED_ORIGIN |
http://localhost:5500 for this local frontend |
The current code accepts one exact browser origin. Use a separate backend/environment for a public demo, or implement an explicit origin allowlist before using both local and hosted frontends.
Verify the configured model is available to your provider account. Both functions currently declare their model in source code.
Before inviting public users, verify deployed authentication for both functions. A request with no valid user token must be rejected before it reaches the AI provider. The current unit tests do not establish gateway JWT verification.
5. Configure authentication
In Supabase Auth settings, configure the local site URL and allow the signup email redirect to http://localhost:5500/index.html. Complete email confirmation if enabled. Use your own development account for the walkthrough.
6. Verify the installation
- Run
npm test: expect 22 passing mocked backend tests. - Sign up, confirm the email if required, and sign in.
- Follow the sample walkthrough below and verify saved data survives reload.
- Confirm a second account cannot access the first account's saved records using a separate integration test before claiming verified tenant isolation.
Troubleshooting
| Symptom | Check |
|---|---|
| Browser cannot reach the backend | Project URL, publishable key, network access |
| AI requests fail in the browser | Exact ALLOWED_ORIGIN, function deployment, signed-in session |
| Provider request fails | Backend key, account limits, model availability |
| Saving fails | Applied migrations, authenticated user, ownership policies |
| Signup does not open the application | Email confirmation and redirect settings |
| Local port is occupied | Stop the other process using port 5500 before restarting |
Built With
- css
- deno
- html
- javascript
- openrouter
- postgresql
- supabase
- typescript
Log in or sign up for Devpost to join the conversation.