Skip to content

ucsb-caliber/caliber-milestone-one

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

283 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Caliber - Milestone One Prototype

Caliber is a fullstack teaching platform prototype for creating coursework from PDFs, organizing courses, and delivering student-facing assignments with saved progress.

What This Build Covers

  • Authentication via Keycloak/OIDC (portal session or Bearer token)
  • Role-aware product experience:
    • Students: Courses + profile access
    • Instructors/Admins: full platform access + student-view preview
  • Course management with autogenerated join codes
  • Student self-enrollment using course codes
  • Assignment authoring + student assignment delivery
  • Student assignment progress persistence (autosave/resume)
  • Instructor student-view preview that does not save progress
  • Question bank workflow with PDF extraction and manual editing

Core Use Cases

1) Student Flow

  • Sign in and complete onboarding (default student role)
  • Join a course by code (<CourseNamePrefix>_<RANDOM6>)
  • Open current assignments in student view
  • Work through questions with autosaved progress
  • Return later and resume where they left off

2) Instructor Flow

  • Create and manage courses
  • Share course code with students for self-enrollment
  • Create assignments and attach questions
  • Use Student View to preview assignment UX without mutating student progress data

3) Admin Flow

  • Manage users and roles
  • Review pending instructor requests at top of Users page
  • Approve or dismiss instructor access requests

Main Product Areas

Authentication + Roles

  • Keycloak/OIDC JWT auth across frontend/backend
  • Onboarding collects profile data
  • Instructor requests are captured as pending
  • Admin approval toggles users into instructor access

Courses

  • Teachers can create/update/delete courses
  • Students can join via course code
  • Course code format:
    • course_name stripped of spaces/symbols
    • first 16 chars max
    • uppercase
    • _<6 random letters/numbers> suffix

Assignments

  • Instructors create assignments per course
  • Students see assignments in a student-facing experience
  • Assignment progress model tracks per-student state

Assignment Progress (Resume Support)

  • Dedicated assignment_progress rows per (assignment, student)
  • Stores:
    • selected/free-response answers
    • current question index
    • submission status/time
  • Sync behavior:
    • Created when assignment is created (for current enrolled students)
    • Created when a new student is added/joins a course
    • Deleted when assignment is deleted

Question Pipeline

  • PDF upload starts background parsing
  • Milestone 2 parser files are vendored into backend/app/m2/ and executed from Milestone 1 backend
  • Upload processing runs the copied M2 layout pipeline first (layout detection + OCR extraction)
  • Fallback parser performs question segmentation from PDF text, with OCR fallback for scanned PDFs
  • Question bank supports verification/editing and assignment inclusion

Architecture Snapshot

  • Frontend: React + Vite
  • Backend: FastAPI + SQLModel + Alembic
  • Auth: Keycloak/OIDC
  • DB: PostgreSQL (or SQLite for local testing)
  • Storage: Supabase buckets for uploaded PDFs/images
  • Background work: FastAPI background tasks for PDF parsing

Additional Docs

  • docs/FEATURES_AND_API.md for current feature scope, routes, and endpoint map
  • docs/SETUP_OPERATIONS_AND_TESTING.md for setup, migrations, storage policy setup, and smoke testing
  • docs/CODING_RUNNER.md for coding-question execution modes, Docker Compose setup, and runner env vars

Quick Start

Backend Setup

Use Python 3.10 or 3.11 for the Milestone 2 parser dependencies (torch==2.1.2, effdet).

cd backend
python -m venv .venv
source .venv/bin/activate  # On Windows: .venv/Scripts/activate
pip install -r requirements.txt
cp .env.example .env

Install system dependencies required by the copied Milestone 2 parser:

  • macOS: brew install poppler tesseract
  • Ubuntu/Debian: sudo apt-get install -y poppler-utils tesseract-ocr

Notes:

  • The first PDF upload may take longer because model files are downloaded and cached.
  • The torch / effdet stack is required to run the copied backend/app/m2/layout_ingest.py.

Then install Ollama, which runs a local LLM to clean PDF extraction output:

brew install ollama

You can then either run ollama serve in a new terminal, or run brew services start ollama to run it in the background.

Then in backend/.env set the following:

LLM_CLEANUP_ENABLED=true
LLM_CLEANUP_BASE_URL=http://127.0.0.1:11434
LLM_CLEANUP_MODEL=llama3.1:8b
# Optional: stronger formatter model if your machine can run it.
# LLM_CLEANUP_MODEL=qwen2.5:14b
# Optional fallback chain:
# LLM_CLEANUP_MODEL_FALLBACKS=qwen2.5:14b,qwen2.5:7b
# Optional: force LLM formatting on every question (slower).
# LLM_CLEANUP_FORCE=true
# Optional: debug logs for formatter behavior.
# LLM_CLEANUP_DEBUG=true

Prompt style instructions are read from backend/app/prompts/llm_cleanup_style.md. You can override that by setting LLM_CLEANUP_STYLE_GUIDE_PATH=/absolute/path/to/your-style-guide.md.

Edit your backend/.env file and replace placeholders:

  • DATABASE_URL with your local/dev Postgres URL
  • OIDC_ISSUER and/or OIDC_JWKS_URL for your Keycloak realm
  • OIDC_AUDIENCE if your tokens enforce audience checks
  • SUPABASE_URL and SUPABASE_SERVICE_ROLE_KEY so /api/upload-pdf can store files in question-pdfs
  • Optional: M2_TESSERACT_TIMEOUT_SEC to cap per-page OCR time (default 45)
  • Optional: M2_RENDER_DPI to control PDF rasterization cost (default 170)
  • Optional: configure LLM_CLEANUP_* and ROSTER_* values only if you plan to use those integrations locally
  • Optional: leave CODING_RUNNER_URL blank for localhost dev, or set it to http://coding-runner:8010 when using the Docker runner service on a server

Run database migrations (first time setup):

alembic upgrade head

If you hit install/runtime errors, make sure your backend venv uses Python 3.10 or 3.11.

See docs/SETUP_OPERATIONS_AND_TESTING.md for Alembic workflow details and troubleshooting.

Start the backend server:

uvicorn app.main:app --reload --port 8000

The backend will be available at http://localhost:8000

For coding questions:

  • Local dev: leave CODING_RUNNER_URL blank and the backend will use the built-in local executor.
  • Server / Docker: use the root docker-compose.yml so the backend can reach the dedicated coding-runner service at http://coding-runner:8010.

Frontend Setup

cd frontend
npm install
cp .env.example .env

Edit your frontend .env file and replace the placeholders:

  • Replace VITE_SUPABASE_URL / VITE_SUPABASE_ANON_KEY for signed URL + image helpers
  • Set VITE_API_BASE to your backend URL (default: http://localhost:8000)
  • Use VITE_BASE_PATH=/ for local dev
  • Set VITE_OIDC_ISSUER + VITE_OIDC_CLIENT_ID for direct local Keycloak login (recommended for npm run dev)
  • Set VITE_PORTAL_BASE_URL only if you want legacy portal /login + cookie flow
npm run dev

The frontend will be available at http://localhost:5173

Team Local Run Modes

A) Fastest local iteration (no local Keycloak): test mode

This bypasses SSO and is useful for frontend/backend iteration.

  1. Start backend and frontend normally.
  2. Open http://localhost:5173/?test-mode=true.

B) Local frontend + backend with real SSO

Use direct Keycloak PKCE login from the frontend (works with npm run dev + uvicorn).

frontend/.env:

VITE_API_BASE=http://localhost:8000
VITE_BASE_PATH=/
VITE_OIDC_ISSUER=https://app.caliber.cs.ucsb.edu/auth/realms/platform
VITE_OIDC_CLIENT_ID=portal
VITE_OIDC_SCOPES=openid profile email

backend/.env:

OIDC_ISSUER=https://app.caliber.cs.ucsb.edu/auth/realms/platform
OIDC_JWKS_URL=https://app.caliber.cs.ucsb.edu/auth/realms/platform/protocol/openid-connect/certs
OIDC_AUDIENCE=portal
SUPABASE_URL=https://your-project-id.supabase.co
SUPABASE_SERVICE_ROLE_KEY=your-service-role-key

If your Keycloak client does not already allow local redirects, add:

  1. Valid redirect URI: http://localhost:5173/*
  2. Web origin: http://localhost:5173
  3. Post logout redirect URI: http://localhost:5173/?logged_out=1

C) Build Docker image locally and serve on localhost

Yes, your teammates can compile and host the frontend image locally while testing.

cd caliber-milestone-one
docker build -t caliber-frontend:dev .
docker run --rm -p 8003:8003 caliber-frontend:dev

Then open http://localhost:8003 (or through your reverse proxy path).

Key API Groups

  • POST /api/upload-pdf and question endpoints for bank management
  • GET/POST/PUT/DELETE /api/courses + POST /api/courses/join
  • GET/POST/PUT/DELETE /api/assignments
  • GET/PUT /api/assignments/{id}/progress for student state
  • GET/PUT /api/users/{id} for admin role management
  • GET/POST/PUT /api/user* for current-user profile/onboarding/preferences

Notes

  • Run migrations whenever pulling schema/model changes.
  • OCR fallback requires a local tesseract binary in PATH.
  • Milestone 2 parser code is copied into backend/app/m2/ and called by POST /api/upload-pdf.
  • Local LLM markdown cleanup is optional and uses Ollama (no API key).

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors