Inspiration

Fa Zhi was a Mathematics Tutor for H2 GCE Math and found that most students just needed a little nudge in order to get the correct answers. He also realise that many students do not deploy scientific-backed study techniques such as spaced-repetition. Hence, this lead to the creation of ProjectMath which aims to use AI to nudge students and creates spaced-repetition mistakes for students so that they can remember their mistakes

What it does

ProjectMath is an AI Math Trainer. It splits the H2 Math syllabus into topics and each topic consists of questions from all the top schools in Singapore as well as Cambridge A-level questions. In each question, student can ask AI for help and can take a picture of their working and upload to the website for AI to transcribe their working for AI to have a better understanding of their though process. Additionally, ProjectMath stores the user mistakes and allow students to re-do questions that they previously got wrong. The questions re-appear on a algorithm that follows Anki's spaced repetition, allowing students to remember their mistakes.

How we built it

We built using Leetcode system design as a reference. The main programming language used is TypeScript. For the frontend, we mainly used React, Tailwindcss. On top of that, for the math-specific questions, we used KaTeX, MathLive for the input as well as a home-grown 2D graph engine to graph out the solution graph for students. For Authentication, we used Firebase web SDK. Lastly, for the backend, we used SQL migration to supabaseDB. We used Google Cloud Run to deploy the website, Stripe for Payment and Resend for automatic receipt generation.

Challenges we ran into

We used mainly used AI such as Claude Code and Gemini to generate code for this proejct. However, as we began to add more features to our project, it gradually took on a Brownfield developmental process, where we were constantly modifying, adding and testing new features on top of Leetcode system design base. As a result, the Large Language Models took longer times and more tokens to contextualise our project along the way, even generating conflicting code that introduced bugs into our codebase at some points, resulting in scattering of our project to a certain extent. Secondly, we found it difficult to generate marketing prowess in this industry to have more users to pay for our website.

Accomplishments that we're proud of

Firstly, we managed to successfully integrate Gemini's API our AI hints chatbot and solution grader, leveraging on Gemini's capacity to provide users with assistance in weakness-targeted problem solving. Users will be able to receive targeted feedback on the specific area that they struggled with, allowing for more effective review of challenging questions.

Another accomplishment was our photo grading flow. When a photograph of handwritten working is submitted, the working is graded against the model solution step-by-step, pinning errors to the exact line of working where they occurred. It also transcribes handwritten working into editable LaTeX, such that if the AI makes mistakes in interpretating handwriting, it can be fixed manually on the question page itself, instead of having to upload another photo, allowing for flexibility in student submissions.

Lastly, we also created our own graph compiler, such that while converting the past year papers into SQL migrations, any graphs associated with the question part(s) would be generated in the question page itself, with the appropriate labels, asymptotes, points, etc. This sped up our paper conversion process, as there was no need to manually copy and display the graph from the paper itself in the question page.

What we learned

As it was our first time creating a project of such a scale, we learnt many things about system design along the course of the project. We learnt about the design for our authentication, payment and automatic receipt email system. We also learnt more about which variables should persist and which should have its state reset, such as solved/unsolved questions, which should retain and display their progress, as well as QR pairing tokens for the AI solution grader, which had to be reset each time.

Another aspect we learned about was the need to rate limit Gemini API request. Given that we were working with Gemini's free models, we needed to find a way for all users to be able to make use of the chatbot and solutions grader functions without going over the rate limit. As such, we designed a few layers of failsafe; per-minute limit to prevent request spamming, per-user cooldown system and daily per-tier quota. This ensures that each user will be able to make use of the AI features to the fullest extent of their subscription plans.

What's next for ProjectMath

In terms of urgency, what we need right now is greater visibility. We plan to do more advertising so as to get the product in front of more students. Alongside the feedback system within our website, it would provide user feedback that would assist us in improving the features and quality of our website. In terms of scalability, should the project eventually gain traction, we would be considering upgrading the Gemini model from a free to a paid tier, such that the platform be able to serve more requests submitted from a larger concurrent user base. We also plan to supplement our database with more SQL migrations by utilizing more open-sourced Junior College Past Year Papers, so as to exposure students to a more diverse selection of questions and build on their pattern recognition. This could be implemented through a semi-automated pipeline, so that the process of converting the paper to SQL migration becomes less tedious.

Built With

Share this project:

Updates

posted an update

ProjectMath — Build Log A LeetCode-style practice platform for Singapore H2 A-Level Maths. This is the story of how it got built, in public, from the first commit to today.

8 June 2026 → 8 August 2026 · 227 commits · ~500 questions live

June 8–15 · The foundations The first week was about proving the core loop works: pick a topic, answer a question, find out if you're right.

Express + TypeScript + Supabase backend — the first commit. Topics, questions, attempts. React + Vite frontend with KaTeX rendering, so maths looks like maths and not like code. The roadmap — the whole syllabus as a visual tree you pan and zoom around, rather than a boring list. Click a node, a drawer slides out with the concepts and every question in that topic. 24-topic H2 syllabus loaded in, with prerequisite concepts mapped per topic. Starred questions — bookmark anything you want to come back to. A visual maths keyboard (MathLive) — typing \frac{x}{5} on a laptop is miserable, so there's a proper 10-group symbol palette that inserts real LaTeX for you. Progress bars per topic. Multi-part questions — real exam questions have (a), (b)(i), (b)(ii). The app now models them properly: a shared preamble, per-part answer boxes, inline ✓/✗, and the solution only unlocks once every graded part is done. June 15–23 · Real papers, and getting grading right First real paper: ASRJC Prelim 2025 (Papers 1 & 2), followed by DHS Prelim 2025. Answer checking, reworked twice. Students write the same answer ten different ways. The checker learned numeric equivalence, or/and normalisation inside inequality chains, tolerant spacing, and MathLive's compact notation (\frac34 → \frac{3}{4}). All unit-tested. Solution tab + retry button — answers moved out of the main view so you can re-attempt a question cleanly instead of being spoiled the moment you submit. Attempts & Hints tabs alongside the question. Streaks and stats — daily streak tracking with a GitHub-style contribution heatmap. June 22–24 · The AI arrives Two big features landed back to back, and both were designed so the API key never leaves the server.

AI hint chatbot — a Socratic tutor that sits beside the question. It knows the question, the parts, and the confidential model solution, and is explicitly instructed to give one small hint at a time and never the final answer. Off-topic and jailbreak attempts get refused. Photo-based AI grading — the headline feature. Photograph your handwritten working; Gemini grades it against the stored model solution as an examiner, not a solver. It returns a per-part verdict, marks awarded, every error pinned to the step it happened on, and hints. Sketches are checked for labelled intercepts, asymptote equations, stationary points and shape. Blank photos, desk clutter and unrelated pages get filtered out and explained rather than graded. Upload via phone — desktops don't have cameras. Scan a QR code, your phone opens a capture page, and photos stream to your desktop live over WebSockets. Hit Done on the phone and the grade appears on the laptop. June 24–28 · Studying smarter Accuracy by topic — stats page now shows where you're actually weak, not just what you've finished.

Review page with 5 modes:

Corrections on questions you got wrong Practice on your weakest topics Re-attempt the solved questions that took you longest Spaced-repetition review Question randomiser Each mode locks itself if you have nothing in that bucket, rather than dumping you on an empty screen.

SM-2 spaced repetition — the Wozniak algorithm (the SuperMemo/Anki one) replaced a simpler Leitner schedule. Card state updates in the background every time you complete a question.

AI weakness diagnostic — Gemini reads your per-topic accuracy and returns a weak/moderate/strong breakdown with written insight. Locked until you've done 5 questions, so it has something to work from.

AI study plan — a quest-log of up to 10 AI-picked questions from your weakest topics. Rows tick themselves off as you get them right. Lives in a collapsible sidebar available anywhere in the app, and syncs to your account so it follows you between devices.

June 26–30 · Accounts Firebase Authentication end to end. The old anonymous session ID is gone; every request carries a verified ID token, and your history, streaks, stars, chats and gradings are tied to a real account. Editable transcription for photo grades — Gemini now transcribes your handwriting into LaTeX and shows it back to you in a rendered, per-line editor. If it misread a character, fix it and re-grade instantly without re-photographing anything. Dark theme redesign — a proper dark indigo palette, Bricolage Grotesque headings, status-styled roadmap nodes (completed / in-progress / up-next / locked), SVG icons throughout. Landing page at /, with auth-aware navigation and honest copy. June 30 – July 4 · More typeable answers, and CI Typed submissions for parts that used to be un-typeable, plus multi-value answer boxes — questions like "find a, b and c" now render one labelled box per value, and the part is only correct when every box matches. Accurate roadmap progress bars — fixed per-part correctness accounting so the bars reflect reality. GitHub Actions CI with a vitest suite over the grading logic. Model solution graphs. Sketch questions used to just say "sketch the curve" and then show you nothing. Now every sketch answer renders an actual generated graph — with asymptotes, labelled intercepts, stationary points, open/closed endpoints, parametric curves, Argand diagrams, scatter plots and shaded regions. Verified against the official mark schemes. July 3–9 · Payments Stripe integration — Checkout and Customer Portal, card and PayNow (Singapore's local rail). Pricing settled at $5/month and $25/semester (the annual plan was dropped). PayNow rollover and plan-switching. Buying PayNow while you still have PayNow time stacks on top instead of restarting. Switching from card to PayNow schedules the card to end and starts PayNow the day it does — no gap, no double-billing. Switching PayNow → card sets a trial so the card isn't charged until your PayNow period actually runs out. Transactional emails via Resend — welcome/induction, first-purchase congrats, transaction receipts (including renewals), and a daily cron that reminds PayNow users before their access expires. Each send is claimed atomically so nothing double-fires. Profile page — email, member since, plan, days left to renewal, billing portal link, today's AI usage, streak heatmap and per-topic accuracy, all in one place. Feedback form in the header, straight to email. Correct-answer tick celebration and animated streak UI. Small thing, feels good. July 5–11 · Making the free tier fair (and abuse-proof) AI calls cost real money, so this stretch was about metering them honestly instead of slamming a paywall down.

Metered free tier rather than a hard block: free accounts get 3 AI scans and 3 chat messages per day, resetting at midnight Singapore time. Paid is unlimited. Rejected scans don't count against you. Per-user cooldowns (5s for hints, 60s for grading) plus a shared request queue for all Gemini traffic — if the app is busy, your request waits in line with a friendly message instead of failing. Hint chat history resets each time you open it, by design, so the panel isn't a wall of old text — but nothing is ever deleted server-side, so limits can't be reset by reopening. Rate limits bucketed by account, not IP. Two students behind the same school NAT were sharing one bucket and starving each other. Fixed. Tier is read from the database, never from the auth token. A token caches its claims for up to an hour, which meant a cancelled subscriber could keep paid access for another hour. Now every request derives access from the live subscription row. Stripe webhooks made idempotent with an event ledger, so a replayed payment event can never grant two billing periods for one payment. Typed re-grades paced properly — fixing a transcription typo is instant, but the exemption is spent per scan so the route can't be used as an uncooled free grader. Generic error messages to the client instead of raw internal ones. July 11–14 · The content explosion Ten days, nine more question sets.

Prelim papers added: YIJC · EJC · JPJC · NJC · NYJC · VJC — joining ASRJC, DHS, HCI, ACJC, CJC and RI. Twelve schools, Papers 1 and 2 each.

Tutorial discussion questions (non-exam, provenance stripped) across four strands:

Functions & Graphs — parametrics, systems of equations, graphing techniques, functions, transformations, conics, inequalities Calculus — differentiation techniques and applications, Maclaurin series, integration techniques, definite integrals, differential equations Statistics — permutations & combinations, probability, discrete random variables, binomial, normal, sampling & estimation, hypothesis testing, correlation & regression Vectors (basic / lines / planes), Sequences & Series, and Complex Numbers Given diagrams in prompts. Loads of questions say "the diagram shows…" and then ship no diagram, because the figure lived in a PDF. Those diagrams are now reconstructed and rendered in the question, using the same engine as the solution graphs — including two 3-D vector scenes (a triangular canopy, an inclined roof slab) drawn as the exam's own oblique projection, with the projection basis measured off the original figures so the reproduction matches the paper.

Solutions reformatted so each part label starts on its own line instead of running together in one block.

July 13–19 · Security hardening and going live Row-level security enabled across the database, with all public grants revoked — the backend service is the only client. Auth required on the question and solution endpoints. The ID patterns were predictable enough that the whole question bank was scrapable without an account. Global backstop rate limiter over the entire API surface, plus helmet security headers. Length caps on all user-supplied strings. Deployed to Google Cloud Run as a single container with WebSockets intact, plus a repeatable deploy script and push-to-main continuous deployment. Card-only launch — PayNow put behind a feature flag for the initial release. Landing page copy cleanup and footer disclaimer. August · Polish More questions made typeable — a review of every "find…" part that the checker can grade robustly (± value pairs, inequality chains, symbolic expressions, coordinate and vector components) unlocked 24 more parts for typed answers instead of just revealing the answer. Roadmap viewport fixes — stale height on async layout shifts, and lateral scrolling / zoom on the roadmap. Responsive landing page, replacing a shrink-to-fit hack. Header no longer clips the account dropdown.

Log in or sign up for Devpost to join the conversation.