Planning backwards from an exam date

How we built Braineos's study planner: one pure function shared by a public page and a signed-in card, plans that never shift, and why it gives no minutes-per-day figure.

Photo by Towfiqu barbhuiya on Unsplash

Braineos already schedules reviews for every card: get it right and it comes back after 1, 3, 7, 14 and then 30 days. What it couldn’t do was answer the question a student asks first: “My exam is in May. What do I study, and when?” The study planner answers that. This post covers the decisions behind it.

One function, two places

The plan appears in two places: on a public page, where anyone can try it without an account, and on the signed-in home page, as today’s step. If those two were computed differently, a learner could make a plan on the public page and then see a different one at home.

So the whole plan comes from one pure function. It takes a start date, an exam date, the study weekdays and the decks (in course order, with card counts) and returns the days. There is no database access and no clock inside it: the same inputs always give the same plan. That made it easy to test the awkward cases (one study day a week, an exam a few days away, an exam a year out, weekdays that miss the final week) and lets the browser redraw the plan instantly as someone changes the date.

The shape of a plan

The first 70% of the study days are learning days. Decks are handed out in unit order and balanced by card count, so one 30-card deck doesn’t land on the same day as three others. Each deck then returns 1, 3, 7, 14 and 30 days later, the same intervals as the review system, on the next study day on or after each gap.

Reviews that would fall after the learning phase are dropped, because the last 30% is mixed review of every deck. Within that stretch the plan doesn’t try to guess which cards are weakest. The real review queue already knows, from the learner’s answers, so the plan just says “mixed review” and points to the cards that are due.

When there are more decks than learning days, the plan doubles them up and says plainly that time is tight.

A saved plan never moves

Saving stores the inputs, not the output: the exam, the weekdays and the date the plan started. The home card runs the same function from that start date each time, so the plan a learner saw on the first day is the plan they still have a month later.

That raised a question: what happens after a missed day? We chose not to reschedule. The review queue already catches overdue cards, so the card says how many decks behind plan the learner is and links to the next one. A plan that rewrote itself every time you missed a day would be harder to trust.

No minutes per day

The obvious extra was an estimate: “about 25 minutes a day”. We left it out. Turning cards into minutes needs a time per card, and we only publish figures we have measured. A made-up estimate would sit on the page looking exactly like a fact.

Pages only where the decks exist

Each exam page uses one AI tutor’s decks, configured in a short typed list (exam name, tutor, units in course order, and a note on anything not covered yet). A page exists only while the exam has at least six live decks, so there are no thin pages for search engines or students. Where the decks don’t yet cover the whole course, the page says which parts are missing rather than implying full coverage.

The plan’s inputs live in the URL, so a plan can be bookmarked or shared with no account and nothing stored. Saving is the step that needs an account.

Planning an app?

We take products from idea to launch for clients, and keep live apps running afterwards.

MVPs & maintenance: what we do →

Start a project