Прототип-трекер — это одна штука. Запустить продукт с мультитенантностью, четырьмя ролями (staff, manager, organizer, investor), Telegram Mini App и двумя отдельными базами данных — совсем другая история. В начале января 2026 года я понял: архитектура прототипа не выдержит нагрузки. Пришлось перестраивать всё с нуля.

Монорепо вместо хаоса

Первое решение — собрать Django 5, Next.js 14 и Telegram Mini App (Vite + React) в один репозиторий. Три отдельных репозитория — это три CI/CD, три источника правды, три места для документации. Монорепо даёт синхронизацию. Меняешь API в Django — сразу обновляешь типы в frontend. Коммит содержит полную картину изменений. Одна ветка — один feature, от бэкенда до UI.

Docker-compose вырос до 9 контейнеров. Два PostgreSQL 15: gonka_db для основных данных (пользователи, подписчики, настройки), txs_db для транзакций (исторические эпохи, награды, bulk import). Отдельная база для транзакций — быстрее запросы, проще масштабировать, проще бэкапить. gonka_redis (Redis 7) для кеша и очередей Celery. gonka_xray — VPN proxy на базе Xray, через который ходят запросы к Discord API (Discord блокирует российские IP, а алерты приходят через Discord webhook).

Backend поднял на gunicorn с 16 workers, 4 threads на worker, 60 секунд timeout. Celery worker настроен на concurrency 8, max-tasks-per-child 500 — перезапуск воркера после 500 задач предотвращает утечки памяти в долгоживущих Python-процессах. Celery beat крутит на DatabaseScheduler — расписание задач хранится в PostgreSQL, а не в коде, и можно менять интервалы через Django Admin без деплоя.

# docker-compose.yml (сокращённо)
gonka_backend:
  build: ./backend
  command: gunicorn config.wsgi:application
    --bind 0.0.0.0:8000
    --workers 16 --threads 4 --worker-class gthread
    --timeout 60 --max-requests 1000
  environment:
    - DISCORD_PROXY_URL=socks5://gonka_xray:10808
    - REWARDS_DB_SOURCE=${REWARDS_DB_SOURCE:-legacy}

gonka_celery_worker:
  command: celery -A config worker -l info
    --concurrency=8 --max-tasks-per-child=500
    --prefetch-multiplier=2

Frontend — это gonka_frontend (Next.js 14 App Router) и gonka_miniapp (Vite с React для Telegram Mini App). Два контейнера, два билда, одна кодовая база. Mini App отдаёт статику через nginx внутри контейнера. Next.js запускается в standalone mode — node server.js вместо next start, бандл весит меньше.

CLAUDE.md как второй мозг

Самое важное решение — файл CLAUDE.md на 290 строк. Это не README для людей. Это контекст для Claude Code, с которым я пишу большую часть кода. Все конвенции, команды Docker, архитектурные решения, gotchas — в одном месте.

Пример: "Django settings module is config.settings (not the project name)". Без этой строчки Claude пытался импортировать gonka.settings и каждый раз получал ImportError. Или: "REWARDS_DB_SOURCE env var switches between legacy (txs_db) and blockchain (API scraping)". Claude Code читает файл перед каждой задачей и делает правильно с первого раза.

Вайбкодинг работает, когда у AI есть контекст. CLAUDE.md — это 290-строчный контекст. Пишу скилл для bulk import — Claude сам понимает, что нужно использовать txs_db routing, что поле epoch на модели NodeReward integer, а не DateField, что Celery app в config. Без CLAUDE.md каждая задача начинается с 10 минут объяснений. С ним — сразу к коду.

Фичи для продакшена

Validator jail map — первая боевая фича. Если нода попадает в jail (штраф за downtime или византийское поведение), она не майнит, владелец теряет награды. Визуализация показывает: какие валидаторы в тюрьме, когда попали, сколько потеряли денег. Для инвестора это критичная информация — нода в jail означает прямые убытки.

Bulk import для исторических данных. Есть CSV с прошлыми эпохами: кто сколько намайнил, какие комиссии, кто делегировал. Загрузка через Celery task: парсинг CSV, создание записей в txs_db, обновление агрегатов. 50,000 строк за 3 минуты. Без этого новый инвестор видел бы только текущие данные, без истории.

Система алертов: Celery task check_node_alerts запускается каждые 30 секунд. Проверяет статусы нод, сравнивает с предыдущим состоянием, пишет в модель NodeAlert (тип INACTIVE, JAILED, SLASHED). 11 настраиваемых категорий уведомлений на модели NetworkSubscriber — каждый инвестор выбирает, о чём его оповещать.

Результат за два дня

14-15 января 2026 года — полная перестройка архитектуры. Монорепо с 9 контейнерами развёрнут и работает. HA-дизайн с двумя PostgreSQL, Redis, Celery worker + beat готов к нагрузке. Validator jail map и bulk import функционируют.

CLAUDE.md стал стандартом для моих проектов. 290 строк документации экономят часы на объяснения Claude Code. База заложена — дальше фичи.

Монорепо — не модно. Зато все три приложения в одном месте, один docker-compose, один источник правды.