Skip to content

the-mrinal/revise

Repository files navigation

Revise

Never forget what you learn.

Track everything you study — coding problems, math exercises, design tutorials, language lessons, and more. FSRS — the modern spaced-repetition algorithm behind Anki — tells you exactly when to revise, so knowledge sticks for good.

Live Demo CI License Python Supabase


Landing Page

What It Does

You learn something. You forget it in a week. This fixes that.

Revise is a browser extension + web dashboard that:

  • Auto-detects the platform you're using (LeetCode, Codeforces, HackerRank, Khan Academy, etc.)
  • Lets you add custom platforms — track any website you learn from
  • Times your study with a built-in timer — no manual entry
  • Schedules revisions using FSRS, the modern spaced repetition algorithm behind Anki
  • Shows a dashboard with stats, charts, activity feed, and a filterable table of everything you've tracked

No passwords. Sign in with a magic link. Your data is yours.

Screenshots

Landing Page

Supported Platforms

10+ platforms supported out of the box, plus add your own.

Dashboard

Dashboard

Full analytics: items tracked, difficulty breakdown, platform distribution, revision schedule, and daily activity — all in one view.

Magic Link Login

Login

No passwords to remember. Enter your email, click the link, you're in.

Browser Extension

Extension - Auto Detect Extension - Capture Problem

The extension auto-detects the URL and title. Navigate to any supported platform and it picks it up instantly.

Extension - Timer Running Extension - Save Question

Start a timer when you begin studying. When you're done, rate your recall (1-5 stars), say how you solved it (yourself, with a hint, or from the solution), add notes, and save. FSRS handles the rest.

How It Works

Browser Extension (Chrome / Safari)
        |
        |  REST API
        v
   FastAPI Server  -->  Supabase (Postgres + Auth)
        |
        v
   Web Dashboard (revise.mrinal.dev/dashboard)
  1. Study something on any supported platform (or add your own)
  2. Click the extension — it auto-detects the URL and title
  3. Start the timer, study, stop when done
  4. Rate your recall (1-5 stars) and save
  5. FSRS schedules your next review — things you found hard come back sooner, easy ones later. Peeking at the solution brings an item back quickly, no matter the rating
  6. Check the dashboard for what's due today, your stats, and your full history

Supported Platforms

Platform Auto-detected
LeetCode Yes
Codeforces Yes
HackerRank Yes
CodeChef Yes
GeeksForGeeks Yes
InterviewBit Yes
AtCoder Yes
NeetCode Yes
AlgoMonster Yes
DesignGurus.io Yes
Custom Platforms User-defined

Any other URL works too — it's tagged as "other". You can add custom platforms from the dashboard settings to auto-detect any website.

Features

  • FSRS Spaced Repetition — the same algorithm behind modern Anki. Rate your recall 1-5 stars, and it models your memory to schedule the next review at the optimal time, tunable via a per-user target retention (70–99%).
  • Honest Check-ins — record how you solved each item: by yourself, with a hint, or from the solution. Assisted recalls earn shorter intervals so the schedule reflects what you actually know.
  • Built-in Timer — start when you begin studying, pause/resume, stop when done. Time is recorded automatically.
  • Custom Platforms — add any website from the dashboard settings. Define a name and URL pattern, and it auto-detects just like the built-in platforms.
  • Analytics Dashboard — items tracked, difficulty breakdown, platform distribution, revision schedule, daily activity feed.
  • Magic Link Auth — no passwords. Enter your email, click the link in your inbox, done. Powered by Supabase Auth.
  • 10+ Platforms — auto-detects LeetCode, Codeforces, HackerRank, CodeChef, GeeksForGeeks, InterviewBit, AtCoder, NeetCode, AlgoMonster, DesignGurus.
  • Browser Extension — Chrome and Safari. Captures the current URL with one click.
  • Due for Revision — the extension and dashboard both show which items are due today, so you always know what to revise.
  • CSV Export — download your entire history as a CSV.
  • Per-user Data Isolation — Row Level Security on Supabase. Each user only sees their own data.

Getting Started

Use the hosted version (easiest)

  1. Go to revise.mrinal.dev
  2. Click Get Started Free
  3. Enter your email and click Send Magic Link
  4. Check your inbox, click the link — you're logged in
  5. Install the browser extension (see below)
  6. Start learning!

Install the Chrome Extension

  1. Download extension.zip from the latest release
  2. Unzip the downloaded file
  3. Open chrome://extensions in Chrome
  4. Enable Developer mode (top right toggle)
  5. Click Load unpacked and select the unzipped folder
  6. Pin the extension from the puzzle icon in the toolbar

