Пример условный. В компании есть панель остатков, которая обновляется каждый час. Задание обновления каждый раз завершается успешно. Но один из складов перестал присылать выгрузку: сломалась интеграция или кто-то сменил пароль. Панель выглядит живой, время последнего обновления свежее, а товары этого склада показаны со вчерашними остатками или вовсе как нулевые. Менеджер по закупкам смотрит на панель и заказывает то, что на самом деле есть, или не заказывает то, чего уже нет.
Сбоя в привычном смысле не было: ни одно задание не упало, ни одно уведомление не пришло. Ошибся не расчёт, а входные данные, и никто об этом не узнал.
Зелёный статус отвечает не на тот вопрос
Статус задания отвечает на вопрос «отработало ли задание». Человеку, который принимает решение, нужен ответ на другой вопрос: «можно ли пользоваться этим результатом сейчас».
Между ними большой зазор. Задание может успешно пересчитать отчёт по данным, которые перестали обновляться. Может собрать сводку из трёх источников вместо четырёх. Может посчитать всё правильно, а результат пролежит в очереди так долго, что к моменту выдачи устареет. Во всех трёх случаях задание «зелёное».
Поэтому проверки свежести ставят не вместо мониторинга заданий, а рядом: они смотрят на сами данные, а не на процесс, который их обработал.

