Версионность анализов: как не запутаться в истории трендов

Строим сложную архитектуру анализов трендов: как не утонуть в версионности
Несколько недель назад встал вопрос, который выглядел просто на первый взгляд: как сделать так, чтобы анализы трендов можно было обновлять, отслеживать изменения и углублять, не теряя историю? Проект trend-analysis требовал переоценки всей модели данных. Первый прототип работал, но архитектура не масштабировалась — анализы были привязаны к тренду один-к-одному, как монолит. Нужна была система с версионностью, историей и возможностью углубления.
Первым делом я запустил параллельное исследование в три направления: посмотрел на текущую архитектуру хранения данных, проанализировал фронтенд-флоу и продумал новую модель данных. Потом привлёк двух виртуальных экспертов — аналитика для продуктового видения и архитектора для технической реализации. Они работали одновременно, каждый отдельно собирал требования и пожелания.
Результат был интересный. План получился ёмким: четыре фазы, пятнадцать шагов. В Phase 1 я добавлял четыре новые колонки в таблицу analyses: version (auto-increment на тренд), depth (глубина анализа), time_horizon (горизонт прогноза) и parent_job_id (ссылка на предыдущий анализ для построения цепочки углублений). На бэкенде появлялись три критические функции — next_version(), find_analyses_by_trend() и list_analyses_grouped().
Но фронтенд-часть потребовала детализации. Я исследовал текущий UI тренда и понял, что нужна полная переделка. Вместо кнопки «Запустить анализ» должна появиться вертикальная временная шкала со всеми версиями анализа. Каждая версия показывает не только score и confidence, но и тип (INITIAL, RE-ANALYZED, DEEPENED), и дельту относительно предыдущей. На странице отчёта добавлялась навигация между версиями, полоса с метриками и дельтами, кнопки для переанализирования или углубления.
Неожиданно выяснилось, что потребуется ещё и сравнение версий. Причём не просто табличное, а с inline-диффом внутри текста отчёта — word-level подсветка изменений, параграф за параграфом. Я выбрал библиотеку diff (она уже была в node_modules) с diffLines() и diffWords(), обёрнутой в useMemo для производительности. На десяти килобайтах текста расчёт занимает примерно пять миллисекунд — приемлемо.
Важное техническое решение: версия — это иммутабельный счётчик, который инкрементируется для каждого тренда отдельно. Углубление — это не модификация старого анализа, а создание нового с depth+2 и ссылкой на parent_job_id. Так мы сохраняем всю историю и можем показать цепочку углублений. Старые записи в БД получают дефолтные значения автоматически — breaking change минимизирован.
Перед кодированием я создал HTML-прототип с Tailwind CDN, mock-данными и тремя экранами: страница тренда с timeline анализов, страница отчёта с версионной навигацией и страница со списком отчётов, сгруппированными по тренду. Прототип дал визуальную уверенность, что архитектура работает.
Теперь план готов к реализации. Первый шаг — миграция БД и API. Главное в этом проекте не в сложности отдельных компонентов, а в координации между слоями: бэкенд должен вернуть список вместо одного объекта, фронтенд должен правильно отрисовать историю, диффы должны считаться эффективно. Это когда архитектура действительно спасает.
Что сказал Nginx при деплое новой версионности? «Наконец-то вы научились отслеживать историю — я давно это делаю через Etag» 😄
Метаданные
- Session ID:
- grouped_trend-analisis_20260208_1511
- Branch:
- feat/scoring-v2-tavily-citations
- Dev Joke
- Что сказал Nginx при деплое? «Не трогайте меня, я нестабилен»
Часть потока:
Разработка: trend-analisis