Discard the
Static.
Embrace the
Dynamic.

TrashTheTest turns academic PDFs into grounded study notes, flashcards, practice questions, an AI tutor, syllabus insights and a published study website. Open source, self-hostable, and built around the document rather than a chat box.

Project workspace
Study notes workspace
Flashcards
AI tutor
The system

One flow. No tab hopping.

Upload material, generate the study set, practise it, then publish it. Every artifact is grounded in retrieved source chunks with page-level citations, and anything that cannot be supported is reported as a gap instead of invented.

+Structure first. Page extraction, a topic/subtopic/concept spine, and page-level provenance.
+Grounded generation. pgvector + Postgres FTS, RRF fusion, optional reranker, citation validation.
+Asynchronous by default. Postgres SKIP LOCKED queue, a dedicated worker, honest stage progress.
+Publish, don't export. Sanitised study sites with public slugs and no login for readers.

Notes

Topic-by-topic generation in source order, coverage checks, and a PDF with TOC, bookmarks and page numbers.

Flashcards

Atomic, source-anchored cards with difficulty. Definitions become cloze cards instead of trivia prompts.

Practice

MCQs with explanations and citations. Cells without enough distinct evidence are left unfilled, never padded.

Tutor

Project-scoped RAG. Greetings skip retrieval; academic questions answer with sources.

Artifacts

Study material you can actually use.

Generated from the same grounded retrieval pipeline, persisted, and rendered consistently in the app and on the published site.

Flashcards
Flashcards - atomic, cited, difficulty-tagged
Practice questions
Practice - explanation and source for every question
Study workspace
Study workspace - notes, practice, answers, explanations
Published study site
Published study site - public URL, no login required
Quick start

Two commands to a running stack.

Docker Compose brings up the API, worker, PostgreSQL with pgvector, Redis and the frontend. You bring a provider key.

git clone https://github.com/ItsAakif/trashthetest.git
cd trashthetest
cp .env.example .env
docker compose up -d --build
docker compose exec api alembic upgrade head

Open http://localhost:5174. Health check: http://localhost:8000/health. Set JWT_SECRET, DATABASE_URL and GROQ_API_KEY (or OPENROUTER_API_KEY) in .env first.

Self-hosting

Yours, on your infrastructure.

Database

Managed PostgreSQL 16 with pgvector, then alembic upgrade head.

Worker

python -m services.jobs.worker as its own process. The queue is in Postgres, no broker required.

Storage

Local volume by default, or S3-compatible via STORAGE_BACKEND=s3 and S3_*.

Secrets

Server-side env only. Provider keys never reach the browser.

Stack

Direct code where it is clearer.

LayerChoice
FrontendReact 19, TypeScript, Vite, TailwindCSS, TanStack Query, wouter, Radix UI
APIPython 3.13, FastAPI, Pydantic v2, SQLAlchemy 2 async
DataPostgreSQL 16, pgvector (HNSW), tsvector FTS, Alembic
JobsPostgres SKIP LOCKED queue, dedicated worker, optional Celery/Redis bridge
AIQwen3-Embedding-0.6B (1024d), bge-reranker-v2-m3, Groq primary / OpenRouter fallback, structured outputs
DocumentsPyMuPDF, pdfplumber, PP-OCRv6 tiny (ONNX, CPU), ReportLab
OpsDocker Compose, storage abstraction (local / S3), structured logs