Допустимый возраст зависит от решения
Начните с вопроса: насколько старыми могут быть данные для этого конкретного решения? Это и есть допустимый возраст данных. Ежедневному отчёту для планирования и оперативной проверке наличия товара не обязательно нужен один и тот же предел. Для первого могут подойти вчерашние данные, для второго и час может оказаться слишком большим сроком.
Предел устанавливает владелец процесса, а не разработчик. Разработчик может подсказать, как часто источник вообще обновляется, но только тот, кто принимает решение, знает, какая задержка для него ещё безопасна.
Старое событие само по себе не ошибка. Для анализа за прошлый год нужны именно старые данные. Допустимый возраст относится к конкретному использованию: одна и та же таблица может быть свежей для квартального отчёта и устаревшей для решения о сегодняшнем заказе.
Три проверки до расчёта
Время: когда случилось и когда получили
У каждой записи есть как минимум два времени: когда произошло событие или сделан снимок данных и когда ваша система эти данные получила. Храните их раздельно.
Недавняя загрузка не делает старое событие недавним. Если вчерашняя выгрузка пришла сегодня утром, в ней по-прежнему вчерашние остатки. Если считать возраст по времени загрузки, панель покажет «данные свежие», хотя они описывают вчерашний день.
Выясните и то, что именно означает отметка времени в каждом источнике. Это может быть время события, время формирования выгрузки или время последнего изменения записи. От этого зависит, как считать возраст.
Поступление: приходят ли обновления
Нужно знать, как часто каждый источник обычно присылает данные, и замечать, когда обновления перестали приходить. Тишина бывает двух видов: событий действительно не было, например магазин закрыт в выходной, или источник замолчал. Без ожидаемого графика поступления эти случаи не различить.
Полнота: все ли источники на месте
Проверьте, что в расчёт попали все обязательные источники и все нужные части бизнеса: все склады, магазины, юрлица или регионы, которые должны быть в отчёте. Частичная загрузка не должна выглядеть как полный отчёт. Если пришли данные по трём складам из четырёх, итог по компании нельзя показывать как итог по компании.
Отсутствующие данные — не ноль
Самая опасная подмена — превратить недоступный источник в ноль. Ноль выглядит как факт: «продаж не было», «остаток закончился». На самом деле это «мы не знаем».
Если обязательные данные устарели, отсутствуют или пришли не полностью, у результата два честных варианта:
- задержать его и сообщить конкретному ответственному, что не так;
- выдать его с явной пометкой об ограничении: какого источника не хватает и что из-за этого в результате неточно.
Какой из вариантов подходит, решает владелец процесса заранее, для каждого отчёта. Важно одно: у такой ситуации должно быть отдельное состояние, а не тихое продолжение работы. Похожая логика с «неизвестным» исходом нужна при передаче данных между системами, мы разбирали её в статье о тайм-аутах при передаче заказа в ERP.
Ещё одна проверка перед выдачей
Если входные данные прошли проверки, результат можно строить. Но на этом проверки не заканчиваются. Расчёт может ждать в очереди, отчёт может уйти по расписанию через несколько часов, ответ может быть показан пользователю намного позже, чем начался расчёт. Результат, который был свежим в начале расчёта, к моменту выдачи может выйти за допустимый возраст.
Поэтому возраст данных проверяют ещё раз прямо перед тем, как результат увидит человек или получит следующая система. Если предел превышен, результат придерживают и пересчитывают, а не отправляют как есть.
«Данные на …» рядом с ответом
Показывайте рядом с результатом время, на которое актуальны данные, и их охват: «Остатки на 09:00, без склада № 3». Это короткая строка, но она меняет то, как человек читает цифры. Он видит не только ответ, но и границы, в которых этому ответу можно доверять.
Когда источник восстановился, недостаточно просто дождаться следующего планового обновления. Найдите результаты, которые были построены без него или с его устаревшими данными, пересчитайте их и снова прогоните проверки, прежде чем ими пользоваться.
Если вы строите хранилище данных на dbt, в нём есть встроенная проверка свежести: для источника или модели задаётся, насколько старыми могут быть самые свежие данные, прежде чем проверка выдаст предупреждение или ошибку. Это хорошая основа, но она проверяет данные в хранилище. Повторную проверку перед выдачей и пометку «данные на …» всё равно нужно сделать там, где результат показывают.
Как проверить до запуска
Главный тест простой: намеренно остановите один источник, а задание отчёта оставьте работающим. Что сделает система: сообщит, что данных не хватает, или продолжит уверенно показывать ответ?
В тестовый набор стоит включить пять случаев:
- свежие данные: результат выдаётся с пометкой «данные на …»;
- источник с задержкой: данные пришли, но старше допустимого возраста;
- остановленный источник: обновлений нет совсем;
- частичная загрузка: пришла только часть складов или магазинов;
- данные, которые устарели, пока результат ждал выдачи.
И отдельно проверьте восстановление: источник вернулся, затронутые результаты пересчитаны, проверки пройдены заново.
Чек-лист
- Для каждого решения, которое опирается на отчёт, владелец процесса установил допустимый возраст данных.
- Время события и время получения данных хранятся раздельно, и известно, что означает отметка времени в каждом источнике.
- Для каждого источника известен ожидаемый график обновлений, и прекращение обновлений замечается.
- Проверяется, что в расчёт попали все обязательные источники и все нужные склады, магазины или юрлица.
- Отсутствующие данные не превращаются в ноль.
- Если проверки не пройдены, результат задерживается или выдаётся с явной пометкой, и об этом узнаёт названный ответственный.
- Возраст данных проверяется ещё раз перед выдачей.
- Рядом с результатом показано, на какое время актуальны данные и какие источники в них вошли.
- После восстановления источника затронутые результаты пересчитываются и проверяются заново.
- В тестовой среде источник намеренно остановлен, и система сообщила о нехватке данных, а не выдала уверенный ответ.
С чего начать
Возьмите один отчёт или одну панель, по которой регулярно принимают решения, и одно такое решение. Запишите источники, как часто каждый обновляется, допустимый возраст данных и того, кто отвечает за результат. Первым делом добавьте рядом с результатом строку «данные на …» с перечнем источников: уже она покажет, где картина неполная. Затем добавьте проверки и проведите тест с остановленным источником.
Если у вас есть отчёт, который собирается автоматически из нескольких систем, посмотрите сценарий «Реклама и продажи → отчёт» на странице автоматизации процессов. Полезный вопрос к такому отчёту не только «собрался ли он», но и «можно ли безопасно пользоваться им прямо сейчас».
