Files
clickstream-data-platform/docs/labs/optional/revenue-over-time.md
T
ddadmin 515f386e5f docs(labs): добавлено наблюдение за выручкой до закрытия дня
Зачем: связать опоздания и отмены с изменением уже рассчитанного отчета.
Что: лабораторная с сохранением состояний заказов, ссылки в индексе и программе; убраны повторы в описании раздела.
Проверка: восемь однодневных world_next_day и etl_pipeline на Airflow 3.3.0; изменения сумм сошлись до копейки, закрытый день неизменен, DQ пройдены. Проверены 54 локальные ссылки, SQL-примеры и git diff --check.
2026-09-22 03:58:42 -04:00

10 KiB
Raw Blame History

Почему вчерашняя выручка меняется сегодня

Чему учит: объяснять изменения уже рассчитанного отчета поступлением заказов и сменой их статусов, определять момент закрытия дня и границы доступной истории.

Факультатив доступен после ступени 1. Понадобятся Airflow и DBeaver с подключением analyst по инструкции. Вы будете наблюдать один день оформления заказов, продвигая мир по одному модельному дню. Новые данные останутся в стенде.

Подготовьте первое наблюдение

Поставьте world_live на паузу. Дождитесь завершения начатых прогонов генерации и обработки, затем запустите etl_pipeline и дождитесь успеха. Так исходное наблюдение будет снято после обновления витрин.

Узнайте последний день событий и дату последнего полученного слепка:

SELECT
    (SELECT max(event_date) FROM dds.event_v) AS event_day,
    (SELECT max(snapshot_date) FROM ods.order_v) AS snapshot_day;

День event_day обозначим D. Наблюдайте именно его до конца работы. Дата слепка, по которому сделано очередное наблюдение, будет S. Это модельные даты магазина. Календарная дата запуска Airflow день D не задает.

Слепок снимается к концу суток и доставляется следующим прогоном. Поэтому покупки последнего сыгранного дня уже видны в событиях, а их заказов в хранилище еще нет. Проверьте это для D в dds.order_v и dm.purchase_vs_orders_v.

Подготовьте запросы и сохраняйте результаты

Напишите запросы для следующих наблюдений:

Что сохранить Откуда взять
Дату полученного слепка S max(snapshot_date) из ods.order_v
Номер, статус и items_total каждого заказа дня D dds.order_v, отбор по order_date
Число заказов в каждом статусе и сумму items_total только у paid те же заказы дня D
Выручку дня D сумма revenue из dm.revenue_daily_v, отбор по report_date
Номера покупок, еще ожидающих заказ строки awaiting_order из dm.purchase_vs_orders_v, отбор по order_day

Выручку складывайте по всем категориям. В этой витрине она означает стоимость позиций оплаченных заказов, без скидки и доставки, поэтому должна сходиться с суммой items_total у заказов в статусе paid.

Сохраняйте результаты запросов отдельными файлами, например выгрузками CSV из DBeaver. Подписывайте D и S. До поступления первого слепка список заказов пуст, а выручка равна нулю; сохраните и это наблюдение.

Публичное представление заказа показывает текущее состояние, а сырые слепки хранятся ограниченное время. Сохраненные выгрузки — история для расследования.

Продвигайте мир по одному дню

Для каждого следующего наблюдения:

  1. Запустите world_next_day с days = 1 и дождитесь успеха.
  2. Запустите etl_pipeline и дождитесь успеха: world_next_day сам витрины не обновляет.
  3. Повторите свои запросы и сохраните новый комплект результатов с датой S.

Во всех запросах остается прежний день D. За один запуск проигрывайте один день, чтобы сохранить промежуточные состояния. Пакетный world_next_day отправляет события без пауз; ждать 24 минуты живого дня здесь не нужно.

Продолжайте до слепка D + 7 включительно. У заказов дня D окно состоит из семи дней, от D до D + 6. Слепок D + 6 содержит окончательное состояние, а еще один шаг позволит проверить, что оно сохранилось за пределами окна. От исходного наблюдения потребуется восемь однодневных запусков.

Объясните изменения отчета

После каждого шага сравнивайте заказы по order_id, а не по положению строк в выгрузке. Найдите:

  • заказы, отсутствовавшие в первом слепке D, но появившиеся в следующем;
  • переходы из created в paid;
  • отмены заказов, для которых раньше был виден статус paid.

Первый слепок, полученный на следующий день, — обычная доставка заказов. Опоздавшими здесь считаются те, которых не было уже в этом слепке. Покажите на нескольких номерах, как они исчезают из awaiting_order.

Для двух соседних наблюдений разложите изменение выручки по заказам. Вклад заказа — его items_total, если статус paid, и ноль в остальных случаях, включая отсутствие заказа. Разность вкладов объясняет, сколько каждый заказ добавил к отчету или убрал из него. Сумма этих изменений должна совпасть с изменением revenue до копейки.

Запишите даты, между которыми выручка выросла или уменьшилась. Отдельный отмененный заказ мог убрать деньги, даже если итог дня вырос: покажите это по его вкладу. Одна общая сумма скрывает встречные изменения.

Что известно об отменах

Возьмите отмененный заказ, у которого в вашей истории был статус paid. Укажите два наблюдения, доказывающих, что он был оплачен, а затем отменен.

Для отмененного заказа без наблюдаемой оплаты сформулируйте предел вывода. Дневные слепки могли не застать промежуточное состояние: оплата и отмена могли произойти между ними. Поэтому отсутствие paid в выгрузках не доказывает, что оплаты не было. Не заменяйте недостающие данные догадкой.

Когда день закрыт

Сравните сохраненные состояния при S = D + 6 и S = D + 7: состав заказов, их статусы, суммы и выручку. Объясните, почему отчет за D теперь окончательный. Основание — получен и обработан последний слепок окна изменяемости; одно совпадение сумм в соседних наблюдениях этого не доказывает.

После собственных выводов сверьтесь с описанием слепка и его доставки и границ истории отмен.

Что должно получиться

  • сохранена последовательность наблюдений одного дня D с датами слепков S;
  • найдены опоздавшие заказы и изменения статусов;
  • изменение выручки между двумя наблюдениями объяснено вкладами заказов;
  • оплата одной из последующих отмен подтверждена двумя наблюдениями;
  • вы различаете доказанную оплату и отсутствие сведений о ней;
  • состояние дня за пределами окна совпало с окончательным, а момент закрытия обоснован правилом доставки слепков.

После работы оставьте world_live на паузе либо верните автоматическое продвижение, если пользовались им до наблюдения.