Skip to content

engineeringwithtemi/acodeaday

Repository files navigation

acodeaday

A daily coding practice app with spaced repetition to help you master the Blind 75.

Open source. Self-host it, fork it, make it yours.


Quick Start

Prerequisites

  • Python 3.13+
  • Node.js 18+
  • Docker & Docker Compose
  • Supabase CLI
  • uv (Python package manager)

Setup

  1. Start Supabase (PostgreSQL database)

    supabase start

    Copy the DB URL from the output and update .env:

    # Change postgresql:// to postgresql+asyncpg://
    DATABASE_URL=postgresql+asyncpg://postgres:postgres@localhost:54322/postgres
  2. Start Judge0 (Code execution engine)

    # Start Judge0 in background
    docker-compose up -d
    
    # Verify it's running
    curl http://localhost:2358/
    
    # View logs if needed
    docker-compose logs -f judge0-server

    See DOCKER.md for detailed Docker commands and troubleshooting.

  3. Set up Backend

    cd backend
    uv venv
    uv sync
    
    # Run database migrations
    uv run alembic upgrade head
    
    # Seed problems (first 15 Blind 75)
    uv run python scripts/seed_problems.py
    
    # Start backend server
    uv run uvicorn app.main:app --reload
  4. Set up Frontend

    cd frontend
    npm install
    npm run dev
  5. Access the app


Project Structure

acodeaday/
├── backend/              # FastAPI backend
│   ├── app/
│   │   ├── config/      # Settings & logging
│   │   ├── db/          # Database models & connection
│   │   ├── routes/      # API endpoints
│   │   ├── services/    # Business logic
│   │   └── middleware/  # Auth & request handling
│   ├── migrations/      # Alembic database migrations
│   ├── scripts/         # Seed data & utilities
│   └── tests/
├── frontend/            # React + TanStack frontend
│   ├── src/
│   │   ├── pages/      # Route components
│   │   ├── components/ # UI components
│   │   ├── hooks/      # Custom React hooks
│   │   └── lib/        # API client & utilities
│   └── public/
├── supabase/           # Supabase configuration
├── docker-compose.yml  # Judge0 & services
└── .env               # Environment variables

Tech Stack

Component Technology
Frontend React 19 + TanStack Router + React Query
Code Editor Monaco Editor
Backend FastAPI (Python 3.13+, async)
Database PostgreSQL (via Supabase)
ORM SQLAlchemy 2.0 (async)
Migrations Alembic
Code Execution Judge0 CE
Auth Supabase Auth (JWT Bearer tokens)
AI Chat litellm (Gemini, OpenAI, Anthropic)
Logging Structlog

Development

Backend

cd backend

# Install dependencies
uv sync

# Run tests
uv run pytest

# Run with auto-reload
uv run uvicorn app.main:app --reload --port 8000

# Create new migration
uv run alembic revision --autogenerate -m "description"

# Apply migrations
uv run alembic upgrade head

# Rollback migration
uv run alembic downgrade -1

Frontend

cd frontend

# Install dependencies
npm install

# Run dev server
npm run dev

# Build for production
npm run build

# Run tests
npm test

Database

# Start Supabase
supabase start

# Stop Supabase
supabase stop

# Reset database (WARNING: deletes all data)
supabase db reset

# View Supabase Studio
# URL shown in 'supabase start' output (usually http://localhost:54323)

Docker

# Start all services
docker-compose up

# Start only Judge0
docker-compose up judge0

# Stop all services
docker-compose down

# View logs
docker-compose logs -f judge0

Environment Variables

Copy .env.example to .env and configure:

Variable Description Default
DATABASE_URL PostgreSQL connection (asyncpg) postgresql+asyncpg://...
SUPABASE_URL Supabase project URL http://localhost:54321
SUPABASE_KEY Supabase anon/public key -
DEFAULT_USER_EMAIL Default user email admin@acodeaday.local
DEFAULT_USER_PASSWORD Default user password changeme123
JUDGE0_URL Judge0 API endpoint http://localhost:2358
LLM_SUPPORTED_MODELS Comma-separated LLM models gemini/gemini-2.5-flash
ENVIRONMENT Environment (development/production) development
DEBUG Enable debug mode true
LOG_LEVEL Logging level INFO

API Documentation

Once the backend is running, visit:

Key Endpoints

Method Endpoint Description
GET /api/problems List all problems
GET /api/problems/{slug} Get problem details
POST /api/run Run code against test cases
POST /api/submit Submit solution (all tests)
POST /api/rate-submission Rate difficulty (Anki SM-2)
GET /api/today Get today's session
GET /api/progress Get user progress
GET /api/mastered Get mastered problems
POST /api/mastered/{id}/show-again Re-add to rotation
POST /api/code/save Save code (auto-save)
GET /api/submissions/{id} Get submission history
POST /api/chat/sessions Create AI chat session

Architecture

Spaced Repetition (Anki SM-2)

The app uses the Anki SM-2 spaced repetition algorithm:

Rating System: After successful submission, rate difficulty:

  • Again: Reset to 1 day, decrease ease factor
  • Hard: Slower growth (×1.2), decrease ease
  • Good: Normal growth (×ease factor)
  • Mastered: Immediately exit rotation

Algorithm: Interval grows based on ease factor (default 2.5, min 1.3). Auto-mastery when interval reaches 30+ days.

"Show Again": Manually re-add mastered problems to rotation (resets ease factor).

Daily Session Logic

Each day presents up to 3 problems:

  1. Review #1: Oldest overdue problem (if any)
  2. Review #2: Second oldest overdue problem (if any)
  3. New Problem: Next unsolved in Blind 75 sequence

Code Execution Flow

User writes code in Monaco Editor
    ↓
Frontend sends to /api/submit
    ↓
Backend wraps code with test harness
    ↓
Sends to Judge0 for execution
    ↓
Judge0 runs code in sandbox
    ↓
Returns results (pass/fail per test case)
    ↓
Backend updates user_progress if all passed
    ↓
Frontend displays results

Documentation

  • README.md (this file) - Quick start and overview
  • TASKS.md - Detailed implementation tasks and patterns
  • DOCKER.md - Docker commands and troubleshooting
  • spec.md - Complete product specification
  • CLAUDE.md - Project instructions for Claude Code

License

MIT — do whatever you want with it.


Core Philosophy

"A code a day keeps rejection away"

Focus on understanding through consistent practice, not cramming. One problem at a time, reviewed at optimal intervals for long-term retention.

About

Leetcode But Better With Spaced Repetition

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages