Refactoring Signal-Trend Model в Trend Analysis: от прототипа к production-ready коду

Когда я начинал работать над проектом Trend Analysis, модель предсказания сигналов выглядела как груда экспериментального кода. Функции пересекались, логика размазывалась по разным файлам, а добавить новый индикатор означало переписывать половину pipeline. Пришлось взяться за рефакторинг signal-trend-model — и это оказалось намного интереснее, чем казалось на первый взгляд.
Проблема была очевидна: старая архитектура росла органически, как сорняк. Каждый новый feature добавлялся туда, где было место, без общей схемы. Claude помогал генерировать код быстро, но без лиц контейнера это приводило к техдолгу. Нужна была ясная структура с разделением ответственности.
Я начал с карточки тренда. Вместо плоского dictionary мы создали pydantic-модель, которая описывает сигнал: входные параметры, условия срабатывания, выходные метрики. Это сразу дало валидацию на входе и самодокументирующийся код. Python type hints стали не просто украшением — они помогали IDE подсказывать поля и ловить баги на этапе редактирования.
Потом разбил логику анализа на отдельные классы. Был один монолитный TrendAnalyzer — стал набор специализированных компонентов: SignalDetector, TrendValidator, ConfidenceCalculator. Каждый отвечает за одно, может тестироваться отдельно, легко заменяется. API между ними четкий — pydantic models на границах.
Интеграция с Claude API стала проще. Раньше LLM вызывался хаотично, результаты парсились по-разному в разных местах. Теперь есть выделенный ClaudeEnricher — отправляет структурированный prompt, получает JSON, парсит в известную схему. Если Claude вернул ошибку — мы её перехватываем и логируем, не ломая весь pipeline.
Сделал миграцию на async/await более честной. Раньше были места, где async смешивался с sync вызовами — классический footgun. Теперь все I/O операции (API запросы, работа с БД) через asyncio, можно запускать несколько анализов параллельно без блокировок.
Любопытный факт про AI: модели типа Claude отлично помогают с рефакторингом, если дать им правильный контекст. Я отправлял код старый → желаемую архитектуру → получал предложения, которые я доводил до ума. Не слепое следование, а направленный диалог.
В итоге код стал: - Модульным — 6 месяцев спустя коллеги добавили новый тип сигнала за день; - Тестируемым — unit-тесты покрывают основную логику, integration-тесты проверяют API; - Поддерживаемым — задачи разберутся новичку за час, не день.
Рефакторинг не был волшебством. Это была кропотливая работа: писать тесты сначала, потом менять код, убеждаться что ничего не сломалось. Зато теперь, когда нужно добавить feature или исправить bug, я не боюсь менять код — он защищен.
Почему Angular считает себя лучше всех? Потому что Stack Overflow так сказал 😄
Метаданные
- Session ID:
- grouped_trend-analisis_20260219_1826
- Branch:
- refactor/signal-trend-model
- Dev Joke
- Почему Angular считает себя лучше всех? Потому что Stack Overflow так сказал