All work

In progress

StudyPilot

Turns a learning goal into a roadmap, daily focus blocks and answers from your own notes.

Role
Solo. Backend, frontend and AI agents.
Context
Personal project, ongoing
Stack
FastAPI, PostgreSQL, pgvector, React, TypeScript, Telegram Mini Apps, aiogram, Docker, Playwright
AI agents sharing one learning loop
6
API routes
28
PostgreSQL tables, with raw SQL migrations
10

The problem

Learning tools each solve one slice: a plan in one app, a timer in another, and a chatbot that doesn’t know your material. I wanted one loop where the plan, the daily work and your notes feed each other.

What I built

You set a goal, your level, a deadline and your weekly hours. A Roadmap agent turns them into stages and milestones, stored as data rather than text. A Daily Coach turns the current stage into focus blocks, and a Focus agent records real sessions, which feed the analytics and a weekly review.

Uploaded TXT, Markdown and PDF files are chunked, embedded and indexed in pgvector. A RAG agent rewrites the question, searches, reranks the results and answers with sources. On Sundays a Telegram bot can send a digest of the week.

It runs as a Telegram Mini App: React and TypeScript in front, FastAPI with async SQLAlchemy and PostgreSQL 16 behind, packaged with Docker and served through Caddy.

Key decisions

  1. Answers from your own material

    Problem
    A general chatbot answers without knowing what you’re studying.
    Decision
    Uploaded documents are embedded into pgvector, and answers come from the retrieved and reranked passages, with their sources. When your material doesn’t contain the answer, the agent says so.
  2. Each user’s data stays theirs

    Problem
    Shared search over everyone’s notes would leak material between users.
    Decision
    Every plan, document, focus session and review is scoped to its user, and search never crosses from one user’s material to another’s.
  3. Sign-in without passwords

    Problem
    A Mini App runs inside Telegram, where users are already signed in.
    Decision
    The server validates Telegram’s signed launch data instead of storing passwords.
  4. The model proposes, the backend decides

    Problem
    An AI that edits the roadmap directly can break a plan the learner relies on.
    Decision
    Roadmaps and weekly-review proposals are treated as untrusted input: the backend validates them, and the learner or a safe service flow applies them. The model never changes the roadmap itself.
  5. Tests never call a real model

    Problem
    Tests that reach real AI providers are slow, flaky and cost money.
    Decision
    Fake LLM, embedding and Telegram providers stand in during tests, and the production configuration refuses to start with a fake provider.

How it’s tested

Pull requests run the frontend’s type check, tests and build, apply the migrations to a pgvector Postgres, and run Ruff and Pytest on the backend. On the main branch, Playwright runs end-to-end tests against a seeded backend with fake AI providers.

Limits and next steps

The Weekly Review works in the backend but has no screen of its own yet, and profile editing returns 501. Answers are AI-generated and can be wrong.

Build the Weekly Review screen and profile settings, then test the quality of document search and daily plans with real learners.

Sources