Safari: Available on request. It requires a macOS/iOS native app wrapper built with Xcode. Reach out at dmrinal626@gmail.com and I'll send you the build.

Self-host (for developers)

1. Supabase Setup

Create a Supabase project and run this in the SQL Editor:

create table public.questions (
  id bigint generated always as identity primary key,
  user_id uuid not null references auth.users(id) on delete cascade,
  url text not null,
  title text,
  platform text,
  difficulty text,
  self_rating integer check (self_rating between 1 and 5),
  time_taken integer,
  notes text,
  solved_at timestamptz default now(),
  easiness_factor double precision default 2.5,  -- legacy SM-2 (kept for rollback)
  interval integer default 1,
  repetitions integer default 0,                 -- legacy SM-2 (kept for rollback)
  next_review date,
  last_reviewed timestamptz,
  attempts integer default 1,
  -- study metadata
  pattern text,
  question_type text default 'dsa',
  approach text,
  mistakes text,
  time_complexity text,
  space_complexity text,
  -- FSRS memory state + solution source (migration 009)
  stability double precision,
  fsrs_difficulty double precision,
  fsrs_state smallint,
  solution_source text check (solution_source in ('self', 'hint', 'solution'))
);

alter table public.questions enable row level security;

create policy "Users see own questions" on public.questions for select using (auth.uid() = user_id);
create policy "Users insert own questions" on public.questions for insert with check (auth.uid() = user_id);
create policy "Users update own questions" on public.questions for update using (auth.uid() = user_id);
create policy "Users delete own questions" on public.questions for delete using (auth.uid() = user_id);

create index idx_questions_user_url on public.questions(user_id, url);
create index idx_questions_next_review on public.questions(user_id, next_review);

-- Custom platforms (for user-defined URL patterns)
create table public.user_platforms (
  id bigint generated always as identity primary key,
  user_id uuid not null references auth.users(id) on delete cascade,
  name text not null,
  url_pattern text not null,
  created_at timestamptz default now()
);

alter table public.user_platforms enable row level security;

create policy "Users see own platforms" on public.user_platforms for select using (auth.uid() = user_id);
create policy "Users insert own platforms" on public.user_platforms for insert with check (auth.uid() = user_id);
create policy "Users update own platforms" on public.user_platforms for update using (auth.uid() = user_id);
create policy "Users delete own platforms" on public.user_platforms for delete using (auth.uid() = user_id);

create unique index idx_user_platforms_unique on public.user_platforms(user_id, name);

-- Per-question audit/event log (history of every solve / review / re-attempt).
-- Also available as server/migrations/001_question_events.sql
create table public.question_events (
  id              bigint generated always as identity primary key,
  user_id         uuid not null references auth.users(id) on delete cascade,
  question_id     bigint not null references public.questions(id) on delete cascade,
  event_type      text not null,            -- 'created' | 'reviewed' | 'attempted'
  self_rating     integer,
  time_taken      integer,
  interval        integer,                  -- schedule snapshot AFTER this event
  repetitions     integer,                  -- legacy SM-2 (frozen post-FSRS)
  easiness_factor double precision,         -- legacy SM-2 (frozen post-FSRS)
  next_review     date,
  reconstructed   boolean default false,    -- true for backfilled rows (approximate)
  created_at      timestamptz default now(),
  -- FSRS snapshot + solution source (migration 009)
  solution_source text check (solution_source in ('self', 'hint', 'solution')),
  stability       double precision,
  fsrs_difficulty double precision,
  fsrs_state      smallint
);

alter table public.question_events enable row level security;

create policy "Users see own events" on public.question_events for select using (auth.uid() = user_id);
create policy "Users insert own events" on public.question_events for insert with check (auth.uid() = user_id);
create policy "Users update own events" on public.question_events for update using (auth.uid() = user_id);
create policy "Users delete own events" on public.question_events for delete using (auth.uid() = user_id);

create index idx_qevents_question on public.question_events(user_id, question_id, created_at);

-- Per-user settings (e.g. how many revisions to surface as "due" at once)
create table public.user_settings (
  user_id              uuid primary key references auth.users(id) on delete cascade,
  revision_queue_size  integer not null default 20,  -- 0 = unlimited
  updated_at           timestamptz default now(),
  -- FSRS (migration 009)
  desired_retention    double precision not null default 0.9
    check (desired_retention between 0.70 and 0.99),
  fsrs_params          jsonb                          -- per-user optimized parameters (null = defaults)
);

