EaseMySemester
A revision tool turning ten years of scattered exam questions into a browsable, tagged question bank. Built for one first-year medical student; about fifty of their batch use it, six pay.
- Role
- Product, research and engineering, solo
- Year
- 2026
- Stack
- Next.js, TypeScript, PostgreSQL, Neon, Vercel
Use the demo account offered on the login screen. Browse and Intelligence both work; nothing you do there touches a real student's data.
Where it is now
About fifty first-year medical students use this. Six pay for the Intelligence tier. It has never been marketed. I built it for one person I know, and it spread through their batch one at a time.
The feature people pay for guesses which questions are coming next. Last cycle it flagged 20; 8 of them showed up in the actual paper.
I nearly used an LLM here
It's the obvious move and I'd have learned something building it.
But someone was going to message me asking why a question was ranked first, and I didn't want the answer to be "the model said so." So it's counting rules: how often a question has been asked, how long since, whether the topic is climbing, and every card shows its working: Asked 5×, 3 yr gap, Rising topic.
Two other things settled it. The question is arithmetic, not language: "how often has this come up, and when?" is something you count. And it has to give the same answer twice. A top 20 that reshuffles overnight would be worthless during exam week, and worse, it'd be obviously untrustworthy the first time someone noticed.
Boring, and it hit 40%.
Where a model does help, I use one: the question banks are generated with LLM assistance and then forced through a strict validator before anything enters the system. The model produces material. It never produces truth.

The part nobody sees
The hard problem was never the interface. It was that ten years of hand-curated exam questions rot unless every file is checkable.
So the format came first. YAML at the top for subject, exam and paper, then a
five-token tag on every single question, (AKU 2020 null Reg P1): board,
year, month, session, paper. Repeat appearances get joined into one tag.
The importer either accepts a file completely or rejects it with line numbers. There's no partial import. The person loading these files is a medical student, not an engineer, and the thing to protect against isn't a rejected file. It's a half-imported one that nobody notices until the night before an exam.
Everything downstream inherits that. The browse view, the counting rules, the retrieval feature I'm building now. They all work because the corpus underneath is clean and tagged the same way every time.

I got the navigation wrong
The data model had paper as a level you click through: exam → subject →
chapter → paper → topic → question. Six levels. Faithful to the data, and I was
pleased with it.
Then it came back to me that the thing was painful to use the night before an exam. Five clicks before you see a single question, on a tool whose whole purpose is "I have one hour, show me what they ask about this."
I rebuilt it as two panes: the tree on the left, the chapter's questions on the right, and paper demoted to a filter. Coming back restores your last chapter at zero clicks. Switching chapters costs one to three.

The data model didn't change. Paper is still on every question. What changed was my assumption that a faithful structure is a usable one. Those are different things and I'd argued myself into conflating them.
Fixing things in the order they hurt
Once real people were using it I did a hardening pass. Eight fixes, one commit each so any of them could be backed out alone.
I ordered them by what actually breaks. The first three cause something you can see: an unhandled database pool error taking the whole process down, students hitting a raw exception screen, the import page going white when a session expired. The other five quietly corrupt the question bank, which is worse because nobody reports it. Cleanup deletes were sweeping the entire database, so publishing Anatomy was quietly garbage-collecting Biochemistry.
The speed fix went last on purpose. A 2,000-question file used to take about 6,000 separate database round trips and blow past every serverless timeout; it now publishes in about 1.7 seconds. It rewrites the same loops the earlier fixes touch, so doing it first would have undone them.
What I chose not to build
No LLM in the ranking. No public signup, just invite-only, because trust in the content is the whole product. And for the retrieval feature, no ingestion pipeline: the app owns the consumer side and the schema contract, and getting PDFs into the database stays an offline job I run myself. The tempting half is the pipeline. The half that actually matters is the contract between them.
What's next, and why
Students should be able to ask the bank a question and get a cited answer back.
I'm not building retrieval because it's the thing to build. I'm building it because the corpus is already clean and tagged, the questions are already grouped by topic, and the obvious next thing someone wants is to ask. That's the necessity; RAG is just the name for it.
The constraint is the interesting part. Vercel and Neon handle the app fine and scale the moment I'm willing to pay. The model doesn't. It runs on Ollama on a small CPU-only server of mine, no GPU. I could buy a bigger box. I'd rather find out how much I can get out of this one, and I have a bench for measuring that now.
What I'd do differently
I'd have asked about the navigation before building it instead of after. The six-level structure was a faithful rendering of the data and it took someone else finding it annoying for me to see the difference. It was cheap to reverse because the app was small. On something bigger that's a quarter gone.
I'd also have measured the strike rate from the first cycle instead of the second. The 40% is the single most persuasive thing about this project and it exists because I eventually thought to check.