Commit Graph
2 Commits
Author SHA1 Message Date
ddadminandClaude Opus 5 6910440400 feat(ods): типизированное событие, строгий приём и таблица ошибок
Зачем: цепочка Kafka → STG → ODS достраивается последним этажом. Сырьё уже
доезжает (#37), настоящие события в топике есть (#41), а типизированного слоя
не было — событие негде было прочитать колонками, а брак негде увидеть.

Что:
- sql/ddl/20-ods-tables.sql — ods.event_rep/_dist на ReplacingMergeTree с
  версией _load_ts, партиция по EventDate, ключ по разделу 1.3 спеки,
  шардирование cityHash64(ClientID); ods.event_errors_rep/_dist с классом
  брака, своими ключами и сроком жизни в месяц.
- sql/ddl/30-ods-views.sql — две матвью над stg.hits_raw_dist. Годность
  считает предикат из трёх частей, вторая матвью берёт его дословное
  отрицание, класс брака пишется первым совпавшим из трёх.
- Метку времени разбирает parseDateTimeBestEffortOrNull, а не JSONExtract:
  ISO-8601 с суффиксом Z JSONExtract не берёт вовсе. Спека генератора
  обещала обратное — обещание поправлено, форма на проводе не менялась.
- Сверка объявлений (contract-тест) снята из документов и из докстрингов
  schema.py: сверх строгого приёма она ловила только смену типа.
- Документация приведена в соответствие: ADR 0005, дока хранилища и обе
  спеки; группа «сказано по памяти» в доке хранилища опустела.

Проверка: make up && make check-clickhouse (8 проверок, 7,5 с); make lint,
make typecheck, make test (406), make docs без диффа. Разовые опыты при
исполнении — в теле PR.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-07 16:06:46 +03:00
ddadminandClaude Opus 5 daf13384a8 feat(stg): DDL-бутстрап, топик hits и приём сырья обеими нодами
Зачем: стенду нужен воспроизводимый холодный старт, при котором схема
хранилища и топик появляются сами, а сырьё из Kafka доезжает в STG обеими
нодами кластера — без ручных шагов между `make clean` и рабочим приёмом.

Что:
- `sql/ddl/` — три файла, применяются по порядку имён: базы `stg` и `ods`,
  Kafka-чтец `hits_raw_kafka` формата RawBLOB, реплицируемая `hits_raw_rep`
  с окном TTL в трое суток, распределённая `hits_raw_dist` и матвью
  `hits_raw_mv`, переносящая сырьё вместе с метаданными доставки.
- `compose.yaml` — службы `kafka-init` (топик `hits` на две партиции, с
  ремонтом уже созданного однопартиционного) и `clickhouse-init` (применяет
  `/ddl/*.sql`); `hostname:` у обеих нод, чтобы `hostName()` отдавал имя узла,
  а не идентификатор контейнера; `airflow-init` зависит от `clickhouse-init` —
  без зависимого успешный одноразовый сервис считается упавшим для `--wait`.
- Доки: конвенции и раздел «Что проверено» в справочнике хранилища, указатели
  и границы обещаний в ADR 0005, снятые пункты в разделе 11 спеки.

Проверка: `make lint`, `make typecheck`, `make config-test`, `make smoke`
(25 проверок), `make smoke-guards` — зелёные. Приёмочный прогон с чистого
тома подтвердил все пять критериев #37: холодный старт и идемпотентный
повтор, две партиции у `hits`, метаданные доставки у доехавшего сообщения,
обе партиции на обеих потребляющих нодах в одном прогоне, некорректный JSON
лежит сырым и приём не встаёт.

Известная граница: RawBLOB молча теряет запись с пустым значением и
запись-надгробие; принято как свойство, замер и довод — в справочнике
хранилища.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-06 08:04:25 +03:00