Перейти к содержимому
Основатель, Full-stack разработчик2026
#Python#FastAPI#PostgreSQL#Redis#Kafka#Celery#OpenRouter#Next.js#TypeScript#Docker#OpenTelemetry

Tech Path Finder

Платформа подготовки IT-специалистов: 65 курсов с квизами и три AI-тренажёра, где спорит автор PR, торгуется оппонент на переговорах и оценивается ответ на собеседовании

О проекте

Tech Path Finder это платформа подготовки IT-специалистов к карьерному росту. Начиналась она как курсы с квизами, а за последний год выросла в другое: к теории и вопросам добавились три тренажёра, в которых на той стороне сидит не форма с вариантами ответа, а собеседник со своими интересами.

Проблема, которую платформа решает, простая. Разработчик не знает, что именно учить для перехода на следующий уровень, и тратит время на хаотичное потребление материала без обратной связи о реальных пробелах. Квиз показывает, что он знает. Тренажёр показывает, как он себя ведёт, когда с ним спорят.

Ключевая идея это персонализация через данные: система строит профиль компетентности с учётом времени. Знания, которые не применяются, постепенно деградируют, и платформа напоминает об этом раньше, чем это станет проблемой на собеседовании.

Что внутри

Обучение и оценка знаний

65 курсов по категориям: Agile/Scrum, Python, Django, FastAPI, Kubernetes, Docker, AWS, System Design, LLM/RAG, ClickHouse, Kafka, Playwright, LeetCode и другие. В сумме 940 тем, 941 теоретическая статья и 8457 вопросов в квизах. Каждый курс содержит:

  • Теорию в Markdown с диаграммами и глоссарием терминов
  • Квизы трёх уровней сложности (junior / middle / senior) с детальными объяснениями
  • Экзамены по 20 детерминированных вопросов на вариант, с историей сдач
  • Прогресс по завершению тем и точности ответов

Алгоритм деградации знаний

Proficiency-score каждой темы снижается со временем, если пользователь не возвращается к материалу:

proficiency = accuracy × recency_factor × 100
recency_factor = max(0.3, 1 - days_since_last_answer / 30)

Темы автоматически попадают в «критичные» (< 40%), «слабые» (40–65%) или «не начатые», и система строит персональную очередь для повторения.

Мок-интервью с AI-оценкой

Структурированные сессии по языкам и уровням, 1236 вопросов в базе. Ответы оцениваются моделью через OpenRouter, на выходе итоговый скор и разбор по каждому ответу. Формат express или полный, стоимость 10 кредитов за сессию.

Code Review Arena

Самое сложное из добавленного за год. Пользователю дают проблемный PR, он пишет свободные замечания, а автор кода отвечает и спорит. Обычный квиз по коду для этого не годился: там достаточно узнать баг, а здесь надо ещё и настоять на своём.

Домен code_review_arena собран из отдельных частей: генерация сценариев, синхронизация сидов, оценка детекции нулевого раунда, диалог с автором, финализация с судьёй, модерация. В библиотеке 133 сценария. Подробный разбор в посте «Code Review Arena».

Тренажёр переговоров

78 сценариев сложных разговоров. На той стороне ролевой персонаж со скрытой карточкой: интересы, страхи, условия, при которых он раскрывается и идёт на уступки. Персонаж отвечает в роли, а параллельно с диалогом идёт разбор, которого сам персонаж не видит.

На выходе главный результат переговоров, профиль по шести параметрам процесса и PDF-отчёт с цитатами из разговора. Есть голосовой режим. Разбор в посте «Тренажёр переговоров».

Code Review как упражнения

Практические задания с реальным кодом на Python, Go, Java, Ruby и других языках. Пользователь находит баги и нарушения, система сравнивает с эталоном по трёхбалльной шкале (0 / 0.5 / 1.0). Есть ежедневный челлендж и отслеживание слабых типов ошибок по языкам.

Геймификация

XP-система с событиями-триггерами (завершение темы +50, экзамен +100, стрики +25/100), достижения по милестонам, ежедневные стрики, дашборд с тепловой картой активности и историей экзаменов.

Архитектурные решения

PythonFastAPIPostgreSQLRedisKafkaCeleryOpenRouterNext.jsReactTypeScriptTailwind CSSDockerNginxOpenTelemetryJaegerPrometheus

Backend: Domain-Driven Design

