Files
clickstream-ch-kafka-supers…/docs/course/LESSON_STANDARD.md
T
ddadmin 79f7103b28 docs(course): стандарт уроков фиксирует регистр, шапку и грабли
- Зачем:
  - наработанный по урокам 0–2 мягкий регистр жил только в памяти и хендоффах;
    стандарт его не требовал — следующий урок мог уехать обратно в сжатый стиль
    и повторить уже пройденные ошибки.
- Что:
  - добавлен §2 «Регистр и голос»: расшифровка терминов на первом употреблении,
    ###-подзаголовки, разбивка «стен», человеческий тон, house style, ai-text-lint;
  - в §1 описана шапка урока (Формат / «О чём урок простыми словами»), старые
    «Статус: черновик» и «Режим: руки» помечены как не возвращать;
  - добавлен §5 «Грабли»: проверять на стенде, сверять имена с DDL, один паттерн
    на урок, спорные API ClickHouse — через MCP Context7;
  - перенумерованы разделы (качество кода → §3, самопроверка → §4) и ссылки на них.
- Проверка:
  - прочитать LESSON_STANDARD.md сверху вниз: §1–§5 идут по порядку, ссылки
    «(раздел 4)» указывают на «Самопроверку».
2026-06-05 18:00:13 +03:00

