fix(generator): правки по двум линиям ревью — сторож состава и честные обещания

- Зачем:
  - линия постановки: тест инвариантов обещал ловить дрейф колонок, но
    переименование Referer или перенос колонки в другую группу проходили
    все проверки; линия стандартов: докстринг говорил о contract-тесте
    как о существующем и не нёс следа сверки API через Context7.
- Что:
  - тест состава по разделу 1.2 мастер-спеки: группа, имя и тип всех 47
    колонок записаны независимо от контракта, поэтому молчаливое
    переименование или перестановка краснеют — проверено правкой
    Referer → Referrer.
  - контракт: contract-тест переведён в будущее время со ссылкой на
    спеку; записана сверка записи типов ClickHouse (Context7 и запрос
    к узлу стенда 26.3.17.56 — параметры входят в имя типа целиком).
  - описание выгрузки самодостаточнее: расшифрованы коды
    DeviceCategory, домен LastTrafficSource честно назван неполным,
    «идентификатор» сведён к «id» ради одного слова на одну вещь.
  - schema_doc: убраны неиспользуемые параметры render и main,
    row → table_row; тест строки сверяет свойство, а не форму.
- Проверка:
  - make test (249 тестов), make lint;
  - make docs, затем git diff --exit-code docs/ — пусто.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-01 22:32:14 +03:00
co-authored by Claude Opus 5
parent 2890c7f9fb
commit 1f96245c41
5 changed files with 94 additions and 26 deletions
@@ -9,7 +9,6 @@
"""
import argparse
from collections.abc import Sequence
from itertools import groupby
from pathlib import Path
@@ -44,18 +43,18 @@ TABLE_HEADER = (
)
def render(columns: Sequence[Column] = COLUMNS) -> str:
def render() -> str:
"""Собирает документ целиком: преамбула и таблица колонок по группам."""
lines = PREAMBLE.format(count=len(columns)).splitlines()
numbers = iter(range(1, len(columns) + 1))
for group, columns_of_group in groupby(columns, key=lambda column: column.group):
lines = PREAMBLE.format(count=len(COLUMNS)).splitlines()
numbers = iter(range(1, len(COLUMNS) + 1))
for group, columns_of_group in groupby(COLUMNS, key=lambda column: column.group):
lines += ["", f"## {group.value}", "", *TABLE_HEADER]
lines += [row(next(numbers), column) for column in columns_of_group]
lines += [table_row(next(numbers), column) for column in columns_of_group]
return "\n".join(lines) + "\n"
def row(number: int, column: Column) -> str:
"""Строка таблицы; номер — место колонки в порядке выгрузки."""
def table_row(number: int, column: Column) -> str:
"""Строка таблицы колонок; номер — место колонки в порядке выгрузки."""
cells = (
str(number),
f"`{column.name}`",
@@ -67,12 +66,12 @@ def row(number: int, column: Column) -> str:
return "| " + " | ".join(cells) + " |"
def main(argv: Sequence[str] | None = None) -> None:
def main() -> None:
parser = argparse.ArgumentParser(
description="Собирает описание выгрузки из контракта схемы события."
)
parser.add_argument("output", type=Path, help="путь к файлу описания")
output = parser.parse_args(argv).output
output = parser.parse_args().output
output.write_text(render(), encoding="utf-8")
print(f"Описание выгрузки собрано: {output}")