14 независимых доменов, каждый со своими api.py, service.py, models.py, schemas.py. За год их стало на семь больше, и это лучший показатель того, куда двигался проект:

ДоменОтветственность
authJWT, OAuth (Google/Yandex/GitHub), восстановление пароля
usersПрофили, достижения, XP, настройки
contentКвизы, экзамены, прогресс, рекомендации
interviewМок-интервью, AI-оценка, расход кредитов
code_reviewУпражнения с кодом, ежедневные челленджи
code_review_arenaСценарии PR, диалог с автором, судья, модерация сидов
negotiationsРолевой персонаж, разбор реплик, голос, PDF-отчёты
billingКредитная система, промокоды, рефанды
adminАналитика, управление пользователями, модерация
seoWordstat, аудит, скоринг, цели, диагностика, бэкфилл
mediaЗагрузка, обработка и хранение медиа
commentsКомментарии с лайками
notificationsEmail-рассылки, отчёты
feedbackОбратная связь

Всего около 54 000 строк Python в app/ и 92 миграции.

Frontend: Feature-Sliced Design

Next.js 16.2.12 (App Router) и React 19.2.3, 75 страниц, три route group'а:

  • (main) для аутентифицированных страниц с навигацией
  • (auth) для публичных: вход, регистрация, восстановление
  • (admin) для панели администратора

Все API-вызовы идут через Server Actions с 'use server'. Токены читаются из httpOnly cookies исключительно на сервере, ни один токен не достигает клиентского кода.

Контент как код

Курсы версионируются в Git как JSON и Markdown в content/data/:

content/data/
  agile/
    ceremonies.json     # Вопросы подтемы с объяснениями
    ceremonies.md       # Теоретическая статья
    glossary.json       # Глоссарий терминов
    exam.json           # 20 детерминированных вопросов

Обновление контента это коммит в Git и редеплой. Никакой CMS, никакой БД для контента. Рядом так же лежат 133 сценария арены, 78 сценариев переговоров и 1236 вопросов мок-интервью.

Инфраструктура

nginx → next.js (:3000) + fastapi (:8000)
├── postgres     # Основная БД
├── redis        # Сессии, rate limiting, кэш
├── kafka        # Event streaming, аудит-лог
├── celery       # Фоновые задачи, email
├── jaeger       # Distributed tracing
└── plausible    # Privacy-first аналитика

Технические вызовы и решения

Ролевой персонаж, который не подглядывает в разбор

Проблема: в тренажёре переговоров одна и та же LLM должна одновременно играть оппонента и оценивать реплики пользователя. Если оба режима живут в одном диалоге, персонаж начинает подыгрывать: он видит разбор и сам подстраивается под правильный ответ.

Решение: протокол разведён. Персонаж отвечает в роли по внутренней логике скрытой карточки (интересы, страхи, условия раскрытия и уступок), разбор идёт параллельным потоком, и персонажу он не виден. LLM-ядро переиспользуется из домена interview, а протокол поверх него свой.

Healthcheck, который уронил celery через SIGBUS

Проблема: проверка здоровья контейнера трое суток копила mmap-файлы prometheus_client, забила tmpfs, форки celery начали умирать с SIGBUS, задачи с acks_late закружились в очереди и за полторы минуты выбрали дневную квоту писем.

Решение: unset PROMETHEUS_MULTIPROC_DIR для команды healthcheck, tmpfs с запасом, счёт писем после SMTP вместо счёта до, отдельный алерт на смерть исполнителя. Полный разбор с хронологией и пунктами в постмортеме.

Тасование ответов без утечки правильного индекса

Проблема: если тасовать варианты только на фронтенде, пользователь запоминает позицию правильного варианта в исходном массиве.

Решение: Fisher-Yates выполняется на сервере при каждом запросе. Клиент отправляет индекс в пространстве перетасованных вариантов, сервер переводит его обратно для валидации.

Rate limiting через Lua и Redis

Проблема: защита чувствительных endpoint'ов от брутфорса без внешних зависимостей.

Решение: атомарный sliding window через Lua-скрипт в Redis, INCR и EXPIRE в одной транзакции. Свои лимиты на каждый endpoint:

POST /auth/login        → 5 / 15 минут / IP
POST /auth/register     → 3 / час / IP
POST /auth/forgot-pw    → 3 / час / IP

Кредитный биллинг без гонок

Проблема: атомарное списание кредитов при параллельных запросах без двойного расхода.

