Прототип-трекер — это одна штука. Запустить продукт с мультитенантностью, четырьмя ролями (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, один источник правды.