Clarift is an AI-powered study engine built specifically for Filipino students and review center learners. It transforms uploaded study material into structured summaries, quizzes, and targeted practice through an active learning loop designed for high-stakes exams.
- Document Ingestion: Upload PDFs as study material
- Structured Summaries: Multi-step AI chain generates comprehensive summaries with MermaidJS diagrams
- Quiz Generation: Auto-generated quizzes strictly from uploaded material to test understanding
- Weak Area Diagnosis: System identifies knowledge gaps based on quiz performance
- Targeted Practice: Personalized practice drills focused on specific weak topics
- Grounded RAG Chat: AI chat that answers exclusively from uploaded notes, never from general knowledge
- Quota System: Daily usage limits with free tier (3 summaries, 3 quizzes, 6 practice, 15 chat per day, 8 document uploads lifetime) and Pro tier (expanded limits)
- Onboarding Flow: Capture user preferences (format, explanation style, custom instructions) on first use
- Per-Generation Overrides: Override global settings per AI generation (summary/quiz/practice)
- Quiz Type Flags: Tracks which question types are applicable to source material via content analysis
- Practice Multi-Select: Select multiple weak topics for combined practice sessions
- Drill Ordering: Drag-and-drop reordering of practice drills
- Mastery Charts: Visual topic accuracy charts in quiz results
Clarift uses a split architecture with two distinct server-side layers sharing a single Neon PostgreSQL database.
Next.js (Frontend)
- UI rendering via Server Components and Server Actions
- CRUD operations using Drizzle ORM
- Authentication via Clerk (Google OAuth)
- Quota display and usage tracking
- Location:
frontend/src/
FastAPI (Backend)
- AI/LangChain pipelines for summaries, quizzes, and practice generation
- Async job processing via ARQ worker
- File storage to Cloudflare R2
- Quota enforcement (authoritative)
- Location:
backend/app/
- Auth: Clerk handles OAuth; JWT verified by FastAPI for protected API calls
- Document Processing: Client uploads file -> FastAPI stores to R2 -> ARQ worker processes (extract, chunk, embed, store in pgvector) -> SSE progress updates
- AI Generation: Client triggers generation -> FastAPI enforces quota -> ARQ worker executes LangChain chain with Gemini -> results stored in DB -> SSE notifies completion
- Route -> Service -> Chain: Strict separation in backend AI features
- Server Component + Server Action: Direct DB access for CRUD in frontend
- SSE Job Tracking: Real-time progress for async operations
- All vector queries MUST filter by
user_id(tenant isolation) - Never pass full document content to LLM (always use retrieved chunks, max 5)
- Framework: Next.js 16.2.3 (App Router)
- Language: TypeScript 5.x
- UI: React 19.2.4, Tailwind CSS 4.2.2, shadcn/ui, Radix UI, Lucide React, Framer Motion
- State: TanStack React Query v5, Zustand
- Database: Drizzle ORM with @neondatabase/serverless
- Auth: Clerk (Google OAuth)
- Charts: Recharts
- Rich Text: Tiptap (summary viewing/editing)
- Uploads: React Dropzone
- Framework: FastAPI 0.135.3+
- Language: Python 3.12
- AI: LangChain + LangChain Google GenAI + Gemini API
- Database: SQLAlchemy async + Alembic (migrations)
- Vector Search: pgvector (Neon PostgreSQL)
- Queue: ARQ (async Redis via Upstash)
- Storage: Cloudflare R2 (S3-compatible)
- Frontend Hosting: Vercel
- Backend Hosting: Railway (web + worker services)
- Database: Neon PostgreSQL
- Cache/Queue: Upstash Redis
- Node.js >= 20
- Python 3.12
- pnpm (frontend package manager)
- uv (Python package manager)
- Neon PostgreSQL database with pgvector extension
- Upstash Redis instance
- Clerk account with Google OAuth enabled
- Gemini API key
cd backend
# Create virtual environment with uv
uv venv
# Install backend in editable mode from pyproject.toml
uv pip install --python ".venv/Scripts/python.exe" -e .
# Copy and configure environment
copy .env.example .env
# Fill in .env with your credentials
# Run migrations
uv run --python ".venv/Scripts/python.exe" alembic upgrade head
# Start the backend server
uv run --python ".venv/Scripts/python.exe" uvicorn main:app --reload
# Backend runs at http://localhost:8000
# API docs available at http://localhost:8000/docsIn a separate terminal:
cd backend
uv run --python ".venv/Scripts/python.exe" arq src.worker.WorkerSettingscd frontend
# Install dependencies
pnpm install
# Copy and configure environment
cp .env.example .env.local
# Fill in .env.local with your credentials
# Start the development server
pnpm run dev
# Frontend runs at http://localhost:3000Once the backend is running:
cd frontend
pnpm run generate:openapi
pnpm run generate:api-typesThis refreshes backend/openapi.json and generates frontend/src/lib/api-types.ts.
# Backend health check
curl http://localhost:8000/health
# Backend tests
cd backend && uv run --python ".venv/Scripts/python.exe" pytest -q
# Frontend tests
cd frontend && pnpm run test:run
# Frontend linting
cd frontend && pnpm lint
# Backend linting
cd backend && uv run --python ".venv/Scripts/python.exe" ruff check .DATABASE_URL=postgresql+asyncpg://user:pass@host/clarift
REDIS_URL=redis://default:token@host:port
CLERK_SECRET_KEY=
CLERK_PUBLISHABLE_KEY=
GEMINI_API_KEY=
R2_ACCOUNT_ID=
R2_ACCESS_KEY_ID=
R2_SECRET_ACCESS_KEY=
R2_BUCKET_NAME=clarift-uploads
# Processing safety limits (optional; defaults shown)
MAX_UPLOAD_SIZE_BYTES=52428800
MAX_DOCUMENT_BYTES=52428800
MAX_PDF_PAGES=300
MAX_EXTRACTED_CHARS=1000000
MAX_CHUNKS_PER_DOCUMENT=500
PAYMONGO_SECRET_KEY=
PAYMONGO_WEBHOOK_SECRET=
SENTRY_DSN=
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=
CLERK_SECRET_KEY=
DATABASE_URL=postgresql://user:pass@host/clarift?sslmode=require
NEXT_PUBLIC_API_URL=http://localhost:8000
- Start backend API:
uv run --python ".venv/Scripts/python.exe" uvicorn main:app --reload - Start worker:
uv run --python ".venv/Scripts/python.exe" arq src.worker.WorkerSettings - Start frontend:
pnpm run dev - In the app, go to
/dashboardand upload a PDF. - Confirm job status reaches
completedin activity stream. - Go to
/summaries, create a summary for the uploaded document. - Confirm summary job reaches
completedand content appears in the summaries list/detail. - Validate tenant isolation by signing in as another user and confirming they cannot view the first user's documents/summaries.
- Create bucket
clarift-uploadsin Cloudflare R2. - Create an R2 API token with Object Read + Object Write for that bucket.
- In backend
.env, set:R2_ACCOUNT_IDR2_ACCESS_KEY_IDR2_SECRET_ACCESS_KEYR2_BUCKET_NAME
- Restart backend + worker after updating env vars.
clarift/
├── frontend/ # Next.js application
│ ├── src/
│ │ ├── app/ # App Router pages and layouts
│ │ ├── components/ # React components (ui + features)
│ │ ├── db/ # Drizzle schema and actions
│ │ ├── hooks/ # React Query hooks
│ │ └── types/ # Generated API types
│ └── package.json
│
├── backend/ # FastAPI application
│ ├── src/
│ │ ├── api/ # Routes, schemas
│ │ ├── chains/ # LangChain chain implementations
│ │ ├── core/ # Config, exceptions
│ │ ├── db/ # SQLAlchemy models, session
│ │ ├── services/ # Business logic services
│ │ └── worker.py # ARQ job worker
│ ├── alembic/ # Database migrations
│ └── pyproject.toml
│
├── .planning/ # Project planning docs
└── docs/dev/ # Development documentation
- Development Documentation - Full developer guide
- Architecture - System design details
- Master Spec - Stack, schema, API contract
- Stack Setup - Complete setup guide
- Modularity Guidelines - Code structure rules