Решение: ledger-паттерн, append-only таблица CreditTransaction плюс денормализованный кэш User.credits_balance, атомарное обновление через SELECT FOR UPDATE. Сессии мок-интервью идемпотентны по ключу.

Refresh-токены без race condition

Проблема: при одновременных запросах с истёкшим токеном оба могут попытаться обновить, и один получит инвалидированный.

Решение: атомарный GETDEL из Redis при обновлении. Токен читается и удаляется в одной операции, второй запрос получает None и идёт на /auth/refresh снова.

Observability с нуля

Полный стек наблюдаемости без vendor lock-in:

  • Tracing: FastAPI, SQLAlchemy и Redis инструментированы через OpenTelemetry в Jaeger
  • Metrics: Prometheus и кастомные метрики (регистрации, XP, завершения тем, потерянные воркеры)
  • Health checks: /health и /health/ready с проверкой БД и Redis
  • Graceful shutdown: дренаж in-flight запросов с 30-секундным таймаутом

Безопасность

  • Пароли: bcrypt с 12 раундами
  • JWT: HS256, access на 30 минут и refresh на 7 дней в httpOnly cookies
  • OAuth: state-параметр верифицируется через Redis (TTL 1 час) против CSRF
  • Чувствительные поля: Fernet-шифрование при наличии APP_ENCRYPTION_KEY
  • SQL: параметризованные запросы через SQLAlchemy
  • Linting: Bandit и Ruff в pre-commit hooks

Результаты

65
Курсов
9693
Вопросов
3
AI-тренажёра
643
Тестов

9693 вопроса это 8457 в квизах курсов и 1236 в мок-интервью. Тесты: 643 штуки в 87 файлах. Коммитов в репозитории 1062.

Что получилось построить

  • Полноценный SaaS с нуля, от архитектуры до деплоя
  • Алгоритм деградации знаний, дающий персонализацию без ML-оверхеда
  • Три AI-тренажёра, в которых оценивается не выбор варианта, а поведение в диалоге
  • Контент как код: 65 курсов и 211 сценариев обновляются через Git без CMS
  • Продакшн-стек с трейсингом, метриками и graceful shutdown

Извлечённые уроки

Контент как код работает лучше CMS для технических курсов: версионирование, code review контента и откат изменений достаются из Git бесплатно.

Алгоритм деградации знаний оказался неочевидно простым решением. Полноценный spaced repetition с планировщиком не понадобился, хватило time-decay функции, чтобы рекомендации стали ощутимо лучше.

DDD-разбиение оправдалось с первого месяца и особенно за последний год: семь новых доменов приросли, не тронув старые. Арена и переговоры переиспользуют LLM-ядро интервью, но живут своей жизнью.

Тренажёр отличается от квиза не интерфейсом, а тем, что на той стороне есть интерес. Автор PR спорит, оппонент на переговорах торгуется и что-то скрывает. Как только у собеседника появились свои цели, задача перестала быть про проверку знания и стала про поведение, и это оказалась совсем другая инженерная работа.

JWT в httpOnly cookies через Server Actions решает проблему токенов на фронтенде: клиентский код никогда их не видит, и XSS их не похитит.

Похожие материалы

Проекты с похожими технологиями и задачами

AI Builders: открытый учебник о LLM в backend и разобранные системы

Основатель, автор • 2026

Платформа на ai.potapov.me для инженеров, которые встраивают LLM в работающие системы. Открытый учебник на 10 частей и 58 глав, под ним разобранные системы с числами и списком пропусков. Бесплатно, без регистрации.

  • Python
  • FastAPI
  • Django
  • Pydantic
  • Celery
  • +4
Читать детальный кейс →

Code Review Arena: живое ревью pull request с ИИ-автором

Основатель, Full-stack Engineer • 2026

Тренажёр code review: проблемный PR, построчные замечания и диалог с автором, который спорит и правит код. Часть Tech Path Finder.

  • Python
  • FastAPI
  • PostgreSQL
  • Celery
  • OpenRouter
  • +1
Читать детальный кейс →

Тренажёр переговоров: разговор с персонажем, у которого есть скрытая карта

Основатель, Full-stack Engineer • 2026

Симуляция сложных разговоров: у собеседника мотивы и условия уступки, которых вы не знаете заранее. В конце отчёт с вашими цитатами. Часть Tech Path Finder.

  • Python
  • FastAPI
  • PostgreSQL
  • Celery
  • OpenRouter
  • +2
Читать детальный кейс →