alter table public.user_settings enable row level security;

create policy "Users see own settings" on public.user_settings for select using (auth.uid() = user_id);
create policy "Users insert own settings" on public.user_settings for insert with check (auth.uid() = user_id);
create policy "Users update own settings" on public.user_settings for update using (auth.uid() = user_id);
create policy "Users delete own settings" on public.user_settings for delete using (auth.uid() = user_id);

Existing deployments: apply the incremental migrations in server/migrations/ (run each .sql in the Supabase SQL Editor).

Configure Auth redirect URLs in Supabase Dashboard:

  • Site URL: https://your-domain.com/dashboard
  • Redirect URL: https://your-domain.com/api/auth/callback

2. Environment Variables

Create a .env file:

SUPABASE_URL=https://xxx.supabase.co
SUPABASE_ANON_KEY=eyJ...
SUPABASE_SERVICE_ROLE_KEY=eyJ...
SUPABASE_JWT_SECRET=your-jwt-secret
SERVER_URL=https://your-domain.com

3. Run

docker compose up -d

The server starts at http://localhost:8765. The landing page is at / and the dashboard at /dashboard.

4. Point the extension at your server

Update the SERVER_URL in the extension's config to point to your self-hosted instance.

Deploying updates

The hosted instance is deployed from the Deploy workflow in the Actions tab (Run workflow → main). It pulls the latest code on the server, rebuilds the container, and verifies the site is up. Database migrations in server/migrations/ are applied manually against Supabase.

API Endpoints

All endpoints except auth require an Authorization: Bearer <token> header.

Method Endpoint Description
POST /api/auth/magic-link Send magic link email
GET /api/auth/callback Handle auth callback (PKCE + implicit flow)
POST /api/auth/refresh Refresh access token
POST /api/questions Save a new item
GET /api/questions List all items
PUT /api/questions/{id} Edit an item
DELETE /api/questions/{id} Delete an item
POST /api/questions/{id}/review Submit a review rating + solution source (triggers FSRS)
GET /api/revisions/today Get items due for revision today
GET /api/activity/today Today's new + revised items
GET /api/stats Summary statistics
GET /api/platforms List built-in + custom platforms
POST /api/platforms Add a custom platform
DELETE /api/platforms/{id} Delete a custom platform

Scheduling Algorithm (FSRS)

The revision schedule uses FSRS (Free Spaced Repetition Scheduler, the algorithm modern Anki adopted), via py-fsrs. It models each item's memory stability and difficulty from your review history and schedules the next review just before you'd forget.

Your 1-5 star rating combines with how you solved it:

Rating Solved myself Used a hint Saw the solution
1-2 Back soon (lapse) Back soon (lapse) Back soon (lapse)
3 Short interval Short interval Back soon (lapse)
4 Normal interval Capped — short Back soon (lapse)
5 Longest interval Capped — short Back soon (lapse)

Reading the answer always brings the item back quickly — solving it yourself is the only way to earn long intervals. A per-user target retention setting (default 90%) controls the trade-off between review frequency and forgetting.

Migrating an existing deployment from SM-2: apply server/migrations/009_fsrs.sql, deploy, then run python migrate_to_fsrs.py once (idempotent) to replay each question's review history through FSRS. Legacy rows also seed themselves lazily on their first post-migration review, so the backfill is a nicety, not a requirement.

DSA Pattern Study Guides

The repo includes 15 in-depth study guides covering the classic DSA patterns — arrays/matrices, two pointers, sliding window, stacks, linked lists, trees, graphs, backtracking, dynamic programming, greedy, binary search, heaps, and more — each with worked problem analyses and step-by-step SVG diagrams. They're also served on the hosted instance at revise.mrinal.dev/research.

Tech Stack

  • Backend: Python, FastAPI
  • Database: Supabase (Postgres + Row Level Security)
  • Auth: Supabase Auth (magic link / passwordless)
  • Frontend: Vanilla HTML/CSS/JS (no frameworks)
  • Extension: Manifest V3 (Chrome & Safari)
  • Deployment: Docker Compose

Contributing

Contributions welcome! See CONTRIBUTING.md for dev setup, testing, and PR guidelines. Good entry points: platform support requests and issues labeled good first issue.

License

MIT

About

Track coding practice with spaced repetition. Browser extension + FastAPI server for LeetCode, CodeChef, HackerRank & more.

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

3 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors