Архитектура, TDD, инциденты и уроки 4 месяцев разработки с Claude Code
В ноябре 2025 я начал эксперимент — построить полноценное финансовое приложение, не написав ни одной строчки кода руками. Спустя 4 месяца: 1 702 коммита, 3 880 тестов, 94.83% покрытие, два серьёзных production-инцидента и работающий продукт.
Моя роль — архитектор и продакт. Я задаю направление, принимаю решения, ревьюю результат. AI реализует. Код руками не пишу.
Проект — EasyStocksAI: скоринг 1 000+ акций по 15 метрикам (4 столпа по 25 баллов = 100), портфели с историей и benchmark-стратегиями, интерактивные графики, блог с кастомным Markdown-парсером. Стек: Elixir/Phoenix LiveView, PostgreSQL, Oban, Tailwind, Lightweight Charts.
Эта статья не про то, что "AI умеет писать код" — это все уже знают. Она про то, как организовать процесс, чтобы AI выдавал production-quality результат. Без guardrails AI генерирует работающий, но неуправляемый код. С правильной организацией — строит системы.
Почему это не "очередной pet project на ChatGPT"
Давайте сразу разберёмся с масштабом. Это не TODO-лист и не лендинг.

Проект в цифрах
Метрика | Значение |
|---|---|
Elixir-код | 422 000 строк |
JavaScript | 6 350 строк |
Тестовый код | 73 000 строк |
Модули | 300+ (214 бизнес-логика + 86 веб-слой) |
Тесты | 3 880+ |
Покрытие | 94.83% |
Oban-воркеры | 34 (11 по расписанию, 23 по требованию) |
Миграции БД | 80 |
Контексты (DDD) | 13 |
Зависимости | 33 |
Что умеет приложение
4-столповая система скоринга — чистые функции без побочных эффектов:
Shareholder Returns (доходность для акционеров)
Growth Quality (качество роста)
Valuation Quality (качество оценки)
Track Record & Resilience (история и устойчивость)
Данные из 5 API-источников с каскадным fallback: Finnhub → Polygon → Alpha Vantage → FMP → Yahoo Finance. Если один источник недоступен — автоматический переход к следующему.
Портфели с историей транзакций, benchmark-стратегии (S&P 500, All Weather, Classic с учётом возраста инвестора), публичное шаринг-ссылки по токену.
Графики на Lightweight Charts с lazy-loading и LRU-кешем. Блог с кастомным Markdown-парсером: [[AAPL]] превращается в ссылку на акцию, {{chart:AAPL|1Y}} — в интерактивный график.

MCP Debug Server — AI может дебажить production прямо через Claude Code (об этом ниже).
Production-инфраструктура
Vultr VPS (2 vCPU, 2GB RAM) + AWS RDS PostgreSQL
CI/CD через GitHub Actions
Разница между "AI написал код" и "AI построил систему" — в архитектуре процесса, а не в возможностях модели.
CLAUDE.md — конституция проекта
AI без ограничений пишет "как попало". Over-engineering, забытые тесты, сломанный существующий код, каждая новая сессия с чистого листа. Знакомо?
Решение — CLAUDE.md. Единый файл, который Claude Code читает при каждом запуске. Это не README и не документация — это набор жёстких правил, которые AI обязан соблюдать.
Что внутри
Обязательные команды — mix format && mix credo --strict после каждого изменения. Без исключений. Не "желательно" — обязательно.
Strict TDD — железный закон: НИ ОДНОЙ строчки продакшн-кода без падающего теста. Red → Green → Refactor. Если AI написал код до теста — стоп.
Список запретов (13 пунктов):
Никаких
Process.sleepв тестах (используйassert_receive)Никаких
floatдля финансовых данных (толькоDecimal)Никаких
@dialyzerдля подавления предупреждений (почини типы)Никогда
docker-compose down -v(уничтожает данные)Никаких DB-запросов внутри циклов в Oban-воркерах
Архитектурные принципы:
Database as Source of Truth — не GenServers
Functional Core / Imperative Shell — чистая бизнес-логика отделена от побочных эффектов
Let It Crash — паттерн-матчинг вместо defensive nil-checking
Query-правила для Oban-воркеров — 6 обязательных правил:
Никаких Repo-вызовов внутри
Enum.map/each/reduceОбщие данные загружаются один раз (prefetch once)
Один и тот же запрос не выполняется дважды за job
Только batch-записи (
Repo.insert_all/Repo.update_all)Query budget документируется в
@moduledocкаждого воркераЧеклист перед мержем нового воркера
Живой документ
CLAUDE.md растёт вместе с проектом. Каждый инцидент, каждая ошибка AI превращается в новое правило.
ConnectionWatchdog убил пул соединений? Добавлено правило про агрессивные таймауты. AI использовал DISTINCT ON? Добавлен запрет с объяснением, почему LATERAL JOIN в 34 раза быстрее. AI показал неполные данные портфеля? Добавлено железное правило: "если хотя бы одна акция без цены — пропустить весь день".
CLAUDE.md — это как coding standards документ для команды. Только команда — это AI, и он действительно следует правилам каждый раз.
Director/Implementor — AI как команда из двух человек
Проблема
Один AI в одной сессии — и архитектор, и кодер, и ревьюер. Результат: решения принимаются на лету, архитектура дрейфует, через 20 сессий проект — лоскутное одеяло.
Решение: два режима работы
Через систему кастомных skills для Claude Code AI работает в двух чётко разделённых режимах:
Director (Архитектор) — проектирует, не пишет код:
Создаёт ADR (Architectural Decision Records) — 6 штук в проекте
Определяет контексты и границы модулей
Пишет планы реализации с точными файлами и тестами
Принимает технологические решения (Pure Ecto vs Ash Framework, JSONB vs отдельные таблицы)
Implementor (Исполнитель) — пишет код строго по плану:
Только TDD: сначала тест, потом код
Не может менять схему БД или границы контекстов без "одобрения Director"
Обязан пройти чеклист: format, credo, 90%+ покрытие
Цепочка на практике — 3 фазы
Brainstorming — я описываю задачу, AI задаёт уточняющие вопросы один за другим, предлагает 2-3 подхода с trade-offs, формирует дизайн-документ
Write Plan — дизайн превращается в пошаговый план: точные файлы, точные тесты, задачи по 2-5 минут каждая
Execute Plan — Implementor выполняет план по шагам с чекпоинтами, строго TDD, без отклонений от плана
Каждая фаза — отдельный skill. Ссылки на skills будут в конце статьи.
Результат
Архитектурные решения документированы и консистентны. Новая сессия AI читает ADR и планы — контекст не теряется. 13 контекстов с чёткими границами — не случайность, а результат Director-фазы.
94.83% покрытие — TDD без компромиссов
Железный закон
В CLAUDE.md записано: "НИ ОДНОЙ строчки продакшн-кода без падающего теста." Не рекомендация — требование. AI, который пишет код до тестов, получает стоп-сигнал.
Цифры
Метрика | Значение |
|---|---|
Тесты | 3 880+ |
Файлов тестов | 319 |
Строк тестового кода | 73 000 |
Покрытие | 94.83% |
JS-тесты (Vitest) | 22 |
73 000 строк тестового кода — больше, чем у многих проектов всего кода.
Что тестируется
Только публичные API контекстов — не внутренние функции
Один behaviour per test — никаких "и ещё проверим вот это"
ExVCR для HTTP-мокинга с уникальной кассетой на каждый тест
ETS-кеш тесты с
async: false— потому что глобальная таблица не изолируется как Ecto Sandbox
Красные флаги
AI обязан остановиться, если:
Тест прошёл сразу → что-то не так с тестом
"Это слишком просто для теста" → нет, не слишком
"Добавлю тест потом" → нет, сейчас
Почему это работает
AI не устаёт, не ленится, не говорит "давай потом напишем тесты". Если правила в CLAUDE.md жёсткие — он их выполняет. Strict TDD с AI оказался проще, чем с людьми, потому что AI не спорит с процессом.
Production-инциденты — AI тоже ломает прод
Было бы нечестно писать только про успехи. AI ломал прод. Дважды. И это самые ценные уроки.
Инцидент 1: Pool Exhaustion (февраль 2026)
Что случилось: Oban-воркеры и веб-запросы делили один пул из 15 соединений к PostgreSQL. Запустили бэкфилл на 923 задачи — веб-интерфейс лёг.
Корневая причина: AI не учёл, что db.t3.micro на AWS RDS имеет ~80 max_connections, и один пул на всё — это бомба замедленного действия.
Решение: ObanRepo — выделенный пул из 5 соединений для внутренних операций Oban (fetch, ack, prune), изолированный от основного Repo (15 соединений). Паттерн из официальной документации Oban.
Урок → новое правило в CLAUDE.md: документирован query budget для каждого воркера, ограничена конкурентность очередей.
Инцидент 2: ConnectionWatchdog Cascade Failure (февраль 2026)
Ирония: мониторинг, написанный AI для предотвращения первого инцидента, сам стал причиной второго.
Что случилось: ConnectionWatchdog проверял здоровье пула через ObanRepo с таймаутом 2 секунды. Под нагрузкой запрос не успевал — DBConnection убивал соединение. С 5 соединениями в ObanRepo watchdog убил весь пул за ~25 секунд.
Oban-продюсеры упали. SSL-реконнект занимал 15 секунд каждый. Спираль смерти.
Решение: Удалить ConnectionWatchdog полностью. Мониторинг стал угрозой.
"Никогда не используй pooled connections с агрессивными таймаутами для мониторинга — монитор становится угрозой"
Система памяти
После каждого инцидента AI записывает урок в memory-файл. Новая сессия читает эти уроки — ошибка не повторяется. CLAUDE.md обрастает новыми правилами как кора дерева — каждое правило имеет свою историю.
Два постмортема хранятся в docs/ — с timeline, root cause analysis и action items. Точно как у человеческих команд.
MCP Debug Server — AI дебажит свой код в проде
В приложение встроен MCP-сервер (Model Context Protocol) на /mcp/* — SSE-транспорт, bearer token аутентификация. Claude Code подключается к production как к инструменту.
Инструменты
Инструмент | Что делает |
|---|---|
| SQL-запросы к production базе |
| Чтение логов приложения |
| Состояние очередей, задач, воркеров |
| CPU, память, BEAM-метрики |
| Инспекция процессов Erlang VM |
| Статистика запросов (pg_stat_statements) |
| Аномалии в скоринге |
Плюс Worker Catalog — триггер, отмена, ретрай задач с валидацией аргументов.
Как это работает
Я говорю Claude Code "проверь почему скоры не обновились" — он сам подключается к проду, смотрит Oban-очереди, проверяет логи, находит застрявший воркер, перезапускает его. Без SSH, без Grafana, без ручного дебага.
Безопасность: WorkerCatalog — белый список воркеров, которые можно триггерить через MCP. Не всё доступно — это security boundary.
1 700 коммитов за 4 месяца — скорость и что за ней стоит
Сырые цифры
1 702 коммита с ноября 2025 по март 2026
~14 коммитов в день в среднем
80 миграций БД — схема активно эволюционировала
410 файлов удалено — рефакторинг без сентиментальности
Откуда скорость
AI не тратит время на "вспомнить синтаксис", "загуглить API", "посмотреть как делали в прошлый раз". Boilerplate генерируется мгновенно — миграции, контексты, тесты, LiveView-компоненты. Рефакторинг без страха — 3 880 тестов ловят регрессии. Нет переключения контекста — AI держит в голове всю кодовую базу через CLAUDE.md и memory.
Где AI медленнее или слабее (честно)
Дизайн UI-компонентов — самая заметная слабость. AI генерирует функциональные, но визуально "generic" интерфейсы. Тонкости UX, визуальная иерархия, "чтобы выглядело как продукт, а не как bootstrap-шаблон" — это требует многих итераций и ручного направления.
Архитектурные решения — я трачу время на обдумывание, brainstorming-сессии, иногда возвращаюсь и переделываю.
Отладка нетривиальных багов — AI может пойти по ложному следу, нужно направлять.
Первый раз с новым паттерном — AI иногда предлагает over-engineering, нужно стопить и упрощать.
Главный инсайт
Скорость — побочный эффект. Главное — консистентность. Каждый коммит проходит через format, credo, тесты. Нет "быстрых грязных фиксов в пятницу вечером".
Выводы
5 главных уроков
AI без рамок — хаос. CLAUDE.md, guardrails, NEVER_DO — без этого AI генерирует работающий, но неуправляемый код. Инвестиция в правила окупается с первого дня.
TDD + AI = идеальная пара. AI не спорит с процессом, не ленится писать тесты, не говорит "потом". Strict TDD с AI проще, чем с людьми.
Разделяй роли. Brainstorming → Plan → Execute. Когда AI одновременно проектирует и кодит — качество падает. Разделение на Director/Implementor через skills решает эту проблему.
Система памяти важнее модели. Claude 3.5, 4, Opus — модель будет меняться. CLAUDE.md, memory, ADR — останутся. Знания проекта живут в файлах, не в контексте чата.
AI ломает прод — и это нормально. Важно не "не ломать", а быстро чинить и превращать каждый инцидент в правило. Постмортем → правило в CLAUDE.md → ошибка не повторяется.
Для кого это подходит
Вы понимаете архитектуру и можете ревьюить решения AI
Вы готовы инвестировать в процесс (CLAUDE.md, skills, guardrails) до написания первой строчки
Вам нужна скорость без потери качества
Для кого НЕ подходит
"Напиши мне приложение" без понимания что должно получиться
Проекты, где дизайн и UX важнее backend-логики (пока)
Завершение
easystocksai.tech работает в проде. 1 000+ акций, реальные пользователи, реальные инциденты