Building Palora's Verified Questions and Spaced Reviews

Dalrymple Ramos
Palora landing page introducing document-based practice and illustrated study pals
table of contents

Palora starts with study material, but the useful result is a question a student can answer, understand, and revisit. I built that path as separate stages: extract the material, generate questions, check them against the source, persist accepted questions, and update a schedule when the student reviews them.

The Palora case study covers the complete product, including its seven study modes, pals, and exam-planning tools. Here I focus on the implementation that joins question creation to spaced review.

Keep the source relationship#

The parser dispatches PDF, PowerPoint, Word, text, and image inputs to format-specific handling. Extracted source units retain labels such as a page or slide reference. Images produce units marked for OCR, which the generation worker resolves through the vision model before generating questions.

Chunking gives the worker smaller pieces of material. Each accepted question belongs to a chunk, and each chunk belongs to a document. That relationship supports source navigation, topic views, and ownership checks without asking the model to invent its own document identity.

Question counts can be automatic or distributed across chunks according to their length. A requested count is constrained by the allocation rules and by which questions survive verification; it is not a promise that an upload will always produce exactly that many usable questions.

Make generation resumable#

The worker reads the document's processed-chunk cursor, selects the next batch, and processes at most three chunks concurrently. It saves the cursor after the batch. Chunks that already have questions are skipped on a later run.

The implementation uses a default 45-second work budget. When the budget check is reached, the worker requests a continuation through the generation route. The continuation uses an internal secret, and user-facing retries also resume from saved progress.

This is a configured budget checked between batches, rather than a hard guarantee that every model call finishes within 45 seconds. Model timeouts, provider failures, and continuation failures still need explicit handling. The document can expose a paused or failed state instead of leaving the student with an upload that appears to run indefinitely.

Route tasks to providers#

The shared router defines separate provider orders:

It filters providers by attachment support, applies request timeouts, and retries retryable failures before trying the next provider. Keeping this policy in one place gives ingestion, verification, and grading the same failure vocabulary while allowing them to use different provider orders.

Treat verification as an admission step#

Generation output is parsed into the question schema. A separate verifier receives the source material and a batch of questions with their answer keys and explanations.

Every question needs a usable verdict. A valid verdict accepts the original. A corrected verdict must contain a replacement that passes the schema. An invalid or missing verdict prevents that question from being accepted. If invalid questions remain, the pipeline can generate up to three replacements in one regeneration round and verify those again.

The worker records verdicts, including discards. It writes the accepted questions and their initial review schedules in the same Prisma transaction as the verification records. The review queue therefore begins with accepted questions rather than every raw completion returned by a provider.

This check reduces unchecked output reaching the interface. It remains an automated model judgment, so explanations and source references still matter when a learner questions an answer.

Join grading and review persistence#

When an answer arrives, the server resolves a verified question through the authenticated user's document relationship. Local grading tries exact and fuzzy matching. Eligible typed answers that do not match can go through the AI judge; self-rated flashcards use the submitted recall rating.

The result becomes an SM-2 quality value. Incorrect answers use quality 2. Correct answers use quality 3, 4, or 5 according to response time and grading method. Again, Hard, Good, and Easy map to 2, 3, 4, and 5 for self-rated cards.

The scheduler updates repetition count, interval, and ease. A first successful review schedules one day ahead, a second schedules six days ahead, and later intervals grow from the previous interval and ease. A miss resets repetitions and schedules one day ahead. Ease has a floor of 1.3.

Due dates use local midnight in the supplied, validated time zone. The server transaction records the attempt, upserts the review schedule, and applies study-day and pal rewards together. This keeps the review result and its associated progress update in one persistence operation.

Keep offline review bounded#

The offline question-review queue stores pending attempts in localStorage, retains at most 200, and submits them in order after reconnection. A network failure leaves the remaining queue for another attempt; rejected submissions are removed. Blocked or full browser storage can prevent persistence.

That queue supports continuity for cached question reviews. It does not run ingestion, verification, or server-side AI judging without a connection, and it does not establish exactly-once delivery under every failure condition.

Separate planning from scheduling#

Palora's practice exams and calendar preparation plans help students decide what to study before an exam. Their implementation leaves the SM-2 schedule separate. A timed practice result and a planned calendar session answer different questions from the recall scheduler.

The same distinction applies to the broader study modes: recall activities, sequence practice, and quick reading have their own recording paths. Their presence in the hub does not imply that every activity has identical effects on each question's next review date.

Explore Palora or return to the project case study. These observations describe the inspected implementation; this portfolio update does not claim a newly executed study of learning outcomes.