Карта входа в этап 4: проектирование трансформаций и витрин по образцу
этапа 3 (карта #69). Тикеты — развилки решений, финал — нарезка #6.
Destination
Маршрут этапа 4 ясен: спроектированы модель заказа в DDS, сессии,
контракт dds.event_v, сборка identity_map, запуск трансформаций до etl_pipeline и форма витрин DM; резолюции перенесены в доки docs/architecture/; финал — этап 4 нарезан на самодостаточные тикеты
исполнения, чек-лист — в #6.
Notes
Рамки — мастер-спека docs/specs/2026-07-30-stand-v2-realism.md,
разделы 4 (сверка), 5 (идентичности), 7 (карта таблиц и витрины);
решение по страховочным срезам — раздел 9.
Развилки вести скиллом brainstorm-with-docs (правило AGENTS.md);
research-тикеты — скиллом research; спорные DDL ClickHouse — сверять
через MCP Context7 перед решением.
Одна сессия — один тикет; резолюция — комментарием в тикете, гист — в
Decisions so far.
Наследство: #85 (_load_id выше ODS) закрыт wontfix — вопрос решается
внутри развилки модели заказа, при названном читателе. Хвост
комментария к #6 про dds.v_event закрыт правками спеки
(переименование + довод «слой — контракт»); остаток сомнения — про
проброс условий сквозь представление — стал research-тикетом карты.
#136 — нарезать тикеты этапа 4 по резолюциям карты
Decisions so far
Проталкивание условий сквозь dds.event_v: условия проталкиваются сквозь обычное представление и второй уровень вложенности, FINAL представление не материализует — цепочка представлений ODS → DDS → DM годится; плата FINAL — отключённый авто-PREWHERE, срезные колонки (EventDate) отдавать в DDS переименованием, не пересчётом. Заметка: docs/research/2026-08-22-view-predicate-pushdown.md (в main, PR #139).
GLOBAL JOIN двух Distributed-таблиц на стенде: GLOBAL JOIN корректен — правая часть собирается на инициаторе и рассылается шардам; с левой частью-подзапросом соединение целиком выполняется на инициаторе; FULL OUTER с голой левой Distributed двоит непарные строки правой части — обе стороны сверки держать подзапросами (в спеке §7 так и есть); режим distributed_product_mode = local без настоящей ко-локации молча занижает ответ. Попутно найден дефект ко-локации заказов — #137. Заметка: docs/research/2026-08-22-distributed-join.md (в main, PR #140).
Модель заказа в DDS: физическая dds.order — зерно «заказ в текущем состоянии», позиции массивами в строке, времена в поясе счётчика, MergeTree с заменой партиции по дню заказа, шардирование cityHash64(order_id); служебные колонки — координаты собственной загрузки слоя, ярлыки ODS выше не едут (закрыто наследство #85). Заодно решён дом резолюций этапа 4: набор docs/architecture/dds/ по ADR 0011, README — карта модели; генераторную границу доки слоя не пересекают. Дока: docs/architecture/dds/order.md (PR #141).
Сессии dds.session: зерно и правила сборки: стенд сессионизирует сам по правилу визита, VisitID — эталон счётной DQ-сверки (кука × день); зерно — визит, session_id — детерминированный хеш от (кука, начало); состав — по образцу визита Метрики, без денег и целей; MergeTree, партиция — день сессии (EventDate), сборка дневным батчем после слепка, день замерзает сразу; шардирование cityHash64(ClientID). Дока: docs/architecture/dds/session.md (PR #142).
Контракт dds.event_v: атрибуты бизнес-модели: представление над ods.event_v — имена модели (event_id, event_time в поясе счётчика, event_date переименованием, client_id остаётся), расшифровка только device_category; скрыты VisitID (DQ-сверка идёт за эталоном в ODS), Sign, ecommerce, служебные _load_id/_load_ts; идея лабы про справочник регионов — #143. Дока: docs/architecture/dds/event.md (PR #144).
Сборка identity_map: трансформация и повторы: физическая карта identity_map_rep / _dist, точное публичное identity_map_v; полный пакетный пересчёт после заказов через GLOBAL JOIN, любой статус устанавливает связь, first_matched_at вынесен в учебную идею #145. Публичный договор *_v закреплён для всех сущностей DDS вместе с границей прав: потребители читают представления, физические объекты — роли загрузки и диагностики. Дока: docs/architecture/dds/identity.md.
Запуск трансформаций до etl_pipeline: даг etl_pipeline рождается этапом 4 — дёргает dds_transform → dm_transform с ожиданием, DQ — будущее звено; живой день зовёт его после установки позиции, после разгона пачкой менти запускает рукой, world_initialize — последним шагом; параметров нет — объём выводится из world_position и состояния слоёв; первый шаг — ожидание хвоста hits; механика REPLACE PARTITION — этап 4, этапу 5 — партиционная переобработка. Дока: docs/architecture/etl.md (PR #146).
Витрины DM: форма и состав: форма по зерну — агрегаты материализуются (_rep/_dist + _v), пересборка дагом dm_transform — три ритма по подвижности источника: хвост / окно K / целиком (daily_traffic — ReplacingMergeTree вслед за картой), зерно источника остаётся представлением; стенд строит revenue_daily, purchase_vs_orders, daily_traffic, dq_summary, остальные витрины — учебные задания менти по ТЗ; dq_summary — зерно «день × проверка», REPLACE PARTITION; звено DQ конвейера проверяет объекты стенда (сессии против VisitID, классы против описи, витрины против DDS), домашки проверяет отдельный ручной даг самопроверки по образцу greenplum-стенда. Дока: docs/architecture/dm.md (PR #147).
Not yet specified
Критерии приёмки этапа 4 — соберутся в нарезке из резолюций развилок.
Механика сверки A+C в SQL (приоритет классов, awaiting_order) —
рамка в спеке §4/§7; модели развилки не вскрыли, уходит прямо в нарезку
(резолюция #135).
Стык с дашбордом Grafana «Данные» (параллельный трек мониторинга):
какие приёмочные вопросы этапа 4 закрывает дашборд.
Out of scope
Расхождения B и D, опоздания, счётчики описи — этап 6 (#8).
Партиционная переобработка — этап 5 (#7): даг etl_pipeline рождается
этапом 4 (резолюция #134), этапу 5 остаётся умение переигрывать прошлое;
туда же стык #111 про дату модельного мира и logical_date.
Инкрементальный ETL вместо полной перезагрузки — техдолг #2.
Нарезать тикеты этапа 4 по резолюциям карты: десять тикетов исполнения #150–#159 чек-листом в #6, цепочка нативных блокировок; даги рождаются тикетами первой задачи, граница доступа сужена до _v первыми тикетами слоёв, счётчики описи A+C — генераторным тикетом; наблюдаемые критерии приёмки этапа — в #6. Нарезка прошла холодное ревью (28 находок).
Part of #6.
Карта входа в этап 4: проектирование трансформаций и витрин по образцу
этапа 3 (карта #69). Тикеты — развилки решений, финал — нарезка #6.
## Destination
Маршрут этапа 4 ясен: спроектированы модель заказа в DDS, сессии,
контракт `dds.event_v`, сборка `identity_map`, запуск трансформаций до
`etl_pipeline` и форма витрин DM; резолюции перенесены в доки
`docs/architecture/`; финал — этап 4 нарезан на самодостаточные тикеты
исполнения, чек-лист — в #6.
## Notes
- Рамки — мастер-спека `docs/specs/2026-07-30-stand-v2-realism.md`,
разделы 4 (сверка), 5 (идентичности), 7 (карта таблиц и витрины);
решение по страховочным срезам — раздел 9.
- Развилки вести скиллом `brainstorm-with-docs` (правило AGENTS.md);
research-тикеты — скиллом `research`; спорные DDL ClickHouse — сверять
через MCP Context7 перед решением.
- Одна сессия — один тикет; резолюция — комментарием в тикете, гист — в
Decisions so far.
- Наследство: #85 (`_load_id` выше ODS) закрыт wontfix — вопрос решается
внутри развилки модели заказа, при названном читателе. Хвост
комментария к #6 про `dds.v_event` закрыт правками спеки
(переименование + довод «слой — контракт»); остаток сомнения — про
проброс условий сквозь представление — стал research-тикетом карты.
## Маршрут
Порядок — цепочка блокировок (нативные зависимости Gitea): research
#128 и #129 идут параллельно и сразу; #130 и #131 открыты с порога;
#132 ждёт #128, #133 ждёт #129, #134 ждёт #130 и #131, #135 ждёт
#130, #132 и #134; финальная нарезка #136 ждёт #133, #134 и #135.
- [x] #128 — проталкивание условий сквозь dds.event_v (research)
- [x] #129 — GLOBAL JOIN двух Distributed-таблиц на стенде (research)
- [x] #130 — модель заказа в DDS: зерно, связи, материализация
- [x] #131 — сессии dds.session: зерно и правила сборки
- [x] #132 — контракт dds.event_v: атрибуты бизнес-модели
- [x] #133 — сборка identity_map: трансформация и повторы
- [x] #134 — запуск трансформаций до etl_pipeline
- [x] #135 — витрины DM: форма и состав
- [x] #136 — нарезать тикеты этапа 4 по резолюциям карты
## Decisions so far
- [Проталкивание условий сквозь dds.event_v](https://git.dementev.space/ddmitry/clickstream-data-platform/issues/128): условия проталкиваются сквозь обычное представление и второй уровень вложенности, FINAL представление не материализует — цепочка представлений ODS → DDS → DM годится; плата FINAL — отключённый авто-PREWHERE, срезные колонки (EventDate) отдавать в DDS переименованием, не пересчётом. Заметка: docs/research/2026-08-22-view-predicate-pushdown.md (в main, PR #139).
- [GLOBAL JOIN двух Distributed-таблиц на стенде](https://git.dementev.space/ddmitry/clickstream-data-platform/issues/129): GLOBAL JOIN корректен — правая часть собирается на инициаторе и рассылается шардам; с левой частью-подзапросом соединение целиком выполняется на инициаторе; FULL OUTER с голой левой Distributed двоит непарные строки правой части — обе стороны сверки держать подзапросами (в спеке §7 так и есть); режим distributed_product_mode = local без настоящей ко-локации молча занижает ответ. Попутно найден дефект ко-локации заказов — #137. Заметка: docs/research/2026-08-22-distributed-join.md (в main, PR #140).
- [Модель заказа в DDS](https://git.dementev.space/ddmitry/clickstream-data-platform/issues/130): физическая `dds.order` — зерно «заказ в текущем состоянии», позиции массивами в строке, времена в поясе счётчика, `MergeTree` с заменой партиции по дню заказа, шардирование `cityHash64(order_id)`; служебные колонки — координаты собственной загрузки слоя, ярлыки ODS выше не едут (закрыто наследство #85). Заодно решён дом резолюций этапа 4: набор `docs/architecture/dds/` по ADR 0011, README — карта модели; генераторную границу доки слоя не пересекают. Дока: docs/architecture/dds/order.md (PR #141).
- [Сессии dds.session: зерно и правила сборки](https://git.dementev.space/ddmitry/clickstream-data-platform/issues/131): стенд сессионизирует сам по правилу визита, VisitID — эталон счётной DQ-сверки (кука × день); зерно — визит, session_id — детерминированный хеш от (кука, начало); состав — по образцу визита Метрики, без денег и целей; MergeTree, партиция — день сессии (EventDate), сборка дневным батчем после слепка, день замерзает сразу; шардирование cityHash64(ClientID). Дока: docs/architecture/dds/session.md (PR #142).
- [Контракт dds.event_v: атрибуты бизнес-модели](https://git.dementev.space/ddmitry/clickstream-data-platform/issues/132): представление над `ods.event_v` — имена модели (`event_id`, `event_time` в поясе счётчика, `event_date` переименованием, `client_id` остаётся), расшифровка только `device_category`; скрыты `VisitID` (DQ-сверка идёт за эталоном в ODS), `Sign`, `ecommerce`, служебные `_load_id`/`_load_ts`; идея лабы про справочник регионов — #143. Дока: docs/architecture/dds/event.md (PR #144).
- [Сборка identity_map: трансформация и повторы](https://git.dementev.space/ddmitry/clickstream-data-platform/issues/133): физическая карта `identity_map_rep` / `_dist`, точное публичное `identity_map_v`; полный пакетный пересчёт после заказов через GLOBAL JOIN, любой статус устанавливает связь, `first_matched_at` вынесен в учебную идею #145. Публичный договор `*_v` закреплён для всех сущностей DDS вместе с границей прав: потребители читают представления, физические объекты — роли загрузки и диагностики. Дока: docs/architecture/dds/identity.md.
- [Запуск трансформаций до etl_pipeline](https://git.dementev.space/ddmitry/clickstream-data-platform/issues/134): даг `etl_pipeline` рождается этапом 4 — дёргает `dds_transform` → `dm_transform` с ожиданием, DQ — будущее звено; живой день зовёт его после установки позиции, после разгона пачкой менти запускает рукой, `world_initialize` — последним шагом; параметров нет — объём выводится из `world_position` и состояния слоёв; первый шаг — ожидание хвоста `hits`; механика REPLACE PARTITION — этап 4, этапу 5 — партиционная переобработка. Дока: docs/architecture/etl.md (PR #146).
- [Витрины DM: форма и состав](https://git.dementev.space/ddmitry/clickstream-data-platform/issues/135): форма по зерну — агрегаты материализуются (`_rep`/`_dist` + `_v`), пересборка дагом `dm_transform` — три ритма по подвижности источника: хвост / окно K / целиком (`daily_traffic` — ReplacingMergeTree вслед за картой), зерно источника остаётся представлением; стенд строит `revenue_daily`, `purchase_vs_orders`, `daily_traffic`, `dq_summary`, остальные витрины — учебные задания менти по ТЗ; `dq_summary` — зерно «день × проверка», REPLACE PARTITION; звено DQ конвейера проверяет объекты стенда (сессии против VisitID, классы против описи, витрины против DDS), домашки проверяет отдельный ручной даг самопроверки по образцу greenplum-стенда. Дока: docs/architecture/dm.md (PR #147).
## Not yet specified
- Критерии приёмки этапа 4 — соберутся в нарезке из резолюций развилок.
- Механика сверки A+C в SQL (приоритет классов, `awaiting_order`) —
рамка в спеке §4/§7; модели развилки не вскрыли, уходит прямо в нарезку
(резолюция #135).
- Стык с дашбордом Grafana «Данные» (параллельный трек мониторинга):
какие приёмочные вопросы этапа 4 закрывает дашборд.
## Out of scope
- Расхождения B и D, опоздания, счётчики описи — этап 6 (#8).
- Партиционная переобработка — этап 5 (#7): даг `etl_pipeline` рождается
этапом 4 (резолюция #134), этапу 5 остаётся умение переигрывать прошлое;
туда же стык #111 про дату модельного мира и logical_date.
- Инкрементальный ETL вместо полной перезагрузки — техдолг #2.
- Superset-дашборд — этап 8 (#10).
- [Нарезать тикеты этапа 4 по резолюциям карты](https://git.dementev.space/ddmitry/clickstream-data-platform/issues/136): десять тикетов исполнения #150–#159 чек-листом в #6, цепочка нативных блокировок; даги рождаются тикетами первой задачи, граница доступа сужена до `_v` первыми тикетами слоёв, счётчики описи A+C — генераторным тикетом; наблюдаемые критерии приёмки этапа — в #6. Нарезка прошла холодное ревью (28 находок).
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Part of #6.
Карта входа в этап 4: проектирование трансформаций и витрин по образцу
этапа 3 (карта #69). Тикеты — развилки решений, финал — нарезка #6.
Destination
Маршрут этапа 4 ясен: спроектированы модель заказа в DDS, сессии,
контракт
dds.event_v, сборкаidentity_map, запуск трансформаций доetl_pipelineи форма витрин DM; резолюции перенесены в докиdocs/architecture/; финал — этап 4 нарезан на самодостаточные тикетыисполнения, чек-лист — в #6.
Notes
docs/specs/2026-07-30-stand-v2-realism.md,разделы 4 (сверка), 5 (идентичности), 7 (карта таблиц и витрины);
решение по страховочным срезам — раздел 9.
brainstorm-with-docs(правило AGENTS.md);research-тикеты — скиллом
research; спорные DDL ClickHouse — сверятьчерез MCP Context7 перед решением.
Decisions so far.
_load_idвыше ODS) закрыт wontfix — вопрос решаетсявнутри развилки модели заказа, при названном читателе. Хвост
комментария к #6 про
dds.v_eventзакрыт правками спеки(переименование + довод «слой — контракт»); остаток сомнения — про
проброс условий сквозь представление — стал research-тикетом карты.
Маршрут
Порядок — цепочка блокировок (нативные зависимости Gitea): research
#128 и #129 идут параллельно и сразу; #130 и #131 открыты с порога;
#132 ждёт #128, #133 ждёт #129, #134 ждёт #130 и #131, #135 ждёт
#130, #132 и #134; финальная нарезка #136 ждёт #133, #134 и #135.
Decisions so far
Проталкивание условий сквозь dds.event_v: условия проталкиваются сквозь обычное представление и второй уровень вложенности, FINAL представление не материализует — цепочка представлений ODS → DDS → DM годится; плата FINAL — отключённый авто-PREWHERE, срезные колонки (EventDate) отдавать в DDS переименованием, не пересчётом. Заметка: docs/research/2026-08-22-view-predicate-pushdown.md (в main, PR #139).
GLOBAL JOIN двух Distributed-таблиц на стенде: GLOBAL JOIN корректен — правая часть собирается на инициаторе и рассылается шардам; с левой частью-подзапросом соединение целиком выполняется на инициаторе; FULL OUTER с голой левой Distributed двоит непарные строки правой части — обе стороны сверки держать подзапросами (в спеке §7 так и есть); режим distributed_product_mode = local без настоящей ко-локации молча занижает ответ. Попутно найден дефект ко-локации заказов — #137. Заметка: docs/research/2026-08-22-distributed-join.md (в main, PR #140).
Модель заказа в DDS: физическая
dds.order— зерно «заказ в текущем состоянии», позиции массивами в строке, времена в поясе счётчика,MergeTreeс заменой партиции по дню заказа, шардированиеcityHash64(order_id); служебные колонки — координаты собственной загрузки слоя, ярлыки ODS выше не едут (закрыто наследство #85). Заодно решён дом резолюций этапа 4: наборdocs/architecture/dds/по ADR 0011, README — карта модели; генераторную границу доки слоя не пересекают. Дока: docs/architecture/dds/order.md (PR #141).Сессии dds.session: зерно и правила сборки: стенд сессионизирует сам по правилу визита, VisitID — эталон счётной DQ-сверки (кука × день); зерно — визит, session_id — детерминированный хеш от (кука, начало); состав — по образцу визита Метрики, без денег и целей; MergeTree, партиция — день сессии (EventDate), сборка дневным батчем после слепка, день замерзает сразу; шардирование cityHash64(ClientID). Дока: docs/architecture/dds/session.md (PR #142).
Контракт dds.event_v: атрибуты бизнес-модели: представление над
ods.event_v— имена модели (event_id,event_timeв поясе счётчика,event_dateпереименованием,client_idостаётся), расшифровка толькоdevice_category; скрытыVisitID(DQ-сверка идёт за эталоном в ODS),Sign,ecommerce, служебные_load_id/_load_ts; идея лабы про справочник регионов — #143. Дока: docs/architecture/dds/event.md (PR #144).Сборка identity_map: трансформация и повторы: физическая карта
identity_map_rep/_dist, точное публичноеidentity_map_v; полный пакетный пересчёт после заказов через GLOBAL JOIN, любой статус устанавливает связь,first_matched_atвынесен в учебную идею #145. Публичный договор*_vзакреплён для всех сущностей DDS вместе с границей прав: потребители читают представления, физические объекты — роли загрузки и диагностики. Дока: docs/architecture/dds/identity.md.Запуск трансформаций до etl_pipeline: даг
etl_pipelineрождается этапом 4 — дёргаетdds_transform→dm_transformс ожиданием, DQ — будущее звено; живой день зовёт его после установки позиции, после разгона пачкой менти запускает рукой,world_initialize— последним шагом; параметров нет — объём выводится изworld_positionи состояния слоёв; первый шаг — ожидание хвостаhits; механика REPLACE PARTITION — этап 4, этапу 5 — партиционная переобработка. Дока: docs/architecture/etl.md (PR #146).Витрины DM: форма и состав: форма по зерну — агрегаты материализуются (
_rep/_dist+_v), пересборка дагомdm_transform— три ритма по подвижности источника: хвост / окно K / целиком (daily_traffic— ReplacingMergeTree вслед за картой), зерно источника остаётся представлением; стенд строитrevenue_daily,purchase_vs_orders,daily_traffic,dq_summary, остальные витрины — учебные задания менти по ТЗ;dq_summary— зерно «день × проверка», REPLACE PARTITION; звено DQ конвейера проверяет объекты стенда (сессии против VisitID, классы против описи, витрины против DDS), домашки проверяет отдельный ручной даг самопроверки по образцу greenplum-стенда. Дока: docs/architecture/dm.md (PR #147).Not yet specified
awaiting_order) —рамка в спеке §4/§7; модели развилки не вскрыли, уходит прямо в нарезку
(резолюция #135).
какие приёмочные вопросы этапа 4 закрывает дашборд.
Out of scope
etl_pipelineрождаетсяэтапом 4 (резолюция #134), этапу 5 остаётся умение переигрывать прошлое;
туда же стык #111 про дату модельного мира и logical_date.
_vпервыми тикетами слоёв, счётчики описи A+C — генераторным тикетом; наблюдаемые критерии приёмки этапа — в #6. Нарезка прошла холодное ревью (28 находок).Маршрут пройден: все девять тикетов карты закрыты, финальная нарезка — резолюцией #136, чек-лист исполнения этапа 4 — в #6. Карта закрывается.