137 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Стандарт уроков курса «Кликстрим на ClickHouse»
> Дата: 2026-06-01. Поправка: 2026-06-05 (по итогам уроков 0–2 — добавлены §2 «Регистр
> и голос», описание шапки урока и §5 «Грабли, на которые мы уже наступили»).
> Назначение: рабочий чеклист, по которому пишется **каждый** урок. Открывается при
> создании урока. Рамка курса (зачем/что/скоуп) — в `PRD.md`; карта уроков и
> маршрут — в `LEARNING_PLAN.md`.
---
## 1. Шаблон урока
Каждый урок строится по единому шаблону:
1. **Зачем и где в проде** — что за паттерн и где он встречается в обычной
кликстрим-аналитике (без привязки к конкретной компании).
2. **Руки** — что запустить и что понаблюдать (Kafka UI / ClickHouse / Grafana).
3. **Загляни внутрь** — чтение отполированного эталонного кода с пояснениями.
4. **Управляемая правка** — одно-два маленьких изменения с **видимым результатом**.
Например: добавить поле в Materialized View и увидеть его в `*_raw`; «сломать»
запись и увидеть `+1` в таблице ошибок `parse_errors`; сменить `kafka_group_name`
и увидеть, как топик читается заново. Менти меняет — видит эффект — объясняет.
**Верни как было** — каждая правка завершается явным шагом отката к чистому
состоянию (откатить изменение либо `make clean/up/ddl/data/transform`), чтобы
самостоятельный менти не застрял со сломанным стендом без ментора.
(Урок 0 — без этого шага, только наблюдение.)
5. **Проверь себя** — самопроверка (раздел 4).
6. **Что должно получиться****конкретный видимый результат**, который менти проверяет
сам: скрин эффекта правки (например, красный DAG или `+1` в таблице ошибок) плюс один
абзац «своими словами» про паттерн урока или запрос, который пришлось написать. Это и
есть самопроверка (раздел 4); те же вопросы «своими словами» менти разбирает с ментором
на еженедельном созвоне. (Урок 0 — без правки, поэтому результат здесь — что менти
увидел при наблюдении.)
### Шапка урока
Кроме шести секций, каждый урок открывается единым блоком-цитатой (`>`) сверху — он задаёт
рамку до того, как менти дойдёт до первой секции:
- **Формат:** одной фразой, что менти делает, — `**практика** — будешь сам запускать…`
или `**наблюдение** — ничего не запускаем и не меняем…`. Старые пометки «Статус: черновик»
и «Режим: руки» не возвращаем: менти читал их как «материал не готов» и «непонятно, как
понимать»;
- **Пререквизит:** какой урок пройден и что менти уже умеет;
- **Эталонный путь:** ссылка(и) на разбираемый файл;
- **Поток данных одной строкой:** та же стрелочная схема, что стоит в начале эталонного файла;
- **О чём урок простыми словами:** 1–2 фразы совсем простым языком, без терминов, — чтобы
менти с первой строки понял, о чём речь.
В конце урока — короткий **мост к следующему**: какой честный вопрос остаётся открытым и
как его закроет следующий урок.
## 2. Регистр и голос
Этот раздел — про то, *как* написан урок. Он появился по итогам уроков 0–2: мы начали со
сжатого регистра и переписывали — дешевле сразу писать мягко.
**Кто читатель.** Менти прошёл курсовую, уровень — «обзорно» (понять идею и потрогать, а не
стать экспертом). Поддержка — еженедельный созвон с ментором, а не «сессия»; на нём менти
разбирает вопросы «своими словами».
**Правила регистра:**
- **термин расшифровываем на первом употреблении** — коротко, своими словами (как `ODS`,
`DQ-split`, `Materialized View`, `*OrNull` в уроках 1–2). Не оставляем слово голым;
- **человеческий тон, без жаргона ради жаргона** — короткие предложения, прямое обращение
к менти («открой», «посмотри», «помнишь из урока 0»);
- **`###`-подзаголовки внутри длинных секций** — особенно в «Загляни внутрь»: каждый
смысловой кусок под своим заголовком, а не сплошной стеной;
- **плотные абзацы-«стены» бьём на пункты** с конкретикой;
- **разжёвывать, а не сжимать.** Урок может выйти заметно длиннее первого черновика — для
«обзорно» это норма, а не повод резать.
**House style (оставляем осознанно, `ai-text-lint` на это не правим):** тире «—», буква «ё»,
жирные зачины абзацев, двоеточие перед списком.
**Перед финалом** — прогнать текст урока через `/ai-text-lint` (контекст `article`) и убрать
настоящие AI-маркеры (например, слова вроде «ключевой», «является»), но house style выше
не снимать.
## 3. Стандарт качества эталонного кода
Эталонные пути полируем до **учебного качества**; остальной код стенда остаётся под
капотом — его не трогаем.
**Чеклист (минимум).** Файл доведён, если:
1. комментарии на русском объясняют **зачем**, а не пересказывают код;
2. шаги явные и названы своими именами, без неочевидных трюков;
3. в начале файла — поток данных одной строкой (как в STG:
`Kafka → kafka_*_raw → MV → *_raw`);
4. ошибки и проверки качества данных видны — понятно, куда смотреть;
5. нет мусора: мёртвого кода, закомментированных экспериментов, разнобоя в именах.
**Тест одного прохода (главный критерий и защита от громоздкости).**
> Менти читает файл один раз сверху вниз и может пересказать своими словами,
> *что* происходит и *зачем* — не прыгая по файлу, не гугля, не расшифровывая трюки.
Если тест не проходит — правим строго одним из трёх способов: (1) упростить код;
(2) добавить ровно одну строку «зачем» там, где код честно неочевиден; (3) убрать
лишнее под капот или в короткую пометку. **Добавить ещё комментариев — не способ.**
**Две защиты от раздувания:**
- комментируем только неочевидное «зачем» (очевидную строку комментировать нельзя —
лишний текст сам по себе мешает понимать);
- «близко к проду» ≠ «вся прод-сложность прямо в коде урока»: один прод-паттерн на
урок показываем чисто, остальные прод-заботы — короткой пометкой «в проде иначе: …».
Вердикты аудита по конкретным путям — в `LEARNING_PLAN.md`.
## 4. Самопроверка (по-простому)
Отдельный тест-фреймворк не строим. Опираемся на то, что в стенде уже есть:
- штатные быстрые проверки (smoke) из `docs/TEST_PLAN.md`;
- встроенные проверки в `etl_pipeline_dag.py` (DAG падает на пустой витрине или
нарушении целостности);
- `make clean/up/ddl/data/transform` для сброса и повтора.
В каждом уроке — маленькая табличка самопроверки в формате
**действие → где смотреть → что ожидать**, а для управляемой правки — какой
видимый результат должен появиться.
## 5. Грабли, на которые мы уже наступили
Короткий список ошибок из уроков 0–2 — чтобы следующий урок их не повторил.
- **Проверяй на стенде, а не «на глаз».** Любой категоричный claim про числа или целостность
подтверждай командой на стенде. Так нашёлся баг с `kafka_ts` в уроке 1 (значение типа
`DateTime64` молча резалось через `toInt64`, и время по всему стенду уехало в `1970`) и
подтвердилось, что «26 из 50» в уроке 2 — это схлопывание повторов по `click_id` (проверено
`uniqExact`), а не потеря данных.
- **Имена таблиц и колонок в тексте сверяй с реальным DDL.** То, что написано в уроке, должно
совпадать с `sql/ddl/...`, иначе менти запутается, когда выполнит запрос на стенде.
- **Один паттерн на урок; будущие темы только анонсируй.** Не раскрывай то, что относится к
следующим урокам (пример: жёсткий гейт на «сирот» — это урок 4, в уроке 3 мы их только
вводим как понятие).
- **Спорные API ClickHouse сверяй через MCP Context7** (зачем и в каком порядке — в
`AGENTS.md`), не полагайся на память: именно типы и поведение функций уже один раз подвели.